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 @@
-
+
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';