ssb: Faster loads around the profile page. An experiment with caching SQL queries, and make one query just plain faster.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 8m53s

This commit is contained in:
2025-11-16 14:20:26 -05:00
parent aea4a14a62
commit 35f374047a
3 changed files with 44 additions and 11 deletions

View File

@@ -1,5 +1,5 @@
{ {
"type": "tildefriends-app", "type": "tildefriends-app",
"emoji": "🦀", "emoji": "🦀",
"previous": "&k075s5Ij+NjRS52GJ6AD8Pl2ZGNseuj63AKBeV4LMQg=.sha256" "previous": "&Tozi8g5lPpLW7znc+jm7xDZxoTq1G3DJAh2YhG+FRAQ=.sha256"
} }

View File

@@ -2,6 +2,7 @@ import * as tfrpc from '/tfrpc.js';
let g_database; let g_database;
let g_hash; let g_hash;
let g_sql_cache = {};
tfrpc.register(async function localStorageGet(key) { tfrpc.register(async function localStorageGet(key) {
return app.localStorageGet(key); return app.localStorageGet(key);
@@ -51,14 +52,38 @@ tfrpc.register(async function connect(token) {
tfrpc.register(async function closeConnection(id) { tfrpc.register(async function closeConnection(id) {
await ssb.closeConnection(id); await ssb.closeConnection(id);
}); });
tfrpc.register(async function query(sql, args) { tfrpc.register(async function query(sql, args, options) {
let start = new Date(); let start = new Date();
let result = []; let result = [];
await ssb.sqlAsync(sql, args, function callback(row) { let key = options?.cacheable ? JSON.stringify([sql, args]) : undefined;
result.push(row); let entry = key ? g_sql_cache[key] : undefined;
}); const k_ideal_count = 64;
if (entry) {
result = entry.result;
} else {
await ssb.sqlAsync(sql, args, function callback(row) {
result.push(row);
});
if (key) {
g_sql_cache[key] = {
result: result,
time: new Date().valueOf(),
};
if (Object.keys(g_sql_cache).length > k_ideal_count * 2) {
let aged = Object.entries(g_sql_cache).map(([k, v]) => [v.time, k]);
aged.sort();
for (let i = 0; i < aged.length / 2; i++) {
delete g_sql_cache[aged[i][1]];
}
}
}
}
let end = new Date(); let end = new Date();
print((end - start) / 1000, sql.replaceAll(/\s+/g, ' ').trim()); print(
(end - start) / 1000,
entry ? 'from cache' : 'from db',
sql.replaceAll(/\s+/g, ' ').trim()
);
return result; return result;
}); });
tfrpc.register(async function appendMessage(id, message) { tfrpc.register(async function appendMessage(id, message) {

View File

@@ -37,16 +37,22 @@ class TfProfileElement extends LitElement {
this.following = undefined; this.following = undefined;
this.blocking = undefined; this.blocking = undefined;
let latest = (
await tfrpc.rpc.query('SELECT MAX(rowid) AS latest FROM messages')
)[0].latest;
let result = await tfrpc.rpc.query( let result = await tfrpc.rpc.query(
` `
SELECT json_extract(content, '$.following') AS following SELECT json_extract(content, '$.following') AS following
FROM messages WHERE author = ? AND FROM messages WHERE author = ? AND
json_extract(content, '$.type') = 'contact' AND json_extract(content, '$.type') = 'contact' AND
json_extract(content, '$.contact') = ? AND json_extract(content, '$.contact') = ? AND
following IS NOT NULL following IS NOT NULL AND
messages.rowid <= ?
ORDER BY sequence DESC LIMIT 1 ORDER BY sequence DESC LIMIT 1
`, `,
[this.whoami, this.id] [this.whoami, this.id, latest],
{cacheable: true}
); );
this.following = result?.[0]?.following ?? false; this.following = result?.[0]?.following ?? false;
result = await tfrpc.rpc.query( result = await tfrpc.rpc.query(
@@ -55,10 +61,12 @@ class TfProfileElement extends LitElement {
FROM messages WHERE author = ? AND FROM messages WHERE author = ? AND
json_extract(content, '$.type') = 'contact' AND json_extract(content, '$.type') = 'contact' AND
json_extract(content, '$.contact') = ? AND json_extract(content, '$.contact') = ? AND
blocking IS NOT NULL blocking IS NOT NULL AND
messages.rowid <= ?
ORDER BY sequence DESC LIMIT 1 ORDER BY sequence DESC LIMIT 1
`, `,
[this.whoami, this.id] [this.whoami, this.id, latest],
{cacheable: true}
); );
this.blocking = result?.[0]?.blocking ?? false; this.blocking = result?.[0]?.blocking ?? false;
} }
@@ -238,7 +246,7 @@ class TfProfileElement extends LitElement {
let profile = this.users[this.id] || {}; let profile = this.users[this.id] || {};
tfrpc.rpc tfrpc.rpc
.query( .query(
`SELECT SUM(LENGTH(content)) AS size, MAX(sequence) AS sequence FROM messages WHERE author = ?`, `SELECT size AS size, max_sequence AS sequence FROM messages_stats WHERE author = ?`,
[this.id] [this.id]
) )
.then(function (result) { .then(function (result) {