Skip to content

Commit 0aa0d81

Browse files
committed
[mv3] Re-work specific cosmetic filtering-related content scripts
To minimize delay to First Contentful Paint. The idea is to avoid complex data structures such as Map in order to speed up first content script execution. Use stringified arrays where practical and instanciate those arrays from their stringified representation only when there are actual cosmetic filters to apply. Related commit: 6039ef2b6d
1 parent 6039ef2 commit 0aa0d81

File tree

9 files changed

+168
-311
lines changed

9 files changed

+168
-311
lines changed

platform/mv3/extension/js/scripting/css-procedural.js

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -30,42 +30,47 @@ self.proceduralImports = undefined;
3030

3131
/******************************************************************************/
3232

33-
const selectors = [];
34-
const exceptions = [];
35-
36-
const lookupHostname = (hostname, details, out) => {
37-
let seqi = details.hostnamesMap.get(hostname);
38-
if ( seqi === undefined ) { return; }
39-
const { argsList, argsSeqs } = details;
40-
for (;;) {
41-
const argi = argsSeqs[seqi++];
42-
const done = argi > 0;
43-
out.push(...JSON.parse(argsList[done ? argi : -argi]));
44-
if ( done ) { break; }
33+
const isolatedAPI = self.isolatedAPI;
34+
const selectors = new Set();
35+
const exceptions = new Set();
36+
37+
const lookupHostname = (hostname, details) => {
38+
const listref = isolatedAPI.binarySearch(details.hostnames, hostname);
39+
if ( listref === -1 ) { return; }
40+
if ( Array.isArray(details.selectorLists) === false ) {
41+
details.selectorLists = details.selectorLists.split(';');
42+
details.selectorListRefs = JSON.parse(`[${details.selectorListRefs}]`);
43+
}
44+
const ilist = details.selectorListRefs[listref];
45+
const list = JSON.parse(`[${details.selectorLists[ilist]}]`);
46+
for ( const iselector of list ) {
47+
if ( iselector >= 0 ) {
48+
selectors.add(details.selectors[iselector]);
49+
} else {
50+
exceptions.add(details.selectors[~iselector]);
51+
}
4552
}
4653
};
4754

4855
const lookupAll = hostname => {
4956
for ( const details of proceduralImports ) {
50-
lookupHostname(hostname, details, selectors);
51-
const matches = [];
52-
lookupHostname(`~${hostname}`, details, matches);
53-
if ( matches.length === 0 ) { continue; }
54-
exceptions.push(...matches.map(a => JSON.stringify(a)));
57+
lookupHostname(hostname, details);
5558
}
5659
};
5760

58-
self.isolatedAPI.forEachHostname(lookupAll, {
61+
isolatedAPI.forEachHostname(lookupAll, {
5962
hasEntities: proceduralImports.some(a => a.hasEntities)
6063
});
64+
6165
proceduralImports.length = 0;
6266

63-
if ( selectors.length === 0 ) { return; }
67+
for ( const selector of exceptions ) {
68+
selectors.delete(selector);
69+
}
70+
71+
if ( selectors.size === 0 ) { return; }
6472

65-
const exceptedSelectors = exceptions.length !== 0
66-
? selectors.filter(a => exceptions.includes(JSON.stringify(a)) === false)
67-
: selectors;
68-
if ( exceptedSelectors.length === 0 ) { return; }
73+
const exceptedSelectors = Array.from(selectors).map(a => JSON.parse(a));
6974

7075
const declaratives = exceptedSelectors.filter(a => a.cssable);
7176
if ( declaratives.length !== 0 ) {

platform/mv3/extension/js/scripting/css-specific.js

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,42 +30,48 @@ self.specificImports = undefined;
3030

3131
/******************************************************************************/
3232

33-
const selectors = [];
34-
const exceptions = [];
35-
36-
const lookupHostname = (hostname, details, out) => {
37-
let seqi = details.hostnamesMap.get(hostname);
38-
if ( seqi === undefined ) { return; }
39-
const { argsList, argsSeqs } = details;
40-
for (;;) {
41-
const argi = argsSeqs[seqi++];
42-
const done = argi > 0;
43-
out.push(...argsList[done ? argi : -argi].split('\n'));
44-
if ( done ) { break; }
33+
const isolatedAPI = self.isolatedAPI;
34+
const selectors = new Set();
35+
const exceptions = new Set();
36+
37+
const lookupHostname = (hostname, details) => {
38+
const listref = isolatedAPI.binarySearch(details.hostnames, hostname);
39+
if ( listref === -1 ) { return; }
40+
if ( Array.isArray(details.selectorLists) === false ) {
41+
details.selectorLists = details.selectorLists.split(';');
42+
details.selectorListRefs = JSON.parse(`[${details.selectorListRefs}]`);
43+
}
44+
const ilist = details.selectorListRefs[listref];
45+
const list = JSON.parse(`[${details.selectorLists[ilist]}]`);
46+
for ( const iselector of list ) {
47+
if ( iselector >= 0 ) {
48+
selectors.add(details.selectors[iselector]);
49+
} else {
50+
exceptions.add(details.selectors[~iselector]);
51+
}
4552
}
4653
};
4754

4855
const lookupAll = hostname => {
4956
for ( const details of specificImports ) {
50-
lookupHostname(hostname, details, selectors);
51-
lookupHostname(`~${hostname}`, details, exceptions);
57+
lookupHostname(hostname, details);
5258
}
5359
};
5460

55-
self.isolatedAPI.forEachHostname(lookupAll, {
61+
isolatedAPI.forEachHostname(lookupAll, {
5662
hasEntities: specificImports.some(a => a.hasEntities)
5763
});
5864

5965
specificImports.length = 0;
6066

61-
if ( selectors.length === 0 ) { return; }
67+
for ( const selector of exceptions ) {
68+
selectors.delete(selector);
69+
}
6270

63-
const exceptedSelectors = exceptions.length !== 0
64-
? selectors.filter(a => exceptions.includes(a) === false)
65-
: selectors;
66-
if ( exceptedSelectors.length === 0 ) { return; }
71+
if ( selectors.size === 0 ) { return; }
6772

68-
self.cssAPI.insert(`${exceptedSelectors.join(',')}{display:none!important;}`);
73+
const css = `${Array.from(selectors).join(',\n')}{display:none!important;}`;
74+
self.cssAPI.insert(css);
6975

7076
/******************************************************************************/
7177

platform/mv3/extension/js/scripting/isolated-api.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,28 @@
7373
if ( r !== undefined ) { return r; }
7474
}
7575
};
76+
77+
isolatedAPI.binarySearch = (sorted, target) => {
78+
let l = 0, i = 0, d = 0;
79+
let r = sorted.length;
80+
let candidate;
81+
while ( l < r ) {
82+
i = l + r >>> 1;
83+
candidate = sorted[i];
84+
d = target.length - candidate.length;
85+
if ( d === 0 ) {
86+
if ( target === candidate ) { return i; }
87+
d = target < candidate ? -1 : 1;
88+
}
89+
if ( d < 0 ) {
90+
r = i;
91+
} else {
92+
l = i + 1;
93+
}
94+
}
95+
return -1;
96+
};
97+
7698
})(self.isolatedAPI);
7799

78100
/******************************************************************************/

0 commit comments

Comments
 (0)