From 30c70a6ecd53c64993b346506bd08f9cd2a6f93b Mon Sep 17 00:00:00 2001 From: Abe Jellinek Date: Mon, 21 Aug 2023 12:20:57 -0400 Subject: [PATCH] Defer removing tab content Improves EPUB close performance. By wrapping with requestIdleCallback(), we ensure: 1. remove() won't be called right away, so the DOM elements being removed won't be visible and won't trigger a relayout. 2. remove() won't be called while there are pending UI events, so it shouldn't cause the UI to hang/lag/stutter. Combined, these two improvements make the UI hang when closing a large EPUB mostly imperceptible on my machine. Addresses #3321; doesn't completely fix it because there's likely more to be done on the reader side to optimize the DOM. --- chrome/content/zotero/tabs.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/chrome/content/zotero/tabs.js b/chrome/content/zotero/tabs.js index 72ba46c5fb..990ea4094e 100644 --- a/chrome/content/zotero/tabs.js +++ b/chrome/content/zotero/tabs.js @@ -269,7 +269,7 @@ var Zotero_Tabs = new function () { var closedIDs = []; var tmpTabs = this._tabs.slice(); for (var id of ids) { - var { tab, tabIndex } = this._getTab(id); + let { tab, tabIndex } = this._getTab(id); if (!tab) { continue; } @@ -281,14 +281,20 @@ var Zotero_Tabs = new function () { } tabIndex = this._tabs.findIndex(x => x.id === id); this._tabs.splice(tabIndex, 1); - document.getElementById(tab.id).remove(); - // For unknown reason fx102, unlike 60, sometimes doesn't automatically update selected index - this.deck.selectedIndex = Array.from(this.deck.children).findIndex(x => x.id == this._selectedID); if (tab.onClose) { tab.onClose(); } historyEntry.push({ index: tmpTabs.indexOf(tab), data: tab.data }); closedIDs.push(id); + + requestIdleCallback(() => { + document.getElementById(tab.id).remove(); + // For unknown reason fx102, unlike 60, sometimes doesn't automatically update selected index + let selectedIndex = Array.from(this.deck.children).findIndex(x => x.id == this._selectedID); + if (this.deck.selectedIndex !== selectedIndex) { + this.deck.selectedIndex = selectedIndex; + } + }); } this._history.push(historyEntry); Zotero.Notifier.trigger('close', 'tab', [closedIDs], true);