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
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 8m53s
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"type": "tildefriends-app",
|
"type": "tildefriends-app",
|
||||||
"emoji": "🦀",
|
"emoji": "🦀",
|
||||||
"previous": "&k075s5Ij+NjRS52GJ6AD8Pl2ZGNseuj63AKBeV4LMQg=.sha256"
|
"previous": "&Tozi8g5lPpLW7znc+jm7xDZxoTq1G3DJAh2YhG+FRAQ=.sha256"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user