ELK runs in a worker: the flow layout loads elkjs's worker build as a Vite ?worker behind elk-api, so a phone's eight layout passes no longer block the page (Demo house at 390px with 4x CPU throttling, long tasks 15.0 to 0.8 s, longest 2.1 to 0.3 s); positions and routes unchanged
This commit is contained in:
@@ -14,6 +14,20 @@ import assert from "node:assert/strict"
|
||||
// @ts-expect-error the runtime has it, the DOM types say it is not removable.
|
||||
globalThis.self = undefined
|
||||
|
||||
// A page runs ELK in a worker Vite builds (`?worker`). Here the same build
|
||||
// runs in-thread, as the fake worker it exports outside a worker.
|
||||
// @ts-expect-error the worker build ships without types.
|
||||
const { Worker: InThread } = await import("elkjs/lib/elk-worker.min.js")
|
||||
// @ts-expect-error bun's global, which the DOM types do not know.
|
||||
Bun.plugin({
|
||||
name: "elk in-thread",
|
||||
setup: (build: { module: (id: string, load: () => object) => void }) =>
|
||||
build.module("elkjs/lib/elk-worker.min.js?worker", () => ({
|
||||
exports: { default: InThread },
|
||||
loader: "object",
|
||||
})),
|
||||
})
|
||||
|
||||
const { layoutGraph, nodeHeight, portFraction, PORT_SPAN } = await import(
|
||||
"./layout"
|
||||
)
|
||||
|
||||
@@ -384,14 +384,20 @@ function wrapWideRanks(placed: Map<string, Point>, ids: string[]): Wrap[] {
|
||||
* The layout engine, fetched the first time a flow needs laying out.
|
||||
*
|
||||
* Its own chunk: ELK is a compiled Java library and weighs more than the rest
|
||||
* of the canvas put together, so nothing but this route ever loads it.
|
||||
* of the canvas put together, so nothing but this route ever loads it. And
|
||||
* its own thread: a phone lays the Demo house out eight times over, about
|
||||
* half a second each, which on the page would freeze it for seconds.
|
||||
*/
|
||||
let engine: Promise<{ layout: (graph: ElkNode) => Promise<ElkNode> }> | null =
|
||||
null
|
||||
|
||||
function elk() {
|
||||
engine ??= import("elkjs/lib/elk.bundled.js").then(
|
||||
(module) => new module.default(),
|
||||
engine ??= Promise.all([
|
||||
import("elkjs/lib/elk-api.js"),
|
||||
import("elkjs/lib/elk-worker.min.js?worker"),
|
||||
]).then(
|
||||
([api, worker]) =>
|
||||
new api.default({ workerFactory: () => new worker.default() }),
|
||||
)
|
||||
return engine
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user