1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-11-06 09:19:22 +02:00

Desktop: Optimised sidebar rendering speed

This commit is contained in:
Laurent Cozic
2020-09-24 14:30:20 +01:00
parent 6ca640d2ed
commit 947d81d96d
9 changed files with 178 additions and 36 deletions

View File

@@ -9,6 +9,8 @@ class Database {
this.logger_ = new Logger();
this.logExcludedQueryTypes_ = [];
this.batchTransactionMutex_ = new Mutex();
this.profilingEnabled_ = false;
this.queryId_ = 1;
}
setLogExcludedQueryTypes(v) {
@@ -71,10 +73,30 @@ class Database {
let waitTime = 50;
let totalWaitTime = 0;
const callStartTime = Date.now();
let profilingTimeoutId = null;
while (true) {
try {
this.logQuery(sql, params);
const queryId = this.queryId_++;
if (this.profilingEnabled_) {
console.info(`SQL START ${queryId}`, sql, params);
profilingTimeoutId = setInterval(() => {
console.warn(`SQL ${queryId} has been running for ${Date.now() - callStartTime}: ${sql}`);
}, 3000);
}
const result = await this.driver()[callName](sql, params);
if (this.profilingEnabled_) {
clearInterval(profilingTimeoutId);
profilingTimeoutId = null;
const elapsed = Date.now() - callStartTime;
if (elapsed > 10) console.info(`SQL END ${queryId}`, elapsed, sql, params);
}
return result; // No exception was thrown
} catch (error) {
if (error && (error.code == 'SQLITE_IOERR' || error.code == 'SQLITE_BUSY')) {
@@ -89,6 +111,8 @@ class Database {
} else {
throw this.sqliteErrorToJsError(error, sql, params);
}
} finally {
if (profilingTimeoutId) clearInterval(profilingTimeoutId);
}
}
}

View File

@@ -0,0 +1,13 @@
import useEffectDebugger from './useEffectDebugger';
export default function usePropsDebugger(effectHook:any, props:any) {
const dependencies:any[] = [];
const dependencyNames:string[] = [];
for (const k in props) {
dependencies.push(props[k]);
dependencyNames.push(k);
}
useEffectDebugger(effectHook, dependencies, dependencyNames);
}

View File

@@ -156,6 +156,8 @@ class BaseItem extends BaseModel {
}
static async loadItemsByIds(ids) {
if (!ids.length) return [];
const classes = this.syncItemClassNames();
let output = [];
for (let i = 0; i < classes.length; i++) {

View File

@@ -109,6 +109,7 @@ class Tag extends BaseItem {
static async tagsByNoteId(noteId) {
const tagIds = await NoteTag.tagIdsByNoteId(noteId);
if (!tagIds.length) return [];
return this.modelSelectAll(`SELECT * FROM tags WHERE id IN ("${tagIds.join('","')}")`);
}

View File

@@ -0,0 +1,56 @@
const Folder = require('lib/models/Folder');
const Note = require('lib/models/Note');
function randomIndex(array:any[]):number {
return Math.round(Math.random() * (array.length - 1));
}
export default async function populateDatabase(db:any) {
await db.clearForTesting();
const folderCount = 2000;
const noteCount = 20000;
const createdFolderIds:string[] = [];
const createdNoteIds:string[] = [];
for (let i = 0; i < folderCount; i++) {
const folder:any = {
title: `folder${i}`,
};
const isRoot = Math.random() <= 0.1 || i === 0;
if (!isRoot) {
const parentIndex = randomIndex(createdFolderIds);
folder.parent_id = createdFolderIds[parentIndex];
}
const savedFolder = await Folder.save(folder);
createdFolderIds.push(savedFolder.id);
console.info(`Folders: ${i} / ${folderCount}`);
}
let noteBatch = [];
for (let i = 0; i < noteCount; i++) {
const note:any = { title: `note${i}`, body: `This is note num. ${i}` };
const parentIndex = randomIndex(createdFolderIds);
note.parent_id = createdFolderIds[parentIndex];
noteBatch.push(Note.save(note, { dispatchUpdateAction: false }).then((savedNote:any) => {
createdNoteIds.push(savedNote.id);
console.info(`Notes: ${i} / ${noteCount}`);
}));
if (noteBatch.length > 1000) {
await Promise.all(noteBatch);
noteBatch = [];
}
}
if (noteBatch.length) {
await Promise.all(noteBatch);
noteBatch = [];
}
}