whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
8.17k stars 2.69k forks source link

Proposal: fire an event before the first rendering opportunity after activation #9315

Closed noamr closed 11 months ago

noamr commented 1 year ago

The problem: we have several lifecycle/visibility events, like pageshow, but none of them take progressive rendering into account. There is currently no event that is fired before the first rendering opportunity after activation (either due to a new document or BFCache/prerender reactivation).

This is needed for cross-document view transitions, as well as for metrics, and solving this can allow the developer to perform "last minute" DOM changes after the document is initialized but before it's rendered.

The proposal: Expose an event (reveal? beforepageshow?) that is guaranteed to be called before the first requestAnimationFrame callback but after activation and after a document is no longer render-blocked.

When a cross-document view transition is present, this event would include a reference to the ViewTransition object, which would allow the new document to observe when the transition is finished, skip it, or potentially extend it. See explainer.

smaug---- commented 1 year ago

This problematic. Nothing may be re-rendered when coming out of the bfcache, as an example, if the rendering is still cached. Why is rAF not enough? That should force rendering if something in DOM is changed in a way which affects the page visually.

noamr commented 1 year ago

This problematic. Nothing may be re-rendered when coming out of the bfcache, as an example, if the rendering is still cached. Why is rAF not enough? That should force rendering if something in DOM is changed in a way which affects the page visually.

hmm interesting point about cached rendering for BFCache. It's possible to simulate this by calling rAF both in the head and in pageshow. Two downsides:

  1. we didn't want this event to fire during update the rendering.
  2. Requiring to have this rAF in two places is error prone. In the case of view transitions, developers might think that their transitions work, but they would be buggy when the page is restored from BFCache if they have the rAF only in the head. Having a reveal event and pointing to it as the place to put transition-related DOM changes seems more solid.

A possible solution is to fire this event if rendering is still cached, but we force it if there's a cross-document transition. An alternative is to call it something else, and always fire it right after pageshow and before the document's first regular rAF callback, regardless of whether there's a rendering opportunity in practice.

/cc @khushalsagar

khushalsagar commented 1 year ago

A possible solution is to fire this event if rendering is still cached, but we force it if there's a cross-document transition.

Did you mean "not fire" this event if rendering is still cached?

Nothing may be re-rendered when coming out of the bfcache, as an example, if the rendering is still cached.

Funny enough, we ran into this while prototyping. The bug is still being fixed. You can see it in action on chrome canary (<116.0.5791.0) if you enable VT on navigations, load https://foil-persistent-bookcase.glitch.me/page2.html, click navigate then go back/fwd. Because the browser displays the cached rendering of the restored page before its first rAF, you get a flash of the restored page and then an animation. The fix is simply to not display the cached rendering.

The reason being that the restored page will start rendering with a tree of view-transition pseudo-elements that show a screenshot of the old page. Authors can then customize the animation when the restored page starts rendering, same as what would happen with an SPA back/fwd nav.

There is no standardization around displaying the restored page's cached rendering (to my knowledge). Looks like with this feature we'll have to explicitly say, "the browser shouldn't display any cached rendered output of the restored page, first frame must be the output of the first rendering opportunity after pageShow". @smaug---- Does that sound reasonable?

smaug---- commented 1 year ago

It doesn't really. Isn't tab switching quite similar case. Browsers do throttle the background tabs heavily, but when making such tab foreground, something needs to be painted, asap, even if there is slow running JS running in that background tab. Bfcache isn't too different to that. We don't want to let the page to postpone showing the page to the user.

noamr commented 1 year ago

It doesn't really. Isn't tab switching quite similar case. Browsers do throttle the background tabs heavily, but when making such tab foreground, something needs to be painted, asap, even if there is slow running JS running in that background tab. Bfcache isn't too different to that. We don't want to let the page to postpone showing the page to the user.

So do you display the tab before the pageshow event? Because that will cause a flicker if you do and pageshow changes the DOM, right?

khushalsagar commented 1 year ago

@smaug----, I agree that we don't want this policy in general. Chrome has similar behaviour, if you switch tabs (or go to a page restored from BFCache) we flip to the cached rendering of the new page if available. If the transition to the new page is going to be a direct flip, it makes sense to do it asap.

I was hoping to carve out an exception if there is a ViewTransition. In this case it makes sense to keep the last rendered output of the old page onscreen until the restored page draws a frame. Because the restored page is going to start with a snapshot of the old page's contents (wrapped up in view-transition pseudo-elements) and customize the transition instead of a direct flip. So the spec should mandate this behaviour only if there is a ViewTransition.

