diff --git a/lib/data-url-plugin.js b/lib/data-url-plugin.js index cf725d4d..34e9bec9 100644 --- a/lib/data-url-plugin.js +++ b/lib/data-url-plugin.js @@ -14,28 +14,40 @@ import { promises as fs } from 'fs'; import { lookup as lookupMime } from 'mime-types'; -const prefix = 'data-url:'; +const prefix = /^data-url(-text)?:/; export default function dataURLPlugin() { return { name: 'data-url-plugin', async resolveId(id, importer) { - if (!id.startsWith(prefix)) return; + const match = prefix.exec(id); + if (!match) return; return ( - prefix + (await this.resolve(id.slice(prefix.length), importer)).id + match[0] + (await this.resolve(id.slice(match[0].length), importer)).id ); }, async load(id) { - if (!id.startsWith(prefix)) return; - const realId = id.slice(prefix.length); + const match = prefix.exec(id); + if (!match) return; + + const isText = !!match[1]; + const realId = id.slice(match[0].length); this.addWatchFile(realId); const source = await fs.readFile(realId); const type = lookupMime(realId) || 'text/plain'; - return `export default 'data:${type};base64,${source.toString( - 'base64', - )}';`; + if (isText) { + const encodedBody = encodeURIComponent(source.toString('utf8')); + + return `export default ${JSON.stringify( + `data:${type};charset=utf-8,${encodedBody}`, + )};`; + } + + return `export default ${JSON.stringify( + `data:${type};base64,${source.toString('base64')}`, + )};`; }, }; } diff --git a/lib/omt.ejs b/lib/omt.ejs index 93c5a484..2fb71493 100644 --- a/lib/omt.ejs +++ b/lib/omt.ejs @@ -28,10 +28,17 @@ if (!self.<%- amdFunctionName %>) { <% } else { %> new Promise(resolve => { if ("document" in self) { - const script = document.createElement("script"); - script.src = uri; - script.onload = resolve; - document.head.appendChild(script); + const link = document.createElement("link"); + link.rel = "preload"; + link.as = "script"; + link.href = uri; + link.onload = () => { + const script = document.createElement("script"); + script.src = uri; + script.onload = resolve; + document.head.appendChild(script); + }; + document.head.appendChild(link); } else { self.nextDefineUri = uri; importScripts(uri); diff --git a/missing-types.d.ts b/missing-types.d.ts index 2adaaa15..b13952e1 100644 --- a/missing-types.d.ts +++ b/missing-types.d.ts @@ -44,6 +44,11 @@ declare module 'data-url:*' { export default url; } +declare module 'data-url-text:*' { + const url: string; + export default url; +} + declare module 'service-worker:*' { const url: string; export default url; diff --git a/src/client/initial-app/index.tsx b/src/client/initial-app/index.tsx index c81affc4..3f387cee 100644 --- a/src/client/initial-app/index.tsx +++ b/src/client/initial-app/index.tsx @@ -37,8 +37,10 @@ main(); ga('set', 'transport', 'beacon'); ga('set', 'dimension1', displayMode); ga('send', 'pageview', '/index.html', { title: 'Squoosh' }); - // Load the GA script - const script = document.createElement('script'); - script.src = 'https://www.google-analytics.com/analytics.js'; - document.head.appendChild(script); + // Load the GA script without keeping the browser spinner going. + addEventListener('load', () => { + const script = document.createElement('script'); + script.src = 'https://www.google-analytics.com/analytics.js'; + document.head.appendChild(script); + }); } diff --git a/src/shared/prerendered-app/Intro/imgs/logo-with-text.svg b/src/shared/prerendered-app/Intro/imgs/logo-with-text.svg index b4cfbec6..a9aa929e 100644 --- a/src/shared/prerendered-app/Intro/imgs/logo-with-text.svg +++ b/src/shared/prerendered-app/Intro/imgs/logo-with-text.svg @@ -1,10 +1 @@ - - -Squoosh +Squoosh diff --git a/src/shared/prerendered-app/Intro/index.tsx b/src/shared/prerendered-app/Intro/index.tsx index b777a4e3..84c11e45 100644 --- a/src/shared/prerendered-app/Intro/index.tsx +++ b/src/shared/prerendered-app/Intro/index.tsx @@ -14,7 +14,7 @@ import smallSectionAsset from 'url:./imgs/info-content/small.svg'; import simpleSectionAsset from 'url:./imgs/info-content/simple.svg'; import secureSectionAsset from 'url:./imgs/info-content/secure.svg'; import logoIcon from 'url:./imgs/demos/icon-demo-logo.png'; -import logoWithText from 'url:./imgs/logo-with-text.svg'; +import logoWithText from 'data-url-text:./imgs/logo-with-text.svg'; import * as style from './style.css'; import type SnackBarElement from 'shared/custom-els/snack-bar'; import 'shared/custom-els/snack-bar';