~cadence/cloudtube

55065e2a9e0ce1ed75202bab2dd9ae3f350866e5 — Cadence Ember a month ago 0aa0505
11x speed up of subscription page generation

My 30 subscriptions now take 25 ms to generate, instead of around 280.

Around 120 ms were saved by creating a database index.
Around 120 ms were saved by pre-compiling the pug template for video
description timestamps.
The other changes in this commit produced slight improvements.
4 files changed, 15 insertions(+), 9 deletions(-)

M api/subscriptions.js
M utils/converters.js
M utils/getuser.js
M utils/upgradedb.js
M api/subscriptions.js => api/subscriptions.js +4 -7
@@ 16,18 16,15 @@ module.exports = [
				// trigger a background refresh, needed if they came back from being inactive
				refresher.skipWaiting()
				// get channels
				const subscriptions = user.getSubscriptions()
				const template = Array(subscriptions.length).fill("?").join(", ")
				channels = db.prepare(`SELECT * FROM Channels WHERE ucid IN (${template}) ORDER BY name`).all(subscriptions)
				channels = db.prepare(`SELECT Channels.* FROM Channels INNER JOIN Subscriptions ON Channels.ucid = Subscriptions.ucid WHERE token = ? ORDER BY name`).all(user.token)
				// get refreshed status
				refreshed = db.prepare(`SELECT min(refreshed) as min, max(refreshed) as max, count(refreshed) as count FROM Channels WHERE ucid IN (${template})`).get(subscriptions)
				refreshed = db.prepare(`SELECT min(refreshed) as min, max(refreshed) as max, count(refreshed) as count FROM Channels INNER JOIN Subscriptions ON Channels.ucid = Subscriptions.ucid WHERE token = ?`).get(user.token)
				// get watched videos
				const watchedVideos = user.getWatchedVideos()
				// get videos
				if (subscriptions.length) {
				if (channels.length) {
					hasSubscriptions = true
					const template = Array(subscriptions.length).fill("?").join(", ")
					videos = db.prepare(`SELECT * FROM Videos WHERE authorId IN (${template}) ORDER BY published DESC LIMIT 60`).all(subscriptions)
					videos = db.prepare(`SELECT Videos.* FROM Videos INNER JOIN Subscriptions ON Videos.authorID = Subscriptions.ucid WHERE token = ? ORDER BY published DESC LIMIT 60`).all(user.token)
						.map(video => {
							video.publishedText = timeToPastText(video.published * 1000)
							video.watched = watchedVideos.includes(video.videoId)

M utils/converters.js => utils/converters.js +2 -1
@@ 58,6 58,7 @@ function normaliseVideoInfo(video) {
	}
}

const timeDisplayCompiled = pug.compile(`a(href=url data-clickable-timestamp=timeSeconds)= timeDisplay`)
function rewriteVideoDescription(descriptionHtml, id) {
	// replace timestamps to clickable links and rewrite youtube links to stay on the instance instead of pointing to YouTube
	// test cases


@@ 93,7 94,7 @@ function rewriteVideoDescription(descriptionHtml, id) {
		params.set("t", timeURL)
		const url = "/watch?" + params

		return pug.render(`a(href=url data-clickable-timestamp=timeSeconds)= timeDisplay`, {url, timeURL, timeDisplay, timeSeconds})
		return timeDisplayCompiled({url, timeURL, timeDisplay, timeSeconds})
	})

	return descriptionHtml

M utils/getuser.js => utils/getuser.js +4 -1
@@ 14,7 14,10 @@ function getToken(req, responseHeaders) {
			return null
		}
	}
	db.prepare("REPLACE INTO SeenTokens (token, seen) VALUES (?, ?)").run([token, Date.now()])
	db.prepare(
		"INSERT INTO SeenTokens (token, seen) VALUES (?, ?)"
			+ " ON CONFLICT (token) DO UPDATE SET seen = excluded.seen"
	).run([token, Date.now()])
	return token
}


M utils/upgradedb.js => utils/upgradedb.js +5 -0
@@ 58,6 58,11 @@ const deltas = [
	function() {
		db.prepare("ALTER TABLE Subscriptions ADD COLUMN channel_missing INTEGER DEFAULT 0")
			.run()
	},
	// 9: add index Videos (authorID)
	function() {
		db.prepare("CREATE INDEX Videos_authorID ON Videos (authorID)")
			.run()
	}
]