feature (boot): optimisation for faster boot

This commit is contained in:
MickaelK 2025-09-02 17:32:54 +10:00
parent 45bc001f5e
commit 3d571b7a08
6 changed files with 65 additions and 53 deletions

View file

@ -0,0 +1,6 @@
document.head.appendChild(Object.assign(document.createElement("script"), {
type: "importmap",
textContent: JSON.stringify({
imports: window.bundler.esModules,
}, null, 4),
}));

View file

@ -1,4 +1,3 @@
if (!HTMLScriptElement.supports?.("importmap")) throw new Error("fastboot is not supported on this platform");
window.bundler = (function(origin) {
const esModules = {};
return {
@ -32,17 +31,3 @@ window.bundler = (function(origin) {
esModules,
};
})(new URL(import.meta.url).origin);
await new Promise((resolve, reject) => {
document.head.appendChild(Object.assign(document.createElement("script"), {
type: "module",
src: `./assets/bundle.js?version=${window.VERSION}`,
onload: resolve,
onerror: reject,
}));
});
document.head.appendChild(Object.assign(document.createElement("script"), {
type: "importmap",
textContent: JSON.stringify({
imports: window.bundler.esModules,
}, null, 4),
}));

View file

@ -1,9 +1,3 @@
import { init as initConfig, getVersion, get } from "../model/config.js";
const DEBOUNCETIME = 100;
await initConfig();
class FilestashTable extends HTMLElement {
constructor() {
super();
@ -30,7 +24,7 @@ class FilestashTable extends HTMLElement {
type: "refresh",
payload: { name: this.getAttribute("name"), src: this.getAttribute("src") },
}, "*");
}, DEBOUNCETIME);
}, 100);
}
}
@ -42,7 +36,6 @@ class FilestashTable extends HTMLElement {
connectedCallback() {
const src = this.getAttribute("src") || "";
const name = this.getAttribute("name") || "main.dat";
const mime = get("mime", {})[name.split(".").pop().toLowerCase()];
this.style.display = "inline-block";
this.iframe.srcdoc = `<!DOCTYPE html>
@ -81,31 +74,33 @@ class FilestashTable extends HTMLElement {
}
});
</script>
<script type="module" defer>
import { render } from "${import.meta.url}/../../${getVersion()}/index.js";
import * as Application from "${import.meta.url}/../../${getVersion()}/pages/viewerpage/application_table.js";
import { init as initConfig, getVersion, get } from "${import.meta.url}/../../model/config.js";
const $app = document.querySelector("#app");
render(Application, $app, {
mime: "${mime}",
hasMenubar: true,
getFilename: () => "${name}",
getDownloadUrl: () => "${src}",
});
window.addEventListener("message", (event) => {
if(event.data.type === "refresh") {
render(Application, $app, {
mime: "${mime}",
hasMenubar: true,
getFilename: () => event.data.payload.name,
getDownloadUrl: () => event.data.payload.src,
});
}
});
await initConfig();
const { render } = await import("${import.meta.url}/../../"+ getVersion() +"/index.js");
const Application = await import("${import.meta.url}/../../"+ getVersion() +"/pages/viewerpage/application_table.js");
const $app = document.querySelector("#app");
const mime = get("mime", {})["${name}".split(".").pop().toLowerCase()];
render(Application, $app, {
mime: mime,
hasMenubar: true,
getFilename: () => "${name}",
getDownloadUrl: () => "${src}",
});
window.addEventListener("message", (event) => {
if(event.data.type === "refresh") {
render(Application, $app, {
mime: mime,
hasMenubar: true,
getFilename: () => event.data.payload.name,
getDownloadUrl: () => event.data.payload.src,
});
}
});
</script>
<script type="module" src="${import.meta.url}/../../${getVersion()}/components/modal.js"></script>
<component-modal></component-modal>
</body>
</html>`;

View file

@ -23,6 +23,6 @@ export async function load(mime) {
const specs = plugins[mime];
if (!specs) return null;
const [, url] = specs;
const module = await import(url);
const module = await import(new URL(url, import.meta.url).href);
return module.default;
}

View file

@ -33,15 +33,20 @@
</template>
<script type="module">
function liftoff() {
document.head.appendChild(document.querySelector("template#head").content);
document.body.appendChild(document.querySelector("template#body").content);
}
async function ignitionSequence() {
window.VERSION = "{{ slice .version 0 7 }}::{{ .hash }}";
try { await import("./assets/boot/warmup.js"); }
catch (err) { console.error(err); }
try {
if (!HTMLScriptElement.supports?.("importmap")) throw new Error("fastboot is not supported on this platform");
{{ load_asset "assets/boot/bundler_init.js" }}
await new Promise((resolve, reject) => document.head.appendChild(Object.assign(document.createElement("script"), {
type: "module",
src: `./assets/bundle.js?version=${window.VERSION}`,
onload: resolve,
onerror: reject,
})))
{{ load_asset "assets/boot/bundler_complete.js" }}
} catch (err) { console.error(err); }
await Promise.all([
import("./assets/{{ .version }}/components/loader.js"),
@ -52,6 +57,11 @@
}),
]);
}
function liftoff() {
document.head.appendChild(document.querySelector("template#head").content);
document.body.appendChild(document.querySelector("template#body").content);
}
//
//
//

View file

@ -12,6 +12,7 @@ import (
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"text/template"
@ -209,7 +210,22 @@ func ServeIndex(indexPath string) func(*App, http.ResponseWriter, *http.Request)
SendErrorResult(res, err)
}
}
tmpl := template.Must(template.New(indexPath).Parse(string(b)))
tmpl := template.Must(template.New(indexPath).Funcs(template.FuncMap{
"load_asset": func(path string) (string, error) {
file, err := WWWPublic.Open(path)
if err != nil {
return "", err
}
out := "/* LOAD " + path + " */ "
f, err := io.ReadAll(file)
file.Close()
out += regexp.MustCompile(`\s+`).ReplaceAllString(
strings.ReplaceAll(string(f), "\n", ""),
" ",
)
return out, err
},
}).Parse(string(b)))
tmpl = template.Must(tmpl.Parse(string(TmplLoader)))
return func(ctx *App, res http.ResponseWriter, req *http.Request) {
@ -389,7 +405,7 @@ func ServeBundle() func(*App, http.ResponseWriter, *http.Request) {
Log.Warning("static::bundle msg=marshal_failed path=%s err=%s", path, err.Error())
continue
}
fmt.Fprintf(&buf, "bundler.register(%q, %s);\n", path, code)
fmt.Fprintf(&buf, "bundler.register(%q, %s);\n", WithBase(path), code)
}
etag = QuickHash(string(bundlePlain), 10)
bundlePlain = buf.Bytes()