Skip to content
This repository was archived by the owner on Sep 9, 2022. It is now read-only.

Commit f959f19

Browse files
committed
Address performance issue reported with large number of open tabs: gorhill#266
(maintain reverse lookup map of tabs by tab ID rather than searching through all tabs to find by ID)
1 parent dc59aa0 commit f959f19

File tree

1 file changed

+50
-40
lines changed

1 file changed

+50
-40
lines changed

platform/firefox/vapi-background.js

Lines changed: 50 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ var tabWatcher = {
345345
var tabId = vAPI.tabs.getTabId(target);
346346
vAPI.tabs.onClosed(tabId);
347347
delete vAPI.toolbarButton.tabs[tabId];
348+
vAPI.tabs.tabLookup.delete(tabId);
348349
},
349350

350351
onTabSelect: function({target}) {
@@ -375,6 +376,20 @@ var getBrowserForTab = function(tab) {
375376
return vAPI.fennec && tab.browser || tab.linkedBrowser || null;
376377
};
377378

379+
/******************************************************************************/
380+
381+
var getTabForBrowser = function(browser) {
382+
if ( !browser ) {
383+
return null;
384+
}
385+
var win = browser.ownerGlobal;
386+
return vAPI.fennec && win.BrowserApp && win.BrowserApp.getTabForBrowser(browser) ||
387+
win.gBrowser && (win.gBrowser.getTabForBrowser && win.gBrowser.getTabForBrowser(browser) ||
388+
win.gBrowser._getTabForBrowser && win.gBrowser._getTabForBrowser(browser));
389+
};
390+
391+
392+
378393
/******************************************************************************/
379394

380395
var getOwnerWindow = function(target) {
@@ -452,6 +467,7 @@ vAPI.tabs.registerListeners = function() {
452467
/******************************************************************************/
453468

454469
vAPI.tabs.stack = new WeakMap();
470+
vAPI.tabs.tabLookup = new Map();
455471
vAPI.tabs.stackId = 1;
456472

457473
/******************************************************************************/
@@ -460,50 +476,50 @@ vAPI.tabs.getTabId = function(target) {
460476
if ( !target ) {
461477
return vAPI.noTabId;
462478
}
479+
480+
var tab;
481+
var browser;
482+
463483
if ( vAPI.fennec ) {
464-
if ( target.browser ) {
484+
if (target.browser) {
465485
// target is a tab
466-
target = target.browser;
486+
tab = target;
487+
browser = target.browser;
488+
} else {
489+
browser = target;
467490
}
468491
} else if ( target.linkedPanel ) {
469492
// target is a tab
470-
target = target.linkedBrowser;
493+
tab = target;
494+
browser = target.linkedBrowser;
495+
} else {
496+
browser = target;
471497
}
472-
if ( target.localName !== 'browser' ) {
498+
499+
if ( browser.localName !== 'browser' ) {
473500
return vAPI.noTabId;
474501
}
475-
var tabId = this.stack.get(target);
502+
503+
var tabId = this.stack.get(browser);
476504
if ( !tabId ) {
477505
tabId = '' + this.stackId++;
478-
this.stack.set(target, tabId);
506+
this.stack.set(browser, tabId);
507+
508+
if (!tab) {
509+
tab = getTabForBrowser(browser);
510+
}
511+
512+
if (tab) {
513+
this.tabLookup.set(tabId, tab);
514+
}
479515
}
480516
return tabId;
481517
};
482518

483519
/******************************************************************************/
484520

485-
// If tabIds is an array, then an array of tabs will be returned,
486-
// otherwise a single tab
487-
488-
vAPI.tabs.getTabsForIds = function(tabIds) {
489-
var tabs = [];
490-
var singleTab = !Array.isArray(tabIds);
491-
if ( singleTab ) {
492-
tabIds = [tabIds];
493-
}
494-
for ( var tab of this.getAll() ) {
495-
var tabId = this.stack.get(getBrowserForTab(tab));
496-
if ( !tabId ) {
497-
continue;
498-
}
499-
if ( tabIds.indexOf(tabId) !== -1 ) {
500-
tabs.push(tab);
501-
}
502-
if ( tabs.length >= tabIds.length ) {
503-
break;
504-
}
505-
}
506-
return singleTab ? tabs[0] || null : tabs;
521+
vAPI.tabs.tabFromTabId = function(tabId) {
522+
return this.tabLookup.get(tabId);
507523
};
508524

509525
/******************************************************************************/
@@ -519,7 +535,7 @@ vAPI.tabs.get = function(tabId, callback) {
519535
tabId = this.getTabId(tab);
520536
}
521537
} else {
522-
tab = this.getTabsForIds(tabId);
538+
tab = this.tabFromTabId(tabId);
523539
if ( tab ) {
524540
win = getOwnerWindow(tab);
525541
}
@@ -639,7 +655,7 @@ vAPI.tabs.open = function(details) {
639655
}
640656

641657
if ( details.tabId ) {
642-
tab = this.getTabsForIds(details.tabId);
658+
tab = this.tabFromTabId(details.tabId);
643659
if ( tab ) {
644660
getBrowserForTab(tab).loadURI(details.url);
645661
return;
@@ -678,7 +694,7 @@ vAPI.tabs.replace = function(tabId, url) {
678694
targetURL = vAPI.getURL(targetURL);
679695
}
680696

681-
var tab = this.getTabsForIds(tabId);
697+
var tab = this.tabFromTabId(tabId);
682698
if ( tab ) {
683699
getBrowserForTab(tab).loadURI(targetURL);
684700
}
@@ -696,15 +712,9 @@ vAPI.tabs._remove = function(tab, tabBrowser) {
696712

697713
/******************************************************************************/
698714

699-
vAPI.tabs.remove = function(tabIds) {
700-
if ( !Array.isArray(tabIds) ) {
701-
tabIds = [tabIds];
702-
}
703-
var tabs = this.getTabsForIds(tabIds);
704-
if ( tabs.length === 0 ) {
705-
return;
706-
}
707-
for ( var tab of tabs ) {
715+
vAPI.tabs.remove = function(tabId) {
716+
var tab = this.tabFromTabId(tabId);
717+
if ( tab ) {
708718
this._remove(tab, getTabBrowser(getOwnerWindow(tab)));
709719
}
710720
};

0 commit comments

Comments
 (0)