On this pageOverview
Slow View
Every time your model changes, Foldkit calls your view function to build a virtual DOM tree describing what the screen should look like. Foldkit then diffs that tree against the previous one and patches the real DOM. The view call is only the first step — the diff, DOM patch, browser layout, and paint still happen after it returns.
By default, Foldkit measures how long the view call takes and warns in the console when it exceeds the frame budget. At 60fps the entire frame gets 16ms, so if view alone takes that long, you are already dropping frames before the DOM work even begins. The warning nudges you to move computation into update or memoize expensive subtrees with createLazy and createKeyedLazy.
The warning runs in dev mode by default (gated behind import.meta.hot), so there is zero runtime cost in production builds. Pass show: 'Always' to enable it in all environments — useful for staging or when logging to an observability tool like Sentry.
The default threshold is 16ms (one frame at 60fps). Pass a slowView config object to makeElement or makeApplication to customize it:
import { Option } from 'effect'
import { Runtime } from 'foldkit'
const element = Runtime.makeElement({
Model,
init,
update,
view,
container: document.getElementById('root')!,
slowView: {
thresholdMs: 50,
onSlowView: ({ model, message, durationMs, thresholdMs }) => {
console.warn(
`[slow view] ${durationMs.toFixed(1)}ms (budget: ${thresholdMs}ms)`,
{
model,
message: Option.getOrNull(message),
},
)
},
},
})
Runtime.run(element)Set slowView to false to disable the warning entirely. Pass an onSlowView callback to replace the default console.warn. The callback receives a SlowViewContext with the current model, the triggering message (Option<Message>, since the initial render has no message), durationMs, and thresholdMs. This gives you enough context to log slow views to Sentry or another observability service with the full application state at the time of the slow render.
When the warning fires, the most effective fix is usually memoization. The next page covers createLazy and createKeyedLazy — two tools for caching view subtrees so they skip both VNode construction and DOM diffing.