Documentation menu

Performance

Measure your production page before changing its update strategy. Include the entry, static imports and modules the page actually fetches; a small entry can still load a large set of component, hydration and fallback chunks.

Rendering and keyed rows

Reducers run immediately. One scheduler batches DOM work in a microtask, renders parents before children, and runs focus and other post-render work after the commit. A message can trigger a view even when the reducer returns the same state; unchanged binding values do not rewrite the DOM. Keep views pure and deterministic.

Use each(items, key, row, pick?) for lists that insert, remove or reorder items. It skips a row when its item reference and picked inputs are unchanged. Preserve unchanged objects in your reducers and put changing external row inputs in pick; do not capture outer view state in the row function. Development checks and the row-purity lint help detect mistakes. See Views and Update.

Child components receive props by property. Unchanged declared props avoid a prop-triggered render; a child's own messages and stores can still update it. Mutating an object in place can hide a real change, while rebuilding every unchanged object defeats structural sharing. For a costly subtree, first isolate it as a component with explicit inputs and measure again.

Production compilation and payload

Use gyralVitePreset() for production builds. It compiles template strings and binding paths ahead of time and removes development diagnostics. A client-only app can use clientOnly: true to exclude hydration machinery when no server markup needs it. This is a build contract: do not use that option for a server-rendered page.

The repository's pnpm size --json measures production JavaScript with gzip level 9 and reports the initial payload separately from all chunks. pnpm size:check enforces example budgets. The package overview gives measurements of Gyral's examples; they are examples, not a guarantee of your app's size. Compare versions with the same build options and assets.

Hydration and loading

Hydration adopts server nodes rather than rebuilding the page. Its first view must agree with the server's state, props, stores and formatted text. Recovery from a mismatch adds work and can disturb user input. Read Server rendering and use production hydration tests, including forms edited before scripts arrive.

Choose islands when a region can wait until visible, idle or interaction. Keep initial HTML useful and ensure keyboard users can reach the interactive part. Preload the modules a page needs using its build manifest; avoid preloading every route just to make one navigation faster. Automatic component loading and manual route splitting should be measured on the whole page, including their loader and preload overhead. See Code splitting and Rendering modes.

Reproduce a speed claim

The Gyral benchmarks build the same six client-rendered apps with Gyral from npm and with current React, Preact, Vue, Svelte, Solid and Lit. Each run's raw data and notes describe the machine, versions and variation, so compare frameworks within one run only. They measure small apps in one browser, not server rendering or your application.

For your page, record network payloads and a browser performance trace for the action users care about. Separate script, layout, paint and frame wait; fewer reducer milliseconds need not make the visible action faster. Warm up, repeat the same tasks, retain raw results and compare in one environment. Check input correctness alongside timings. For bursty external sources, evaluate renderOnFrame; discrete clicks and submits usually need the default microtask rendering. See Testing.