perf: demand-driven rendering + mobile-aware auto (1.5.0) - #6
Open
amnn-in wants to merge 1 commit into
Open
Conversation
svg-clone and webgl no longer run an unconditional rAF loop. The loop spins down after ~1s with no observed motion and wakes on scroll / resize / pointer / CSS transitions & animations / style mutations / ResizeObserver / update()/refresh(). Idle cost per instance drops from 60 rAF ticks + 360 SVG attr writes + 120 forced rect reads per second (svg-clone) and 60 GL draws/s (webgl) to zero. - syncClone: relative-geometry no-op guard — scrolling glass and background together no longer touches the filter (attr writes forced a full re-filter every frame, the main mobile jank source) - renderGL: uniform-input key early-out; static image backgrounds skip the whole GL pass when nothing moved - new `live` option: null (auto — video/canvas backgrounds stay per-frame), false forces on-demand for static canvases, true forces a permanent loop. Wired through web component, React and types. - auto mode resolves to css on phones (userAgentData.mobile, falling back to any-pointer:fine) — the svg filter chain re-runs on every scrolled frame and janks mobile GPUs - ResizeObserver now also watches the background element - bench/verify-perf.mjs: 14 checks — idle counters, wake-on-scroll, scrolled-vs-fresh alignment, live/canvas semantics, mobile auto Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Field report: an app using glasskit lagged on mobile in every mode. Root cause for the refraction modes:
svg-cloneandwebglran an unconditionalrequestAnimationFrameloop forever, andsvg-clone's per-frame SVG attribute writes forced the browser to re-run the whole filter 60×/second even when nothing on screen moved. On top of that,autoserved mobile Chromium thesvgmode — the slowest possible path on a phone GPU.What changed
Demand-driven frame loop. The loop now spins down after ~1s with no observed motion and wakes on scroll / resize / pointer / wheel / CSS transitions & animations (window-level passive listeners), style/class mutations on the element, ResizeObserver (now also watching the background element), and
update()/refresh().No-op guards so "awake" ≠ "working".
syncClonekeys on relative geometry — glass scrolling together with its background writes nothing, so the SVG filter never re-runs (this was the big mobile jank source).renderGLkeys on its uniform inputs — a static image background skips the entire GL pass when nothing moved.Idle cost per instance (measured, old → new):
svg-clonewebglNew
liveoption (engine +<glass-kit live>+ React + types):null= auto (video/canvas backgrounds keep per-frame texture upload, since their pixels can change without any layout signal — the generator's WebGL preview is unaffected),false= on-demand even for a static canvas (callrefresh()after redrawing),true= permanent loop.Mobile-aware
auto.autonow resolves tocsson phones (navigator.userAgentData.mobile, falling back to(any-pointer:fine)); refraction modes remain available explicitly. README gains a Performance section documenting all of this.Verification
New
bench/verify-perf.mjs(14 checks, all ✓): idle counters via instrumentedrequestAnimationFrame/SVGElement.setAttribute/drawArrays; scroll wakes and re-syncs the clone; a scrolled instance renders identically to a freshly-applied one (max channel delta 3/255 — Chromium filter noise, not misalignment);update()wakes exactly one re-render then idles; canvas live-by-default andlive:falsesemantics; Pixel 7 emulation →auto=css, desktop →svg.Regressions:
verify-buildmap(300 configs byte-identical, zoom probes ✓),verify-zoom(svg + webgl lensing, byte-identicalupdate({zoom:0})round-trips — proving the wake path renders exact frames),bench-smoke— all pass.Version: 1.5.0 (behavior change in
auto+ new option). After merge:git tag v1.5.0 && git push origin v1.5.0publishes to npm.🤖 Generated with Claude Code