own page load microopt: reduce blocking on i18n
* localStorage cache is faster than chrome.i18n.get * TreeWalker is faster than tHTML for removing extraneous whitespace * simple for() is faster than for-of with [...iterable]
This commit is contained in:
parent
4eae87e606
commit
b3b1d4a628
|
@ -37,6 +37,18 @@ function webNavigationListener(method, data) {
|
|||
});
|
||||
}
|
||||
|
||||
// reset i18n cache on language change
|
||||
|
||||
setTimeout(() => {
|
||||
const {browserUIlanguage} = tryJSONparse(localStorage.L10N) || {};
|
||||
const UIlang = chrome.i18n.getUILanguage();
|
||||
if (browserUIlanguage != UIlang) {
|
||||
localStorage.L10N = JSON.stringify({
|
||||
browserUIlanguage: UIlang,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// messaging
|
||||
|
||||
chrome.runtime.onMessage.addListener(onRuntimeMessage);
|
||||
|
|
|
@ -5,10 +5,14 @@ tDocLoader();
|
|||
|
||||
|
||||
function t(key, params) {
|
||||
const s = chrome.i18n.getMessage(key, params);
|
||||
const cache = !params && t.cache[key];
|
||||
const s = cache || chrome.i18n.getMessage(key, params);
|
||||
if (s == '') {
|
||||
throw `Missing string "${key}"`;
|
||||
}
|
||||
if (!params && !cache) {
|
||||
t.cache[key] = s;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -35,24 +39,38 @@ function tHTML(html) {
|
|||
|
||||
|
||||
function tNodeList(nodes) {
|
||||
for (const node of [...nodes]) {
|
||||
const PREFIX = 'i18n-';
|
||||
for (let n = nodes.length; --n >= 0;) {
|
||||
const node = nodes[n];
|
||||
// skip non-ELEMENT_NODE
|
||||
if (node.nodeType != 1) {
|
||||
continue;
|
||||
}
|
||||
if (node.localName == 'template') {
|
||||
const elements = node.content.querySelectorAll('*');
|
||||
tNodeList(elements);
|
||||
template[node.dataset.id] = elements[0];
|
||||
// compress inter-tag whitespace to reduce number of DOM nodes by 25%
|
||||
template[node.dataset.id] = tHTML(node.innerHTML);
|
||||
const walker = document.createTreeWalker(elements[0], NodeFilter.SHOW_TEXT);
|
||||
const toRemove = [];
|
||||
while (walker.nextNode()) {
|
||||
const textNode = walker.currentNode;
|
||||
if (!textNode.nodeValue.trim()) {
|
||||
toRemove.push(textNode);
|
||||
}
|
||||
}
|
||||
toRemove.forEach(el => el.remove());
|
||||
continue;
|
||||
}
|
||||
for (const attr of [...node.attributes]) {
|
||||
let name = attr.nodeName;
|
||||
if (name.indexOf('i18n-') != 0) {
|
||||
for (let a = node.attributes.length; --a >= 0;) {
|
||||
const attr = node.attributes[a];
|
||||
const name = attr.nodeName;
|
||||
if (!name.startsWith(PREFIX)) {
|
||||
continue;
|
||||
}
|
||||
name = name.substr(5); // 'i18n-'.length
|
||||
const type = name.substr(PREFIX.length);
|
||||
const value = t(attr.value);
|
||||
switch (name) {
|
||||
switch (type) {
|
||||
case 'text':
|
||||
node.insertBefore(document.createTextNode(value), node.firstChild);
|
||||
break;
|
||||
|
@ -63,15 +81,17 @@ function tNodeList(nodes) {
|
|||
node.insertAdjacentHTML('afterbegin', value);
|
||||
break;
|
||||
default:
|
||||
node.setAttribute(name, value);
|
||||
node.setAttribute(type, value);
|
||||
}
|
||||
node.removeAttribute(attr.nodeName);
|
||||
node.removeAttribute(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function tDocLoader() {
|
||||
t.cache = tryJSONparse(localStorage.L10N) || {};
|
||||
const cacheLength = Object.keys(t.cache).length;
|
||||
// localize HEAD
|
||||
tNodeList(document.getElementsByTagName('*'));
|
||||
|
||||
|
@ -85,6 +105,9 @@ function tDocLoader() {
|
|||
const onLoad = () => {
|
||||
tDocLoader.stop();
|
||||
process(observer.takeRecords());
|
||||
if (cacheLength != Object.keys(t.cache).length) {
|
||||
localStorage.L10N = JSON.stringify(t.cache);
|
||||
}
|
||||
};
|
||||
tDocLoader.start = () => {
|
||||
observer.observe(document, {subtree: true, childList: true});
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
<title i18n-text-append="optionsHeading">Stylus </title>
|
||||
<link rel="stylesheet" href="index.css">
|
||||
<script src="/dom.js"></script>
|
||||
<script src="/localization.js"></script>
|
||||
<script src="/messaging.js"></script>
|
||||
<script src="/localization.js"></script>
|
||||
<script src="/prefs.js"></script>
|
||||
<script src="/apply.js"></script>
|
||||
</head>
|
||||
|
|
|
@ -56,8 +56,8 @@
|
|||
</template>
|
||||
|
||||
<script src="dom.js"></script>
|
||||
<script src="localization.js"></script>
|
||||
<script src="messaging.js"></script>
|
||||
<script src="localization.js"></script>
|
||||
<script src="prefs.js"></script>
|
||||
<script src="apply.js"></script>
|
||||
<script src="popup.js"></script>
|
||||
|
|
Loading…
Reference in New Issue
Block a user