Repository navigation
Offscreen rendering fps (Tao backend) #57
Description
Activity
- added a commit that references this issue
on Aug 30, 2026 Thanks for the detailed report. Short answer: there is no offscreen rendering and no frame-rate cap in the library, so there is no
max_fpsto expose — but I could not reproduce the slowdown either, so I would like your numbers before closing this.What the backend actually does
The desktop backend embeds a real native view, it never renders the page into a bitmap:
- macOS: the
WKWebViewNSViewis a subview of the Tao window, below the Compose Metal layer, which punches a transparent hole over the WebView rect - Linux: the WebKit2GTK widget is reparented into Tao's content widget
- Windows: WebView2 runs as a DirectComposition visual composited by DWM
No backend contains frame-rate logic (
grepfor fps/frame/vsync/timer overwebview-compose/src/jvmMain/native/**is empty). Pacing is the platform compositor's job.Measurements (macOS, M4, 90 Hz display, Nucleus Tao 2.5.5)
Embedded WebView vs. the same page in a bare
WKWebViewin a plainNSWindow:Workload Embedded (Tao NativeView)Bare WKWebViewCanvas 2D rAF90 fps 90 fps WebGL (light) 90 fps 90 fps WebGL, GPU-bound shader 31–34 fps 32–35 fps Compose rendered at 90 fps in the same window at the same time. Blending was the obvious suspect, so I measured it separately at full-screen size (2560×1040) with an animated Compose overlay composited over the WebView every frame — page fps / Compose fps, plus GPU utilization while both run at the display rate:
Compose overlay Light page GPU-bound page GPU util (light page) none 90 / 90 34 / 90 23.4 % 64 dp animated bar 90 / 90 34 / 90 — full-window translucent scrim 90 / 90 34 / 90 22.9 % full-window opaque surface 90 / 90 34 / 90 — bare WKWebView, opaque window90 34 27.6 % No measurable blending penalty. But my display is 2560×1040 @1x at 90 Hz on a desktop M4 (~2.7 Mpx/frame); a Retina ProMotion laptop is ~7.7 Mpx at 120 Hz, roughly 4× the compositing bandwidth and no fan — so this does not rule out your case, it only says I cannot see it here.
Could you run the diagnostics? (v1.0.2)
The visual e2e suite now reports two rendering measurements —
./gradlew :e2e-desktop:run, then look for:Passed R01 Rendering requestAnimationFrame rate 90 fps Passed R02 Rendering WebGL renderer Apple GPUWhat would help most, from your ProMotion Mac:
- The
R01/R02values (R01should be ~120 fps there;R02must name a GPU — a software renderer would explain slow WebGL immediately) - The same numbers in your own app, and whether Compose content overlaps the WebView
- The display refresh rate, and whether the window is on the internal Retina display or an external one
One trap worth ruling out first:
R01is reported as Skipped when the document ishidden. Every engine suspendsrequestAnimationFramefor a fully covered or backgrounded window — I hit exactly that during this investigation and a bareWKWebViewbehaves identically. So keep the window in front while measuring.Also relevant if you are on battery: an opaque Compose overlay does not stop the WebView underneath — it keeps rendering at full speed behind it, so the GPU work is duplicated. Hide or dispose it rather than covering it.
Details and how to reproduce: README section "Rendering model & frame rate" (#58).
- macOS: the
Thank you for your detailed answer!
Since this turned out to be a native view (perfect!) the cause is most likely in some other changes in our code. We didn't perform one-to-one comparison so this was just an impression (possibly wrong based on your explanation).You may close this issue for now I think. If we get some updates on this (or some actually measured numbers) I will reopen it. Thanks again!
Reacted by Elie Gambache
Overall, the new WebView with the Tao backend is very good!
However, we’ve noticed a noticeable performance degradation compared to previous versions (at least on Mac). It’s not as smooth as before, especially in WebGL games or maps. It definitely no longer renders at 120 FPS.
Is this caused by offscreen rendering costs, or are there internal settings that limit the frame rate to around 30 FPS? If so, could the max_fps API be made public?