fix #2011: improve heuristic on when to give up on DOM surveying

This commit is contained in:
gorhill 2016-10-06 10:49:46 -04:00
parent 751e34f3ce
commit b20b43e351
2 changed files with 28 additions and 50 deletions

View File

@ -78,8 +78,6 @@ if ( typeof vAPI !== 'object' ) {
} }
vAPI.lock(); vAPI.lock();
vAPI.executionCost.start();
vAPI.matchesProp = (function() { vAPI.matchesProp = (function() {
var docElem = document.documentElement; var docElem = document.documentElement;
if ( typeof docElem.matches !== 'function' ) { if ( typeof docElem.matches !== 'function' ) {
@ -416,8 +414,6 @@ var domFilterer = {
}, },
commit_: function() { commit_: function() {
vAPI.executionCost.start();
commitTimer = null; commitTimer = null;
var beforeHiddenNodeCount = this.hiddenNodeCount, var beforeHiddenNodeCount = this.hiddenNodeCount,
@ -503,8 +499,6 @@ var domFilterer = {
503 503
); );
} }
vAPI.executionCost.stop('domFilterer.commit_');
}, },
commit: function(nodes, commitNow) { commit: function(nodes, commitNow) {
@ -700,8 +694,6 @@ return domFilterer;
return; return;
} }
vAPI.executionCost.start();
if ( response.noCosmeticFiltering ) { if ( response.noCosmeticFiltering ) {
vAPI.domFilterer = null; vAPI.domFilterer = null;
vAPI.domSurveyor = null; vAPI.domSurveyor = null;
@ -761,8 +753,6 @@ return domFilterer;
} else { } else {
document.addEventListener('DOMContentLoaded', vAPI.domIsLoaded); document.addEventListener('DOMContentLoaded', vAPI.domIsLoaded);
} }
vAPI.executionCost.stop('domIsLoading/responseHandler');
}; };
var url = window.location.href; var url = window.location.href;
@ -793,8 +783,6 @@ vAPI.domWatcher = (function() {
listeners = []; listeners = [];
var safeObserverHandler = function() { var safeObserverHandler = function() {
vAPI.executionCost.start();
safeObserverHandlerTimer = null; safeObserverHandlerTimer = null;
var i = addedNodeLists.length, var i = addedNodeLists.length,
nodeList, iNode, node; nodeList, iNode, node;
@ -821,15 +809,11 @@ vAPI.domWatcher = (function() {
addedNodes.length = 0; addedNodes.length = 0;
removedNodes = false; removedNodes = false;
} }
vAPI.executionCost.stop('domWatcher/safeObserverHandler');
}; };
// https://github.com/chrisaljoudi/uBlock/issues/205 // https://github.com/chrisaljoudi/uBlock/issues/205
// Do not handle added node directly from within mutation observer. // Do not handle added node directly from within mutation observer.
var observerHandler = function(mutations) { var observerHandler = function(mutations) {
vAPI.executionCost.start();
var nodeList, mutation, var nodeList, mutation,
i = mutations.length; i = mutations.length;
while ( i-- ) { while ( i-- ) {
@ -845,8 +829,6 @@ vAPI.domWatcher = (function() {
if ( (addedNodeLists.length !== 0 || removedNodes) && safeObserverHandlerTimer === null ) { if ( (addedNodeLists.length !== 0 || removedNodes) && safeObserverHandlerTimer === null ) {
safeObserverHandlerTimer = window.requestAnimationFrame(safeObserverHandler); safeObserverHandlerTimer = window.requestAnimationFrame(safeObserverHandler);
} }
vAPI.executionCost.stop('domWatcher/observerHandler');
}; };
var addListener = function(listener) { var addListener = function(listener) {
@ -935,7 +917,6 @@ vAPI.domCollapser = (function() {
if ( requests === null || Array.isArray(requests) === false ) { if ( requests === null || Array.isArray(requests) === false ) {
return; return;
} }
vAPI.executionCost.start();
var selectors = [], var selectors = [],
netSelectorCacheCountMax = response.netSelectorCacheCountMax, netSelectorCacheCountMax = response.netSelectorCacheCountMax,
aa = [ null ], aa = [ null ],
@ -986,11 +967,9 @@ vAPI.domCollapser = (function() {
} }
); );
} }
vAPI.executionCost.stop('domCollapser/onProcessed');
}; };
var send = function() { var send = function() {
vAPI.executionCost.start();
timer = null; timer = null;
// https://github.com/gorhill/uBlock/issues/1927 // https://github.com/gorhill/uBlock/issues/1927
// Normalize hostname to avoid trailing dot of FQHN. // Normalize hostname to avoid trailing dot of FQHN.
@ -1011,7 +990,6 @@ vAPI.domCollapser = (function() {
}, onProcessed }, onProcessed
); );
roundtripRequests = []; roundtripRequests = [];
vAPI.executionCost.stop('domCollapser/send');
}; };
var process = function(delay) { var process = function(delay) {
@ -1134,10 +1112,8 @@ vAPI.domCollapser = (function() {
}; };
var onResourceFailed = function(ev) { var onResourceFailed = function(ev) {
vAPI.executionCost.start();
vAPI.domCollapser.add(ev.target); vAPI.domCollapser.add(ev.target);
vAPI.domCollapser.process(); vAPI.domCollapser.process();
vAPI.executionCost.stop('domCollapser/onResourceFailed');
}; };
var domChangedHandler = function(nodes) { var domChangedHandler = function(nodes) {
@ -1212,13 +1188,12 @@ vAPI.domSurveyor = (function() {
cosmeticSurveyingMissCount = 0, cosmeticSurveyingMissCount = 0,
highGenerics = null, highGenerics = null,
lowGenericSelectors = [], lowGenericSelectors = [],
queriedSelectors = Object.create(null); queriedSelectors = Object.create(null),
surveyCost = 0;
// Handle main process' response. // Handle main process' response.
var surveyPhase3 = function(response) { var surveyPhase3 = function(response) {
vAPI.executionCost.start();
var result = response && response.result, var result = response && response.result,
firstSurvey = highGenerics === null; firstSurvey = highGenerics === null;
@ -1232,6 +1207,7 @@ vAPI.domSurveyor = (function() {
} }
if ( highGenerics ) { if ( highGenerics ) {
var t0 = window.performance.now();
if ( highGenerics.hideLowCount ) { if ( highGenerics.hideLowCount ) {
processHighLowGenerics(highGenerics.hideLow); processHighLowGenerics(highGenerics.hideLow);
} }
@ -1241,6 +1217,7 @@ vAPI.domSurveyor = (function() {
if ( highGenerics.hideHighSimpleCount || highGenerics.hideHighComplexCount ) { if ( highGenerics.hideHighSimpleCount || highGenerics.hideHighComplexCount ) {
processHighHighGenerics(); processHighHighGenerics();
} }
surveyCost += window.performance.now() - t0;
} }
// Need to do this before committing DOM filterer, as needed info // Need to do this before committing DOM filterer, as needed info
@ -1252,7 +1229,9 @@ vAPI.domSurveyor = (function() {
what: 'cosmeticFiltersInjected', what: 'cosmeticFiltersInjected',
type: 'cosmetic', type: 'cosmetic',
hostname: window.location.hostname, hostname: window.location.hostname,
selectors: domFilterer.job0._0 selectors: domFilterer.job0._0,
first: firstSurvey,
cost: surveyCost
} }
); );
} }
@ -1266,8 +1245,6 @@ vAPI.domSurveyor = (function() {
domFilterer.commit(surveyPhase3Nodes); domFilterer.commit(surveyPhase3Nodes);
surveyPhase3Nodes = []; surveyPhase3Nodes = [];
vAPI.executionCost.stop('domSurveyor/surveyPhase3');
}; };
// Query main process. // Query main process.
@ -1460,11 +1437,12 @@ vAPI.domSurveyor = (function() {
// http://jsperf.com/enumerate-classes/6 // http://jsperf.com/enumerate-classes/6
var surveyPhase1 = function(addedNodes) { var surveyPhase1 = function(addedNodes) {
var nodes = selectNodes('[class],[id]', addedNodes); var t0 = window.performance.now(),
var qq = queriedSelectors; nodes = selectNodes('[class],[id]', addedNodes),
var ll = lowGenericSelectors; qq = queriedSelectors,
var node, v, vv, j; ll = lowGenericSelectors,
var i = nodes.length; node, v, vv, j,
i = nodes.length;
while ( i-- ) { while ( i-- ) {
node = nodes[i]; node = nodes[i];
if ( node.nodeType !== 1 ) { continue; } if ( node.nodeType !== 1 ) { continue; }
@ -1496,6 +1474,7 @@ vAPI.domSurveyor = (function() {
} }
} }
} }
surveyCost += window.performance.now() - t0;
surveyPhase2(addedNodes); surveyPhase2(addedNodes);
}; };
@ -1545,8 +1524,6 @@ vAPI.domIsLoaded = function(ev) {
} }
vAPI.domIsLoaded = null; vAPI.domIsLoaded = null;
vAPI.executionCost.start();
vAPI.domWatcher.start(); vAPI.domWatcher.start();
vAPI.domCollapser.start(); vAPI.domCollapser.start();
@ -1604,12 +1581,8 @@ vAPI.domIsLoaded = function(ev) {
document.removeEventListener('mousedown', onMouseClick, true); document.removeEventListener('mousedown', onMouseClick, true);
}); });
})(); })();
vAPI.executionCost.stop('domIsLoaded');
}; };
/******************************************************************************/ /******************************************************************************/
/******************************************************************************/ /******************************************************************************/
/******************************************************************************/ /******************************************************************************/
vAPI.executionCost.stop('contentscript.js');

