From 44ddcdd852dbb4527b7f1804f2af9ea1bff86fc8 Mon Sep 17 00:00:00 2001 From: zadam Date: Mon, 3 Feb 2020 21:16:33 +0100 Subject: [PATCH] various widget optimizations for faster note switching --- libraries/springy.js | 2 +- .../javascripts/services/app_context.js | 16 ----- src/public/javascripts/services/bundle.js | 15 +---- src/public/javascripts/services/server.js | 6 ++ .../javascripts/services/tab_context.js | 3 - src/public/javascripts/widgets/attributes.js | 58 +++++++++-------- src/public/javascripts/widgets/link_map.js | 12 ++++ src/public/javascripts/widgets/note_paths.js | 62 ++++++++++--------- .../javascripts/widgets/note_revisions.js | 12 ++++ src/public/javascripts/widgets/note_type.js | 3 +- .../javascripts/widgets/similar_notes.js | 14 +++++ src/public/stylesheets/style.css | 2 +- src/services/note_cache.js | 2 +- 13 files changed, 111 insertions(+), 96 deletions(-) diff --git a/libraries/springy.js b/libraries/springy.js index 7767b2eb4..f9bc03ffb 100644 --- a/libraries/springy.js +++ b/libraries/springy.js @@ -486,7 +486,7 @@ window.Springy = function() { t._started = false; onRenderStop(); } else { - requestIdleCallback(step, { timeout: 10 }); + requestIdleCallback(step, { timeout: 30 }); } } diff --git a/src/public/javascripts/services/app_context.js b/src/public/javascripts/services/app_context.js index ebec1a93d..04ba44556 100644 --- a/src/public/javascripts/services/app_context.js +++ b/src/public/javascripts/services/app_context.js @@ -433,22 +433,6 @@ class AppContext { this.openTabsChangedListener(); } - // FIXME non existent event - noteChangesSavedListener() { - const activeTabContext = this.getActiveTabContext(); - - if (!activeTabContext || !activeTabContext.note) { - return; - } - - if (activeTabContext.note.isProtected && protectedSessionHolder.isProtectedSessionAvailable()) { - protectedSessionHolder.touchProtectedSession(); - } - - // run async - bundleService.executeRelationBundles(activeTabContext.note, 'runOnNoteChange', activeTabContext); - } - activateNextTabListener() { const tabIdsInOrder = this.tabRow.getTabIdsInOrder(); const oldIdx = tabIdsInOrder.findIndex(tid => tid === this.activeTabId); diff --git a/src/public/javascripts/services/bundle.js b/src/public/javascripts/services/bundle.js index 95d973085..d85638b5e 100644 --- a/src/public/javascripts/services/bundle.js +++ b/src/public/javascripts/services/bundle.js @@ -29,21 +29,8 @@ async function executeStartupBundles() { } } -async function executeRelationBundles(note, relationName, tabContext) { - note.bundleCache = note.bundleCache || {}; - - if (!note.bundleCache[relationName]) { - note.bundleCache[relationName] = await server.get("script/relation/" + note.noteId + "/" + relationName); - } - - for (const bundle of note.bundleCache[relationName]) { - await executeBundle(bundle, note, tabContext); - } -} - export default { executeBundle, getAndExecuteBundle, - executeStartupBundles, - executeRelationBundles + executeStartupBundles } \ No newline at end of file diff --git a/src/public/javascripts/services/server.js b/src/public/javascripts/services/server.js index 8181ffc88..54e5fb04e 100644 --- a/src/public/javascripts/services/server.js +++ b/src/public/javascripts/services/server.js @@ -50,6 +50,8 @@ let maxKnownSyncId = 0; async function call(method, url, data, headers = {}) { let resp; + const start = Date.now(); + if (utils.isElectron()) { const ipc = require('electron').ipcRenderer; const requestId = i++; @@ -74,6 +76,10 @@ async function call(method, url, data, headers = {}) { resp = await ajax(url, method, data, headers); } + const end = Date.now(); + + console.log(`${method} ${url} took ${end-start}ms`); + const maxSyncIdStr = resp.headers['trilium-max-sync-id']; if (maxSyncIdStr && maxSyncIdStr.trim()) { diff --git a/src/public/javascripts/services/tab_context.js b/src/public/javascripts/services/tab_context.js index dbce42527..d8b11d92f 100644 --- a/src/public/javascripts/services/tab_context.js +++ b/src/public/javascripts/services/tab_context.js @@ -66,9 +66,6 @@ class TabContext extends Component { } }, 5000); - // should be done somewhere else ... - bundleService.executeRelationBundles(this.note, 'runOnNoteView', this); - if (this.note.isProtected && protectedSessionHolder.isProtectedSessionAvailable()) { // FIXME: there are probably more places where this should be done protectedSessionHolder.touchProtectedSession(); diff --git a/src/public/javascripts/widgets/attributes.js b/src/public/javascripts/widgets/attributes.js index 8cacb6a12..f8fbbd574 100644 --- a/src/public/javascripts/widgets/attributes.js +++ b/src/public/javascripts/widgets/attributes.js @@ -24,46 +24,44 @@ export default class AttributesWidget extends CollapsibleWidget { } async refreshWithNote(note) { - const attributes = await note.getAttributes(); const ownedAttributes = note.getOwnedAttributes(); - - if (attributes.length === 0) { - this.$body.text("No attributes yet..."); - return; - } - const $attributesContainer = $("
"); await this.renderAttributes(ownedAttributes, $attributesContainer); - const inheritedAttributes = attributes.filter(attr => attr.noteId !== this.tabContext.note.noteId); + const $inheritedAttrs = $("").append($("").text("Inherited: ")); + const $showInheritedAttributes = $("") + .attr("href", "javascript:") + .text("+show inherited") + .on('click', async () => { + const attributes = await note.getAttributes(); + const inheritedAttributes = attributes.filter(attr => attr.noteId !== this.tabContext.note.noteId); - if (inheritedAttributes.length > 0) { - const $inheritedAttrs = $("").append($("").text("Inherited: ")); - const $showInheritedAttributes = $("") - .attr("href", "javascript:") - .text("+show inherited") - .on('click', () => { - $showInheritedAttributes.hide(); - $inheritedAttrs.show(); - }); + if (inheritedAttributes.length === 0) { + $inheritedAttrs.text("No inherited attributes yet..."); + } + else { + await this.renderAttributes(inheritedAttributes, $inheritedAttrs); + } - const $hideInheritedAttributes = $("") - .attr("href", "javascript:") - .text("-hide inherited") - .on('click', () => { - $showInheritedAttributes.show(); - $inheritedAttrs.hide(); - }); + $inheritedAttrs.show(); + $showInheritedAttributes.hide(); + $hideInheritedAttributes.show(); + }); - $attributesContainer.append($showInheritedAttributes); - $attributesContainer.append($inheritedAttrs); + const $hideInheritedAttributes = $("") + .attr("href", "javascript:") + .text("-hide inherited") + .on('click', () => { + $showInheritedAttributes.show(); + $hideInheritedAttributes.hide(); + $inheritedAttrs.empty().hide(); + }); - await this.renderAttributes(inheritedAttributes, $inheritedAttrs); + $attributesContainer.append($showInheritedAttributes, $inheritedAttrs, $hideInheritedAttributes); - $inheritedAttrs.append($hideInheritedAttributes); - $inheritedAttrs.hide(); - } + $inheritedAttrs.hide(); + $hideInheritedAttributes.hide(); this.$body.empty().append($attributesContainer); } diff --git a/src/public/javascripts/widgets/link_map.js b/src/public/javascripts/widgets/link_map.js index 0aa9c13ec..744e4ef60 100644 --- a/src/public/javascripts/widgets/link_map.js +++ b/src/public/javascripts/widgets/link_map.js @@ -28,6 +28,18 @@ export default class LinkMapWidget extends CollapsibleWidget { return [$showFullButton]; } + noteSwitched() { + const noteId = this.noteId; + + // avoid executing this expensive operation multiple times when just going through notes (with keyboard especially) + // until the users settles on a note + setTimeout(() => { + if (this.noteId === noteId) { + this.refresh(); + } + }, 1000); + } + async refreshWithNote(note) { this.$body.css('opacity', 0); this.$body.html(TPL); diff --git a/src/public/javascripts/widgets/note_paths.js b/src/public/javascripts/widgets/note_paths.js index 5351a8771..1e89929d5 100644 --- a/src/public/javascripts/widgets/note_paths.js +++ b/src/public/javascripts/widgets/note_paths.js @@ -26,47 +26,48 @@ export default class NotePathsWidget extends TabAwareWidget { this.$notePathList = this.$widget.find(".note-path-list"); this.$notePathCount = this.$widget.find(".note-path-count"); + this.$widget.on('show.bs.dropdown', () => this.renderDropdown()); + return this.$widget; } async refreshWithNote(note, notePath) { - if (note.noteId === 'root') { - // root doesn't have any parent, but it's still technically 1 path + const pathCount = note.noteId === 'root' + ? 1 // root doesn't have any parent, but it's still technically 1 path + : note.getBranchIds().length; - this.$notePathCount.html("1 path"); + this.$notePathCount.html(pathCount + " path" + (pathCount > 1 ? "s" : "")); + } - this.$notePathList.empty(); + async renderDropdown() { + this.$notePathList.empty(); + if (this.noteId === 'root') { await this.addPath('root', true); + return; } - else { - const parents = await note.getParentNotes(); - this.$notePathCount.html(parents.length + " path" + (parents.length > 1 ? "s" : "")); - this.$notePathList.empty(); + const pathSegments = this.notePath.split("/"); + const activeNoteParentNoteId = pathSegments[pathSegments.length - 2]; // we know this is not root so there must be a parent - const pathSegments = notePath.split("/"); - const activeNoteParentNoteId = pathSegments[pathSegments.length - 2]; // we know this is not root so there must be a parent + for (const parentNote of await this.note.getParentNotes()) { + const parentNotePath = await treeService.getSomeNotePath(parentNote); + // this is to avoid having root notes leading '/' + const notePath = parentNotePath ? (parentNotePath + '/' + this.noteId) : this.noteId; + const isCurrent = activeNoteParentNoteId === parentNote.noteId; - for (const parentNote of parents) { - const parentNotePath = await treeService.getSomeNotePath(parentNote); - // this is to avoid having root notes leading '/' - const notePath = parentNotePath ? (parentNotePath + '/' + note.noteId) : note.noteId; - const isCurrent = activeNoteParentNoteId === parentNote.noteId; - - await this.addPath(notePath, isCurrent); - } - - const cloneLink = $("
") - .addClass("dropdown-item") - .append( - $('