Skip to content

fix(render): lazy playwright-core — static import cost ~20s per omp startup - #22

Merged
rz1989s merged 1 commit into
masterfrom
fix/lazy-playwright-import
Sep 6, 2026
Merged

fix(render): lazy playwright-core — static import cost ~20s per omp startup#22
rz1989s merged 1 commit into
masterfrom
fix/lazy-playwright-import

Conversation

@rz1989s

@rz1989s rz1989s commented Sep 6, 2026

Copy link
Copy Markdown
Member

What

Fixes #21.

extensions/render.ts statically imported playwright-core. omp's guarded extension loader preloads every statically resolvable import of an extension module at host startup — measured ~20s for playwright-core's ~9MB graph (a native bun import of the same package: 0.57s). chromium is used only inside the execute path, so every omp start paid 20s for a browser driver that almost never launches.

Attribution (omp 18.1.12, Apple M5)

Config omp total startup
all 3 plugins ~24–28s, loadExtensions warnings at 10s/20s
keystone disabled 5.5s
keystone skills-only 6.3s
playwright import line deleted 4.0s
import type (type-only) instead still 27.7s — loader preloads type imports too
dynamic await import("playwright-core") in fn body still 27.7s — loader preloads dynamic-import literals too
runtime-assembled specifier (this PR) 5.2s

Change

const spec = ["playwright", "-core"].join("")
const mod = await import(spec)

Memoized (cachedChromium), loads once on first actual render. Comment block in the file documents why the indirection exists and forbids reintroducing any static reference (including import type).

Verification

  • pnpm typecheck clean; full suite green: engine 162, lint 103, render 4 (real chromium launches through the lazy path), examples 1.
  • Real render under bun (omp's runtime) with the indirected import: screenshot + computed styles + DOM snapshot all produced.
  • omp -p startup timing: 27.7s → 5.2s, no Still starting warning.

Follow-up (out of scope here)

The omp-side loader behavior is the deeper bug: preloading extension import graphs (even type-only/dynamic) costs ~35× native import. Will report upstream to omp (can1357/tap, omp.sh).

…tartup

omp's guarded extension loader preloads every statically resolvable
import of an extension module at host startup — including import()
literals — and pays ~20s for playwright-core's ~9MB graph (native bun
import: 0.57s). chromium is only needed when a render executes.

The specifier is assembled at runtime (['playwright','-core'].join())
so no static analysis can pull it into the preload set; it loads once,
memoized, on first actual render. Verified under bun: full render
(screenshot + computed styles + dom snapshot) works with the indirected
import; omp startup 27.7s -> 5.2s.

Fixes #21
@rz1989s
rz1989s merged commit 03c5d51 into master Sep 6, 2026
1 check passed
@rz1989s
rz1989s deleted the fix/lazy-playwright-import branch September 6, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

omp startup: static playwright-core import in render.ts makes loadExtensions take ~20s

1 participant