~cadence/cloudtube

55065e2a9e0ce1ed75202bab2dd9ae3f350866e5 — Cadence Ember 28 days 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()
	}
]