@noamr you're right that if the page chooses to update the DOM in pageshow, you'd see a "flicker". But we can't really avoid that. Multiple browsers have UI which need to show screenshots of inactive pages (tab switcher on Chrome on Android or back/forward swipe on Safari come top of mind). Browser UX can paper over such flickers by animating between a screenshot and live DOM.

noamr commented 1 year ago

We don't want to let the page to postpone showing the page to the user.

... In situations where navigation is explicitly different from tab-switching, i.e. there's a pageshow or reveal event, this is potentially exactly what the developer wants.

However, delaying is not the problem here. In the case of having cached rendering on BFCache traversal and no view-transition, we can fire that event without re-rendering. This would keep this "cached rendering" thing an implementation detail that's not observable.

The event should be somewhat equivalent to addEventListener('pageshow', () => requestAnimationFrame(...)) with subtleties that make it distinct enough (also fired on initial render-unblock, fired before update-the-rendering)

smaug---- commented 1 year ago

So if pageshow listener does slow things, like it often may do, rendering might be postponed significantly and user experience would be worse, since user wouldn't see anything. Or I'm not sure what would be visible... the previous page, while the current is already the one which got out of bfcache...that might be a security issue then. We also don't want flickers when a page comes out of the bfcache, so something reasonable should be painted.

noamr commented 1 year ago

So if pageshow listener does slow things, like if often may do, rendering might be postponed significantly and user experience would be worse, since user wouldn't see anything. Or I'm not sure what would be visible... the previous page, while the current is already the one which got out of bfcache...that might be a security issue then. We also don't want flickers when a page comes out of the bfcache, so something reasonable should be painted.

Not sure how pageshow is related. Not suggesting to change the behavior of pageshow.

smaug---- commented 1 year ago

You said "The event should be somewhat equivalent to addEventListener('pageshow', () => requestAnimationFrame(...))"

noamr commented 1 year ago

You said "The event should be somewhat equivalent to addEventListener('pageshow', () => requestAnimationFrame(...))"

Right, it would be somewhat equivalent to that in behavior. But not suggesting to change the behavior of pageshow. The event should only affect the lifecycle if there are (same-origin) view-transitions, otherwise it's the same as "pageshow" or something like waiting for all render-blocking styles/scripts to load.

khushalsagar commented 1 year ago

Let's take this up in a separate issue, filed https://github.com/w3c/csswg-drafts/issues/8888. The desired behaviour is needed irrespective to the event proposed here.

khushalsagar commented 1 year ago

This was discussed at CSSWG recently, the notes are on https://github.com/w3c/csswg-drafts/issues/8805#issuecomment-1640688426. There is general support of the idea but we need a discussion at HTML WG to narrow down the specifics of when the event is dispatched and whether it should be VT specific.

khushalsagar commented 1 year ago

@noamr's feedback below.

Re: whether this event should fire only when there is a transition, one of the use-cases to fire it every time is detecthing whether is a transition to execute code which is deferred until the end of the transition. For example:

function hideLoader() { ... }

document.addEventListener("reveal", event => {
if (event.viewTransition) {
  event.viewTransition.finished.then(hideLoader);
} else {
  hideLoader();
}
});

A transient loading UI which is hydrated with content when the transition is finished. If the event is not fired when there is no transition then authors will have to write awkward code to track whether the event was fired and run hideLoader() immediately on rAF if it was not fired (indicating no transition).

vmpstr commented 1 year ago

At the HTML spec triage, we've talked about a possibility of the rAF based solution. Below roughly would be the equivalent required for the same effect (I actually don't know of a sure way to hook into the first rAF, but I think just doing requestAnimationFrame works)

<script>
function runRevealEvent() {
  if (document.activeViewTransition) {
    ...
  }
  ...
}

// For the "very first rAF" (this works, right?)
requestAnimationFrame(runRevealEvent);

// For BFCache activation
addEventListener("pageshow", e => { if (e.persisted) { runRevealEvent() } });
</script>

With the reveal event, the code would be the following:

<script>
// This fires at "the right time" whether or not it's a new navigation
// or BFCache activation
addEventListener("reveal", e => {
  if (e.viewTransition) {
    ...
  }
  ...
});
</script>

