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.
This commit is contained in:
Cadence Ember 2021-08-26 23:47:53 +12:00
parent 0aa0505009
commit 55065e2a9e
No known key found for this signature in database
GPG Key ID: BC1C2C61CF521B17
4 changed files with 15 additions and 9 deletions

View File

@ -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)

View File

@ -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

View File

@ -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
}

View File

@ -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()
}
]