1
0
mirror of https://github.com/gorhill/uBlock.git synced 2024-07-05 11:37:01 +02:00

]firefox] Improve load time & behavior from suspended state

Related issue:
https://github.com/uBlockOrigin/uBlock-issues/issues/2969

Changes:

Use browser.alarms to trigger selfie creation. Presence of a selfie
improve markedly time to readiness when uBO is unsuspended.

Mirror content of storage.local to (in-memory) storage.session for
faster load to readiness when uBO is ususpended.
This commit is contained in:
Raymond Hill 2023-12-04 15:15:08 -05:00
parent a969a672e0
commit eb66820728
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
4 changed files with 126 additions and 12 deletions

View File

@ -87,26 +87,111 @@ vAPI.app = {
},
};
/******************************************************************************/
/******************************************************************************/
/*******************************************************************************
*
* https://developer.mozilla.org/docs/Mozilla/Add-ons/WebExtensions/API/storage/session
*
* Session (in-memory) storage is promise-based in all browsers, no need for
* a webext polyfill. However, not all browsers supports it in MV2.
*
* */
vAPI.sessionStorage = (( ) => {
if ( browser.storage.session instanceof Object === false ) {
return {
get() {
return Promise.resolve({});
},
set() {
return Promise.resolve();
},
remove() {
return Promise.resolve();
},
clear() {
return Promise.resolve();
},
implemented: false,
};
}
return {
get(...args) {
return browser.storage.session.get(...args).catch(reason => {
console.log(reason);
return {};
});
},
set(...args) {
return browser.storage.session.set(...args).catch(reason => {
console.log(reason);
});
},
remove(...args) {
return browser.storage.session.remove(...args).catch(reason => {
console.log(reason);
});
},
clear(...args) {
return browser.storage.session.clear(...args).catch(reason => {
console.log(reason);
});
},
implemented: true,
};
})();
/*******************************************************************************
*
* Data written to and read from storage.local will be mirrored to in-memory
* storage.session.
*
* Data read from storage.local will be first fetched from storage.session,
* then if not available, read from storage.local.
*
* */
vAPI.storage = {
get(...args) {
return webext.storage.local.get(...args).catch(reason => {
console.log(reason);
get(key, ...args) {
if ( vAPI.sessionStorage.implemented !== true ) {
return webext.storage.local.get(key, ...args).catch(reason => {
console.log(reason);
});
}
return vAPI.sessionStorage.get(key, ...args).then(bin => {
const size = Object.keys(bin).length;
if ( size === 1 && typeof key === 'string' && bin[key] === null ) {
return {};
}
if ( size !== 0 ) { return bin; }
return webext.storage.local.get(key, ...args).then(bin => {
if ( bin instanceof Object === false ) { return bin; }
// Mirror empty result as null value in order to prevent
// from falling back to storage.local when there is no need.
const tomirror = Object.assign({}, bin);
if ( typeof key === 'string' && Object.keys(bin).length === 0 ) {
Object.assign(tomirror, { [key]: null });
}
vAPI.sessionStorage.set(tomirror);
return bin;
}).catch(reason => {
console.log(reason);
});
});
},
set(...args) {
vAPI.sessionStorage.set(...args);
return webext.storage.local.set(...args).catch(reason => {
console.log(reason);
});
},
remove(...args) {
vAPI.sessionStorage.remove(...args);
return webext.storage.local.remove(...args).catch(reason => {
console.log(reason);
});
},
clear(...args) {
vAPI.sessionStorage.clear(...args);
return webext.storage.local.clear(...args).catch(reason => {
console.log(reason);
});
@ -1422,14 +1507,14 @@ vAPI.adminStorage = (( ) => {
store = await webext.storage.managed.get();
} catch(ex) {
}
webext.storage.local.set({ cachedManagedStorage: store || {} });
vAPI.storage.set({ cachedManagedStorage: store || {} });
};
return {
get: async function(key) {
let bin;
try {
bin = await webext.storage.local.get('cachedManagedStorage') || {};
bin = await vAPI.storage.get('cachedManagedStorage') || {};
if ( Object.keys(bin).length === 0 ) {
bin = await webext.storage.managed.get() || {};
} else {
@ -1477,7 +1562,7 @@ vAPI.localStorage = {
start: async function() {
if ( this.cache instanceof Promise ) { return this.cache; }
if ( this.cache instanceof Object ) { return this.cache; }
this.cache = webext.storage.local.get('localStorage').then(bin => {
this.cache = vAPI.storage.get('localStorage').then(bin => {
this.cache = bin instanceof Object &&
bin.localStorage instanceof Object
? bin.localStorage
@ -1487,7 +1572,7 @@ vAPI.localStorage = {
},
clear: function() {
this.cache = {};
return webext.storage.local.set({ localStorage: this.cache });
return vAPI.storage.set({ localStorage: this.cache });
},
getItem: function(key) {
if ( this.cache instanceof Object === false ) {
@ -1509,7 +1594,7 @@ vAPI.localStorage = {
await this.start();
if ( value === this.cache[key] ) { return; }
this.cache[key] = value;
return webext.storage.local.set({ localStorage: this.cache });
return vAPI.storage.set({ localStorage: this.cache });
},
cache: undefined,
};
@ -1740,3 +1825,17 @@ vAPI.cloud = (( ) => {
})();
/******************************************************************************/
/******************************************************************************/
vAPI.alarms = browser.alarms || {
create() {
},
clear() {
},
onAlarm: {
addListener() {
}
}
};
/******************************************************************************/

View File

@ -106,6 +106,7 @@
"open_in_tab": true
},
"permissions": [
"alarms",
"dns",
"menus",
"privacy",

View File

@ -144,6 +144,8 @@ if ( vAPI.webextFlavor.soup.has('firefox') ) {
}
const µBlock = { // jshint ignore:line
wakeupReason: '',
userSettingsDefault,
userSettings: Object.assign({}, userSettingsDefault),

View File

@ -19,8 +19,6 @@
Home: https://github.com/gorhill/uBlock
*/
/* globals WebAssembly */
'use strict';
/******************************************************************************/
@ -1243,6 +1241,8 @@ onBroadcast(msg => {
// memory usage at selfie-load time. For some reasons.
const create = async function() {
vAPI.alarms.clear('createSelfie');
createTimer.off();
if ( µb.inMemoryFilters.length !== 0 ) { return; }
if ( Object.keys(µb.availableFilterLists).length === 0 ) { return; }
await Promise.all([
@ -1316,11 +1316,23 @@ onBroadcast(msg => {
io.remove(/^selfie\//);
µb.selfieIsInvalid = true;
}
if ( µb.wakeupReason === 'createSelfie' ) {
µb.wakeupReason = '';
return createTimer.offon({ sec: 27 });
}
vAPI.alarms.create('createSelfie', {
delayInMinutes: µb.hiddenSettings.selfieAfter
});
createTimer.offon({ min: µb.hiddenSettings.selfieAfter });
};
const createTimer = vAPI.defer.create(create);
vAPI.alarms.onAlarm.addListener(alarm => {
if ( alarm.name !== 'createSelfie') { return; }
µb.wakeupReason = 'createSelfie';
});
µb.selfieManager = { load, destroy };
}