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.
This commit is contained in:
Abe Jellinek 2023-08-21 12:20:57 -04:00
parent 38d0750dd3
commit 30c70a6ecd

View file

@ -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);