To make my case: the script here is by no means complicated, but for the user adopting view transitions, in the latter case, the only way to get the viewTransition object is to listen to this event, and this event will work correctly for BFCache and new navigation cases. This seems hard to get wrong.

In the former, it seems easy enough to miss the BFCache case. Also, the if (document.activeViewTransition) check has two meanings:

/cc @smaug---- @mfreed7

smaug---- commented 1 year ago

One very nice feature of rAF based solution is that it is basically an explicit request to paint. Adding an event listener is not. And when coming out of bfcache one might not paint normally, because it would be just useless if the rendering has been cached. Sure, implementation might optimize behavior so that painting would happen if event listener is there and avoid useless paints without it.

And in the first example the question about 'very first rAF...?' applies to adding the event listener too. If rendering is blocked in some way (through the explicit renderBlocking or via the old style heuristics, which are somewhat spec'ed), I'd expect both to work.

Tab switching is still something a bit unclear to me. If a page is loaded in a background tab, it might not be painted at all before the tab is brought to foreground. I guess I don't know how view transitions are supposed to work in that case.

(And yesterday when I talked about FF not implementing render blocking, I meant explicit blocking="render" . FF bug)

noamr commented 1 year ago

One very nice feature of rAF based solution is that it is basically an explicit request to paint. Adding an event listener is not. And when coming out of bfcache one might not paint normally, because it would be just useless if the rendering has been cached. Sure, implementation might optimize behavior so that painting would happen if event listener is there and avoid useless paints without it.

Why does this need to be an explicit request to paint? You might want the event without wanting to paint.

The problem with the rAF-based solution is that it's very easy to overlook BFCache-restore, creating bugs. you'd always have to do the following, otherwise your animation would sometimes work and sometimes not:

/* in <head> */
function animateTransitionWithWebAnimations() { if (document.inboundViewTransition) { ... } }
requestAnimationFrame(animateTransitionWithWebAnimations);
document.addEventListener("pageshow", animateTransitionWithWebAnimations);

It's OK to do this and educate people about it but it seems awkward.

And in the first example the question about 'very first rAF...?' applies to adding the event listener too. If rendering is blocked in some way (through the explicit renderBlocking or via the old style heuristics, which are somewhat spec'ed), I'd expect both to work.

Tab switching is still something a bit unclear to me. If a page is loaded in a background tab, it might not be painted at all before the tab is brought to foreground. I guess I don't know how view transitions are supposed to work in that case.

There are no view transitions in tab switching. I think the reveal event should apply if it's the first render opportunity in that tab.

(And yesterday when I talked about FF not implementing render blocking, I meant explicit blocking="render" . FF bug)

vmpstr commented 1 year ago

The need to have two different ways to hook into rAF (initial frame + pageshow for persisted case) is going to make this approach error prone. I still prefer that we consider the reveal event (perhaps named something less similar to pageshow).

I also want to clarify that the rAF based solution isn't "free". That is, it isn't only using existing features: it also requires activeViewTransition (or inboundViewTransition as @noamr called it). So I think the cost between the two solutions is similar.

The pro of the rAF based solution is that we don't need to worry about event timing, but the con is that the developer can get the pattern wrong pretty easily (omitting BFCache case for example).

The pro of the "reveal" event is that it's hard for the developer to get it wrong. The con is that it may be trickier to specify in all cases (e.g. tab switching).

Let me know if you disagree with this assessment. If it's correct, then I think we should prioritize the ease of use for the developer

noamr commented 1 year ago

The pro of the "reveal" event is that it's hard for the developer to get it wrong. The con is that it may be trickier to specify in all cases (e.g. tab switching).

The challenge with the reveal event is that when activating from BFCache there might not be an animation frame at all (on Firefox). This is an actual issue. Perhaps we should fire the reveal event:

  1. Right before the first rAF
  2. Right after pageshow when reactivating, whether there's a pending animation or not
vmpstr commented 1 year ago

Correct me if I'm wrong, but the reveal event does not need an animation frame, it just needs to fire before the first animation frame would happen (like option 2 in your example). We haven't discussed the timing of the event in great detail yet. With view transitions, the animation frame will happen but for reasons unrelated to the reveal event

noamr commented 1 year ago

Correct me if I'm wrong, but the reveal event does not need an animation frame, it just needs to fire before the first animation frame would happen (like option 2 in your example). We haven't discussed the timing of the event in great detail yet. With view transitions, the animation frame will happen but for reasons unrelated to the reveal event

In the current spec draft it's at the first rAF after page init/activation. But yes, this can be discussed and resolved. I don't think it's THAT complex, and if we don't figure it out developers would have to...

khushalsagar commented 1 year ago

@smaug---- @marcoscaceres

Just to make sure we’re on the same page with the use-case. A key motivation behind this proposal is to let authors customize the View Transition based on the state of the DOM at first paint, which itself relies on which sub-resources are fetched at that point.

For example, you’re going from page A to B where one image morphs into another. In page A you added a prefetch link to B’s image. When page B paints, the image on that side may/may not be available. So the author could design the transition as:

// Track whether the target image has been loaded.
let imageLoaded = false;
myImage.onload = () => { imageLoaded = true; };

function setUpTransition() {
   if (imageLoaded) {
      // If the image has loaded, tag it with a view-transition-name to create a morph animation.
      myImage.style.viewTransitionName = target;
  } else {
      // As a fallback, just fade-in the whole page.
     setUpRootOnlyTransition();
  }
}

The browser walks the DOM to discover elements with a view-transition-name on B once (for new page load or activation). The exact logic is spec’d in the capture new state algorithm. This means that setUpTransition() must run before this algorithm.

The way this works for same-document transitions is as follows:

Author calls document.startViewTransition(updateCallback) where updateCallback can be async. Browser captures the old DOM state and dispatches updateCallback where the author updates the DOM to the new state. Once updateCallback resolves, the browser immediately runs “capture new state”, spec’d here.

So authors can write code like this. The callback gives them an entry point to know state on first paint and set up transitions accordingly.

document.startViewTransition(async () => {
   await fetchNewResourcesOrTimeout();
   updateDOM();

   setUpTransition();
});

For cross-document transitions, fetchNewResourcesOrTimeout() and updateDOM() conceptually map to the browser parsing the new Document and waiting on render-blocked resources. But once that’s done, authors need an entry point for setUpTransition(). So the choices are:

  1. Add a new event which gives them that entry point, the proposal on this issue. Then “capture new state” can run immediately after the event is dispatched.

  2. Assume authors will use rAF() for setUpTransition() and move “capture new state” to after dispatching the rAF callbacks here.

I prefer 1 for consistency with the timing used for same-document transitions and the awkwardness with tracking the right rAF. I can be convinced for 2 but I’m not seeing how that’s better.

An alternate way to do this would be for authors to add load event listeners for each resource they care about and update the DOM whenever an event fires based on the current state. For example,

setUpRootOnlyTransitionForNow();
myImage.onload = () => {
   myImage.style.viewTransitionName = target;
   setUpImageTransition();
};

But that feels way less ergonomic, and will be required only with cross-document transitions because the requisite hook is not available.

One very nice feature of rAF based solution is that it is basically an explicit request to paint. Adding an event listener is not. And when coming out of bfcache one might not paint normally, because it would be just useless if the rendering has been cached.

I might be misunderstanding what you meant but I think it’s about the API contract for pages restored from BFCache:

vmpstr commented 1 year ago

and if we don't figure it out developers would have to...

This is a good way of putting it, and it's one of my main arguments for having a new event

smaug---- commented 1 year ago

The problem with "reveal" event is that if such listener is added, UA is forced to delay showing the restored-from-bfcache page to the user. UA would effectively need to ask permission from the web page when it can be shown. And handling the event might take quite a bit time. rAF does have similar issues, but so far nothing has guaranteed that rAF gets called when the page comes out of bfcache (which of course would be problematic for the view transitions use case).

Do we really want the main thread of the web page do anything related to the painting (like modify DOM) when coming out of bfcache? I'd expect view transition stuff being pushed to some other process (parent/compositor/whatever-it-is-called-in-different-browsers) and then we can guarantee smooth and fast transitions.

noamr commented 1 year ago

The problem with "reveal" event is that if such listener is added, UA is forced to delay showing the restored-from-bfcache page to the user. UA would effectively need to ask permission from the web page when it can be shown.

It shouldn't change the behavior in this way, unless there is an actual view transition. It's more similar to pageshow in the activation case. When there is no view transition, go ahead and present the page, and fire the event - it's there as a FYI so that you know that there is no view transition.

Do we really want the main thread of the web page do anything related to the painting (like modify DOM) when coming out of bfcache? I'd expect view transition stuff being pushed to some other process (parent/compositor/whatever-it-is-called-in-different-browsers) and then we can guarantee smooth and fast transitions.

Yes. The CSS needs to change to enable the pseudo-elements etc. And in the case of the reveal event when there is a view transition, perhaps the transition is going to be animated with the web animation API.

noamr commented 1 year ago

To clarify how this can work in the different scenarios:

  1. first render: fire right before first rAF
  2. BFCache/prerender reactivation, no view transition: fired before the first rAF after the page is shown. If the reactivated page can be displayed without main-thread work, it can be displayed before the reveal event.
  3. BFCache/prerender reactivation, view transition pending: showing old document until next render, fire before first rAF and display the old page until then
khushalsagar commented 1 year ago

@noamr don't think that's what you meant but just confirming. The timing of the event will be the same in BFCache/pre-render cases irrespective of whether there is a transition and it must be before first rAF after activation (whether before or after pageShow).

The only difference is that in the View Transition case, the first frame displayed for the new Document must be painted on the main thread which by design will include updates in the rAF callback. Even if this event didn't exist, that contract is still there.

noamr commented 1 year ago

@noamr don't think that's what you meant but just confirming. The timing of the event will be the same in BFCache/pre-render cases irrespective of whether there is a transition and it must be before first rAF after activation (whether before or after pageShow).

The only difference is that in the View Transition case, the first frame displayed for the new Document must be painted on the main thread which by design will include updates in the rAF callback. Even if this event didn't exist, that contract is still there.

Yes exactly. My comment was a bit confusing in hindsight, will revise

jakearchibald commented 1 year ago

If reveal fires at the same time as pageshow, except for the stupid case where pageshow fires after load, maybe call it pagereveal, and give the event .persisted.

Then, developers and just use pagereveal as the opposite of pagehide and forget pageshow ever existed.

noamr commented 1 year ago

If reveal fires at the same time as pageshow, except for the stupid case where pageshow fires after load, maybe call it pagereveal, and give the event .persisted.

Then, developers and just use pagereveal as the opposite of pagehide and forget pageshow ever existed.

I'm fine with all of this.

smaug---- commented 1 year ago

The semantics of (page)reveal is a bit weird if it is guaranteed to fire before first paint only when used with view transitions.

jakearchibald commented 1 year ago

Agreed. I hadn't realised that was the proposal.

noamr commented 1 year ago

We can either:

  1. do it this way (perhaps confusing?)
  2. make it always block (this can be misused?)
  3. Fire it only when there is a view transition (this can be error prone if the old document didn't opt in)
  4. Don't have an event, use a document accessor (can be very error prone, if developers don't explicitly write a pageshow handler or so)

I think we're going in circles between these.

My tendency is with (1) because it allows developers who build pages with view-transition to handle the case of a navigation where an expected view transition didn't happen.

noamr commented 1 year ago

OK speaking with @smaug---- on Matrix, perhaps we could do something different: Fire this event only when the current page has opted in to cross-document view transitions, but regardless of whether there is an actual view transition. It would need a different name. It would cover this use case without causing any overhead/confusing for non-VT cases.

One option is that it would always have a ViewTransition, but that it would be already in finished state if the previous document hasn't opted in, with some indicator of that.

noamr commented 1 year ago

Perhaps to avoid confusion, it could be a matter of naming? e.g. beforerenderingupdate, which doesn't necessarily imply "before first paint". @smaug---- @jakearchibald

khushalsagar commented 1 year ago

I'm good with beforerenderingupdate as well. I strongly feel that only dispatching it when the current Document opt-ins to VT is unnecessary complexity. The API contract options are:

  1. Guaranteed to fire before first rendering opportunity (both initial load and activation). Browser may display a cached frame from this Document if there is no transition.
  2. Guaranteed to fire before first rendering opportunity (both initial load and activation) if the Document has a ViewTransition opt-in for this navigation (the value can be configured based on multiple characteristics of the navigation, see table here). Browser may display a cached frame from this Document if there is no transition. Just because the current Document has an opt-in doesn't imply there will always be a transition. For example if this was a cross-origin navigation.

Irrespective of the 2 options above, whether the first frame displayed by the browser for this Document is something cached or output of first rendering opportunity is the same. If the problem with reveal is that the name seems to imply no cached output can be used then we can do a better name. Otherwise 2 is making this hard for implementors and adding no benefit for authors.

noamr commented 1 year ago

I still think option (1) would make things a lot simpler for developers, and we should find the right name for the event to avoid confusion. e.g. beforefirstrender, readytorender, canrender. I still think that reveal doesn't necessarily imply "before first paint", definitely it doesn't imply that more than pageshow. We're showing some old state and revealing the new one.

But in either case, I'm OK with finding a name that everyone is comfortable with and means "before the first rendering opportunity after a navigation"

bokand commented 1 year ago

As an FYI: adding a hook on the navigation API was considered in https://github.com/WICG/navigation-api/issues/256. Chatting with @khushalsagar though that doesn't handle the motivating reason for the reveal event, which is that it'd require authors to explicitly and separately handle BFCache which is likely to be mishandled - so I think we're leaning towards the event at this point.

noamr commented 1 year ago

So, we discussed it at TPAC and seemed like we received a go. @zcorpan @smaug---- can we treat it as a positive position from Mozilla as part of the view transitions feature? same for @annevk for webkit. I can open a new standards-position thing if it helps but I see this as part of view-transitions.

Regarding names: my current favorite is readytorender or pagereadytorender (or pagereveal). The "page" prefix mentally connects it with pageshow and pagehide as a page-lifecycle method of sorts.

Also it was not decided in TPAC whether the event should fire before the first rendering update or at the beginning of that update phase. Currently leaning towards the latter for simplicity, perhaps we can resolve this on the PR?

annevk commented 1 year ago

That's probably okay, but please make sure it's tracked as part of https://bugs.webkit.org/show_bug.cgi?id=259055.

domenic commented 1 year ago

Sorry for realizing this so late, but I think "reveal" or something similar related to visibility is going to be better than "render". The reason is that prerendering can definitely perform rendering while off screen. (It's right in the name, actually!) Chromium currently doesn't, but we'd like to, to close the performance gap between our current prerendering implementation and a truly-instant experience.

So, I think it'd be strange if you got an event like readytorender far after the rendering-to-pixels process had already started, i.e. after requestAnimationFrame()s had already started firing and other such things.

noamr commented 1 year ago

I also still like reveal.. Perhaps pagereveal to mentally link it with pageshow and pagehide. The concerns about reveal were that it's confusing in the case of displaying a cached image of the page, but I think that "displaying a cached image and then revealing the new state" is legit. Revealing means "showing gradually" which is exactly what this is about. @smaug----, @zcorpan?

jakearchibald commented 1 year ago

It might be helpful to restate when this event actually fires.

Is it as simple as "once a document becomes active, the event is fired before the end of the next render steps"?

It's a good point that this might not run before the user is presented a visual of the page, which may be a cached rendering or a prerender.

noamr commented 1 year ago

It might be helpful to restate when this event actually fires.

Is it as simple as "once a document becomes active, the event is fired before the end of the next render steps"?

It's "once a document becomes active and has a rendering opportunity, the event is fired right at the beginning of the next render steps"

It's a good point that this might not run before the user is presented a visual of the page, which may be a cached rendering or a prerender.

Correct.

smaug---- commented 1 year ago

Ok, so it could fire as part of the update rendering. Does that mean in practice that update rendering needs to happen at some point after restoring from bfcache? Since wouldn't it be rather surprising to never get the event (since nothing guarantees there is update rendering step after coming out of bfcache)

jakearchibald commented 1 year ago

@smaug---- hmmmmmm, it might be fine that it fires along with the next frame (which I guess could be never). View transitions would request a render on document activation.

noamr commented 1 year ago

Ok, so it could fire as part of the update rendering. Does that mean in practice that update rendering needs to happen at some point after restoring from bfcache? Since wouldn't it be rather surprising to never get the event (since nothing guarantees there is update rendering step after coming out of bfcache)

Spec-wise, there is an update the rendering phase after every task. Implementation-wise, we could either fire it when we are indeed going to render, or schedule a single rendering update only if this event has a listener.

smaug---- commented 1 year ago

(FWIW, the spec for update rendering will likely need to change anyhow if we ever want to get scheduling API to the HTML spec. And all the implementations have separate tasks to do rendering update, so the spec doesn't match reality.)

noamr commented 1 year ago

Sure. but in this case I'm OK with putting this event after the part where we exit early if the document doesn't need to be updated. So this would match the behavior of "this event is fired after activation, when there is both a rendering opportunity and the document needs to be rendered"

jakearchibald commented 1 year ago

So I guess the long name is frameafteractivate (assuming it's clear that doesn't mean every frame after activate)