From 798f8dab9d41053697768fa8b2d338c09e5fd5b6 Mon Sep 17 00:00:00 2001 From: Raymond Hill Date: Fri, 1 Jun 2018 07:54:31 -0400 Subject: [PATCH] reduce baseline memory at selfie-load time --- src/js/background.js | 4 +-- src/js/redirect-engine.js | 9 +++--- src/js/static-net-filtering.js | 53 ++++++++++++++-------------------- src/js/storage.js | 48 ++++++++++++++++-------------- src/js/utils.js | 12 -------- 5 files changed, 53 insertions(+), 73 deletions(-) diff --git a/src/js/background.js b/src/js/background.js index ed5ecda72..8739edd20 100644 --- a/src/js/background.js +++ b/src/js/background.js @@ -137,8 +137,8 @@ var µBlock = (function() { // jshint ignore:line // Read-only systemSettings: { - compiledMagic: 2, // Increase when compiled format changes - selfieMagic: 2 // Increase when selfie format changes + compiledMagic: 3, // Increase when compiled format changes + selfieMagic: 3 // Increase when selfie format changes }, restoreBackupSettings: { diff --git a/src/js/redirect-engine.js b/src/js/redirect-engine.js index 37a66a241..cc9e475c8 100644 --- a/src/js/redirect-engine.js +++ b/src/js/redirect-engine.js @@ -408,12 +408,11 @@ RedirectEngine.prototype.toSelfie = function() { } rules.push(rule); } - var µb = µBlock; return { rules: rules, - ruleTypes: µb.arrayFrom(this.ruleTypes), - ruleSources: µb.arrayFrom(this.ruleSources), - ruleDestinations: µb.arrayFrom(this.ruleDestinations) + ruleTypes: Array.from(this.ruleTypes), + ruleSources: Array.from(this.ruleSources), + ruleDestinations: Array.from(this.ruleDestinations) }; }; @@ -508,7 +507,7 @@ RedirectEngine.prototype.selfieFromResources = function() { vAPI.cacheStorage.set({ resourcesSelfie: { version: resourcesSelfieVersion, - resources: µBlock.arrayFrom(this.resources) + resources: Array.from(this.resources) } }); }; diff --git a/src/js/static-net-filtering.js b/src/js/static-net-filtering.js index 46d37db33..33e39bb17 100644 --- a/src/js/static-net-filtering.js +++ b/src/js/static-net-filtering.js @@ -1139,7 +1139,7 @@ FilterHostnameDict.prototype.logData = function() { }; FilterHostnameDict.prototype.compile = function() { - return [ this.fid, µb.arrayFrom(this.dict) ]; + return [ this.fid, Array.from(this.dict) ]; }; FilterHostnameDict.load = function(args) { @@ -2014,8 +2014,8 @@ FilterContainer.prototype.freeze = function() { this.fdataLast = null; this.filterLast = null; this.frozen = true; - //console.log(JSON.stringify(µb.arrayFrom(filterClassHistogram))); - //this.tokenHistogram = new Map(µb.arrayFrom(this.tokenHistogram).sort(function(a, b) { + //console.log(JSON.stringify(Array.from(filterClassHistogram))); + //this.tokenHistogram = new Map(Array.from(this.tokenHistogram).sort(function(a, b) { // return a[0].localeCompare(b[0]) || (b[1] - a[1]); //})); }; @@ -2023,27 +2023,27 @@ FilterContainer.prototype.freeze = function() { /******************************************************************************/ FilterContainer.prototype.toSelfie = function() { - var categoriesToSelfie = function(categoryMap) { - var categoryEntries = []; - for ( var categoryEntry of categoryMap ) { - var tokenEntries = []; - for ( var tokenEntry of categoryEntry[1] ) { + let categoriesToSelfie = function(categoryMap) { + let selfie = []; + for ( let categoryEntry of categoryMap ) { + let tokenEntries = []; + for ( let tokenEntry of categoryEntry[1] ) { tokenEntries.push([ tokenEntry[0], tokenEntry[1].compile() ]); } - categoryEntries.push([ categoryEntry[0], tokenEntries ]); + selfie.push([ categoryEntry[0], tokenEntries ]); } - return JSON.stringify(categoryEntries); + return selfie; }; - var dataFiltersToSelfie = function(dataFilters) { - var selfie = []; - for ( var entry of dataFilters.values() ) { + let dataFiltersToSelfie = function(dataFilters) { + let selfie = []; + for ( let entry of dataFilters.values() ) { do { selfie.push(entry.compile()); entry = entry.next; } while ( entry !== undefined ); } - return JSON.stringify(selfie); + return selfie; }; return { @@ -2069,28 +2069,17 @@ FilterContainer.prototype.fromSelfie = function(selfie) { this.blockFilterCount = selfie.blockFilterCount; this.discardedCount = selfie.discardedCount; - var entries; - - var categoryMap = new Map(); - entries = JSON.parse(selfie.categories); - for ( var i = 0, ni = entries.length; i < ni; i++ ) { - var categoryEntry = entries[i], - tokenMap = new Map(); - var tokenEntries = categoryEntry[1]; - for ( var j = 0, nj = tokenEntries.length; j < nj; j++ ) { - var tokenEntry = tokenEntries[j]; + for ( let categoryEntry of selfie.categories ) { + let tokenMap = new Map(); + for ( let tokenEntry of categoryEntry[1] ) { tokenMap.set(tokenEntry[0], filterFromCompiledData(tokenEntry[1])); } - categoryMap.set(categoryEntry[0], tokenMap); + this.categories.set(categoryEntry[0], tokenMap); } - this.categories = categoryMap; - entries = JSON.parse(selfie.dataFilters); - var entry, bucket; - i = entries.length; - while ( i-- ) { - entry = FilterDataHolderEntry.load(entries[i]); - bucket = this.dataFilters.get(entry.tokenHash); + for ( let dataEntry of selfie.dataFilters ) { + let entry = FilterDataHolderEntry.load(dataEntry); + let bucket = this.dataFilters.get(entry.tokenHash); if ( bucket !== undefined ) { entry.next = bucket; } diff --git a/src/js/storage.js b/src/js/storage.js index f05a99052..7a48ae3b2 100644 --- a/src/js/storage.js +++ b/src/js/storage.js @@ -278,7 +278,7 @@ this.removeFilterList(oldKeys[i]); } } - newKeys = this.arrayFrom(newSet); + newKeys = Array.from(newSet); var bin = { selectedFilterLists: newKeys }; @@ -358,10 +358,10 @@ } selectedListKeySet.add(assetKey); } - externalLists = this.arrayFrom(importedSet).sort().join('\n'); + externalLists = Array.from(importedSet).sort().join('\n'); } - var result = this.arrayFrom(selectedListKeySet); + var result = Array.from(selectedListKeySet); if ( externalLists !== this.userSettings.externalLists ) { this.userSettings.externalLists = externalLists; vAPI.storage.set({ externalLists: externalLists }); @@ -387,7 +387,7 @@ } out.add(location); } - return this.arrayFrom(out); + return Array.from(out); }; /******************************************************************************/ @@ -1018,23 +1018,27 @@ // some set time. µBlock.selfieManager = (function() { - var timer = null; + let µb = µBlock; + let timer = null; - var create = function() { + // As of 2018-05-31: + // JSON.stringify-ing ourselves results in a better baseline + // memory usage at selfie-load time. For some reasons. + + let create = function() { timer = null; - var selfie = { - magic: this.systemSettings.selfieMagic, - availableFilterLists: this.availableFilterLists, - staticNetFilteringEngine: this.staticNetFilteringEngine.toSelfie(), - redirectEngine: this.redirectEngine.toSelfie(), - staticExtFilteringEngine: this.staticExtFilteringEngine.toSelfie() + let selfie = { + magic: µb.systemSettings.selfieMagic, + availableFilterLists: JSON.stringify(µb.availableFilterLists), + staticNetFilteringEngine: JSON.stringify(µb.staticNetFilteringEngine.toSelfie()), + redirectEngine: JSON.stringify(µb.redirectEngine.toSelfie()), + staticExtFilteringEngine: JSON.stringify(µb.staticExtFilteringEngine.toSelfie()) }; vAPI.cacheStorage.set({ selfie: selfie }); - }.bind(µBlock); + }; - var load = function(callback) { + let load = function(callback) { vAPI.cacheStorage.get('selfie', function(bin) { - var µb = µBlock; if ( bin instanceof Object === false || bin.selfie instanceof Object === false || @@ -1043,22 +1047,22 @@ ) { return callback(false); } - µb.availableFilterLists = bin.selfie.availableFilterLists; - µb.staticNetFilteringEngine.fromSelfie(bin.selfie.staticNetFilteringEngine); - µb.redirectEngine.fromSelfie(bin.selfie.redirectEngine); - µb.staticExtFilteringEngine.fromSelfie(bin.selfie.staticExtFilteringEngine); + µb.availableFilterLists = JSON.parse(bin.selfie.availableFilterLists); + µb.staticNetFilteringEngine.fromSelfie(JSON.parse(bin.selfie.staticNetFilteringEngine)); + µb.redirectEngine.fromSelfie(JSON.parse(bin.selfie.redirectEngine)); + µb.staticExtFilteringEngine.fromSelfie(JSON.parse(bin.selfie.staticExtFilteringEngine)); callback(true); }); }; - var destroy = function() { + let destroy = function() { if ( timer !== null ) { clearTimeout(timer); timer = null; } vAPI.cacheStorage.remove('selfie'); - timer = vAPI.setTimeout(create, this.selfieAfter); - }.bind(µBlock); + timer = vAPI.setTimeout(create, µb.selfieAfter); + }; return { load: load, diff --git a/src/js/utils.js b/src/js/utils.js index 918a49b1b..ba70b292b 100644 --- a/src/js/utils.js +++ b/src/js/utils.js @@ -357,18 +357,6 @@ /******************************************************************************/ -µBlock.arrayFrom = typeof Array.from === 'function' - ? Array.from - : function(iterable) { - var out = [], i = 0; - for ( var value of iterable ) { - out[i++] = value; - } - return out; - }; - -/******************************************************************************/ - µBlock.openNewTab = function(details) { if ( details.url.startsWith('logger-ui.html') ) { if ( details.shiftKey ) {