perf(aegis): 251 KB off every panel open — jsQR loads when it is wanted
panel.html loaded lib/jsqr.js synchronously: 257 KB and 10,105 lines of
vendored decoder parsed on every panel open, so on every hide/show, for a
feature most sessions never touch. It is now fetched the first time someone
imports a QR image, with concurrent callers sharing one load and a failed
load retryable rather than cached as a permanent rejection.
qr.js and panel.js get `defer`, so the browser can paint the (already dark)
document before executing 300 KB of panel.js. Order is preserved, so qr.js
is still defined before panel.js runs.
Parsed on open: 650 KB -> 399 KB.
This shortens the blank window but does not remove it. The white box itself
is Theseus-side: the sidebar panel's view is built as
new WebContentsView({ webPreferences: { preload: "sidebar-preload.js" } })
with no backgroundColor, and Electron defaults a view's background to white —
so white shows from view-attach until the page paints. Every other view in
the app passes a colour, and registerSidebarPanel takes only
{id, title, icon, page}, so an add-on cannot declare one. Not fixed here:
main.js belongs to the Theseus work in flight.
This commit is contained in:
parent
7983e24f2e
commit
65b4ac5ad3
3 changed files with 29 additions and 5 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "aegis",
|
"id": "aegis",
|
||||||
"name": "Aegis Wallet",
|
"name": "Aegis Wallet",
|
||||||
"version": "0.28.0",
|
"version": "0.28.1",
|
||||||
"category": "plugin",
|
"category": "plugin",
|
||||||
"description": "Multi-chain wallet (BCH, BTC, TRX, ETH, SOL, SC, DGB) derived from your Theseus vault. Dapps get window.bitcoincash and window.wizardconnect on any site; window.tronWeb / window.tronLink / window.ethereum / window.solana too. Every call needs your approval.",
|
"description": "Multi-chain wallet (BCH, BTC, TRX, ETH, SOL, SC, DGB) derived from your Theseus vault. Dapps get window.bitcoincash and window.wizardconnect on any site; window.tronWeb / window.tronLink / window.ethereum / window.solana too. Every call needs your approval.",
|
||||||
"author": "Silent Mode",
|
"author": "Silent Mode",
|
||||||
|
|
|
||||||
|
|
@ -1387,8 +1387,14 @@
|
||||||
<span class="brandver" id="brandVer"></span>
|
<span class="brandver" id="brandVer"></span>
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
<script src="lib/jsqr.js"></script>
|
<!-- jsqr.js is deliberately NOT loaded here: 257 KB of vendored decoder,
|
||||||
<script src="qr.js"></script>
|
parsed on every panel open (so on every hide/show), for a feature most
|
||||||
<script src="panel.js"></script>
|
sessions never touch. panel.js fetches it the first time someone imports
|
||||||
|
a QR image. `defer` lets the browser paint the already-dark document
|
||||||
|
before executing 300 KB of panel.js, which shortens the blank window
|
||||||
|
while the view loads. Order is preserved, so qr.js is still defined
|
||||||
|
before panel.js runs. -->
|
||||||
|
<script src="qr.js" defer></script>
|
||||||
|
<script src="panel.js" defer></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1619,8 +1619,26 @@ function classifyScannedSecret(text) {
|
||||||
return { kind: "unknown", value: s };
|
return { kind: "unknown", value: s };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// jsQR is 257 KB of vendored decoder and it is only needed when someone
|
||||||
|
// actually imports a QR image. Loading it from panel.html meant every panel
|
||||||
|
// open — every hide/show — parsed all of it before panel.js even started.
|
||||||
|
// Fetch it the first time it is wanted instead.
|
||||||
|
let jsqrLoad = null;
|
||||||
|
function loadJsQr() {
|
||||||
|
if (typeof jsQR === "function") return Promise.resolve();
|
||||||
|
if (jsqrLoad) return jsqrLoad;
|
||||||
|
jsqrLoad = new Promise((resolve, reject) => {
|
||||||
|
const el = document.createElement("script");
|
||||||
|
el.src = "lib/jsqr.js";
|
||||||
|
el.onload = () => (typeof jsQR === "function" ? resolve() : reject(new Error("the QR decoder loaded but exposed nothing")));
|
||||||
|
el.onerror = () => { jsqrLoad = null; reject(new Error("the QR decoder failed to load")); };
|
||||||
|
document.head.appendChild(el);
|
||||||
|
});
|
||||||
|
return jsqrLoad;
|
||||||
|
}
|
||||||
|
|
||||||
async function decodeQrFile(file) {
|
async function decodeQrFile(file) {
|
||||||
if (typeof jsQR !== "function") throw new Error("the QR decoder failed to load");
|
await loadJsQr();
|
||||||
const bitmap = await createImageBitmap(file);
|
const bitmap = await createImageBitmap(file);
|
||||||
try {
|
try {
|
||||||
// Very large photos cost time and memory for no accuracy gain; jsQR wants
|
// Very large photos cost time and memory for no accuracy gain; jsQR wants
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue