-
Notifications
You must be signed in to change notification settings - Fork 3.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
intersect-resources: Support prerender mode, patch for stale rects #27176
intersect-resources: Support prerender mode, patch for stale rects #27176
Conversation
Add comment about first intersection callback in Chrome 82. Only prerender 1 viewport (if prerenderSize > 0). Create 3vp observer after first 1vp observer callback. Wait until visible to start 3vp observer. First firstCallback. Avoid double-handling by early-out when isIntersecting didn't change. Add comment. Simplify handling of first intersection callback. Tweak comment. Use ampdoc instead of viewer. Add comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good questions.
@jridgewell Friendly ping. |
src/service/resources-impl.js
Outdated
@@ -193,8 +193,17 @@ export class ResourcesImpl { | |||
this.ampdoc.getVisibilityState() | |||
); | |||
|
|||
/** @private {?IntersectionObserver} */ | |||
this.intersectionObserver_ = null; | |||
/** |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bigger question I have: if this continues to diverge in major ways, would it be easier to just fork this whole manager for the InOb experiment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. I only have a few small changes left to do, so this is nearly the final state.
Also I'm concerned about bundle size since we can't leverage module/nomodule or other tricks easily.
src/service/resources-impl.js
Outdated
for (let i = 0; i < this.resources_.length; i++) { | ||
const r = this.resources_[i]; | ||
if (r.getState() == ResourceState.NOT_BUILT && !r.isBuilding()) { | ||
this.buildOrScheduleBuildForResource_(r, /* checkForDupes */ true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are blocking build? We've not blocked build before - only loading. This is certain to be positive, but might have lots of regressions with the elements that do some early work on build?
Also, does the whenBuilt
never fail for any individual elements, or all together? Overall this seems like a pretty strict rule. What if a 1vp element is very slow in download?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, I was originally planning to split this out but I think this should be safe to do since we already do something similar in prerender mode with our quota system.
Good points on being bottlenecked by slow outliers. I'll think about how to mitigate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the handling of the two observers is weird. Why not just register both, and record what the actual distance to viewport is? Make you decisions from there.
Heh, I assume you're talking about the lazy instantiation of 3vp observer? After observing an element, there's an initial intersection entry/callback (even if not intersecting). So lazy instantiation (1) allows the browser to defer the work and (2) avoids the need for us to store/queue the entry. Alternatively, we could try just using one observer and always compute viewport distance. But this trades the complexity of two observers for a more complex handling with one observer. It's not clear to me that it's better, though I can try it out. |
Changed back to use one observer. Much simpler code, though at the cost of a few extra calculations and potentially staler rects due to queueing during prerender. Also removed the deferral of build on upgrade (will do that separately). |
@dvoytenko @jridgewell PTAL, the diff is much less scary now. :) In other news, the spec change was supposed to land in Chrome 81 which has now been postponed unfortunately. The experiment can still activate on non-iframed pages. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with one q.
intersects_(entries, unusedObserver) { | ||
intersects_(entries) { | ||
// TODO(willchou): Remove assert once #27167 is fixed. | ||
devAssert(this.prerenderSize_ == 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the value of the devAssert()
for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly as an FYI for readers. Assert would trigger for the few people that are playing with prerenderSize
in development (maybe just me).
9d506d1
to
7148444
Compare
Update: discovered a preexisting race condition (#27483) that affects the current IntersectionObserver implementation. Fixing this race is easy but I'm leaning towards a lower impact/risk integration that keeps most of the Closing this PR for now. |
Partial for #25428.
Will add tests next.
/to @dvoytenko @jridgewell /cc @ampproject/wg-runtime