View File

@ -410,10 +410,15 @@ SelectorCacheEntry.prototype.dispose = function() {
/******************************************************************************/ /******************************************************************************/
SelectorCacheEntry.prototype.addCosmetic = function(selectors) { SelectorCacheEntry.prototype.addCosmetic = function(details) {
var i = selectors.length || 0; var selectors = details.selectors,
if ( i === 0 ) { i = selectors.length || 0;
this.cosmeticSurveyingMissCount += 1; // https://github.com/gorhill/uBlock/issues/2011
// Avoiding seemingly pointless surveys only if they appear costly.
if ( details.first && i === 0 ) {
if ( (details.cost || 0) >= 80 ) {
this.cosmeticSurveyingMissCount += 1;
}
return; return;
} }
this.cosmeticSurveyingMissCount = 0; this.cosmeticSurveyingMissCount = 0;
@ -474,12 +479,12 @@ SelectorCacheEntry.prototype.addNetMany = function(selectors, now) {
/******************************************************************************/ /******************************************************************************/
SelectorCacheEntry.prototype.add = function(selectors, type) { SelectorCacheEntry.prototype.add = function(details) {
this.lastAccessTime = Date.now(); this.lastAccessTime = Date.now();
if ( type === 'cosmetic' ) { if ( details.type === 'cosmetic' ) {
this.addCosmetic(selectors); this.addCosmetic(details);
} else { } else {
this.addNet(selectors); this.addNet(details.selectors);
} }
}; };
@ -1526,7 +1531,7 @@ FilterContainer.prototype.addToSelectorCache = function(details) {
this.selectorCacheCount += 1; this.selectorCacheCount += 1;
this.triggerSelectorCachePruner(); this.triggerSelectorCachePruner();
} }
entry.add(selectors, details.type); entry.add(details);
}; };
/******************************************************************************/ /******************************************************************************/