html
html copied to clipboard
Consider improving interoperability of <iframe> throttling margins.
What is the issue with the HTML Standard?
My understanding is that all browsers implement some sort of throttling of offscreen / invisible iframes.
In Firefox, this is kind of messy, and differs between in-process and out-of-process iframes right now.
It seems according to @szager-chromium in Chromium there's no margin at all.
I think some things could probably be specified properly:
-
visibility: hidden
/display: none
should always be throttled. - Offscreen iframes should be throttled, with some UA-defined margin perhaps?
Are there other cases where UAs throttle iframes? cc @khushalsagar
For reference, here is chromium's logic:
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/frame/frame_view.cc;drc=4834462d69ddf6e0ac6b27572618e4436de4a2f3;l=317
Historically, we have also had one or two weird carve-outs for throttling logic that were driven by real-world usage; for example:
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/frame/frame_view.cc;drc=4834462d69ddf6e0ac6b27572618e4436de4a2f3;l=279
A tighter spec with WPT would be great.
Other than the visibility based throttling @szager-chromium mentioned, content-visibility
is the other reason I could find for it (@vmpstr for it). The throttling done for view transitions is already carved out separately.
c-v language is in https://www.w3.org/TR/css-contain-2/#cv-notes point number 7, but it's "should" language
What does margin refer to here? Criteria?
Distance with the viewport (as in, IntersectionObserver
margins etc).
Thanks! This would be reasonable to standardize more. Some relevant WebKit code:
- LocalFrameView::viewportContentsChanged
-
LocalFrameView::updateScriptedAnimationsAndTimersThrottlingState (we currently do not throttle
display:none
, but if everyone else does this seems reasonable to change) - Page::preferredRenderingUpdateFramesPerSecond
- DOMTimer::updateThrottlingStateIfNecessary
I'm wondering if content-visibility is a good concept to build on for this throttling; since the goal is similar: minimize rendering cost of content not relevant to the user (as opposed to just visible). For example, IIUC c-v will force layout for find-in-page. I'm wondering if lifecycle updates should similarly be resumed for offscreen iframes when the user triggers find-in-page, it's possible that a DOM update (which populates the content the user is searching for) is blocked on the next rAF.
@vmpstr might have input based on edge cases like this addressed for c-v.
For content-visibility
, it's not a comprehensive list but selection, focus, and accessibility (find in page specifically) are all things that cause us to do rendering. FWIW, content-visibility: auto
also has a user-agent defined margin for visibility that causes it to be relevant, which is similar to the iframe one if I understand correctly.
I don't think specifying the exact extent of this margin is worthwhile, but specifying more explicitly cases where we don't want throttling is useful.
IIRC, render throttling already has a carve-out that allows find-in-page to work correctly. I could be wrong.
We should be mindful that throttling rendering for off-screen iframes also prevents badly-behaved iframes from sabotaging battery usage and performance of the embedding page. In some situations chromium will throttle setTimeout
and setInterval
timers to 1s, and I wouldn't want requestAnimationFrame
to become an escape hatch that allows an iframe to run lots of code at high frequency.
Also see https://github.com/w3c/IntersectionObserver/issues/508#issuecomment-1545646474
What WebKit does there seems better from a privacy POV since it avoids the Text Fragment side-channel using APIs affected by thottling.
This is still on my list fwiw. I want to make a change to Gecko here to make it more consistent and confirm such a thing is web compatible before proposing it more formally.