Skip to content
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

Closed

Conversation

dreamofabear
Copy link

@dreamofabear dreamofabear commented Mar 10, 2020

Partial for #25428.

  • Keep using a single observer at 3vp and compute intersection with 1vp. In prerender mode, queue intersections outside of 1vp.
  • Addresses the stale layout box issue by reverting to continue to use the current system i.e. requesting measure on mutations, scheduling passes after element size changes, etc.
  • Removes some of the edge case handling for simplicity. I'll restore them if needed later.

Will add tests next.

/to @dvoytenko @jridgewell /cc @ampproject/wg-runtime

William Chou added 2 commits March 10, 2020 11:49
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.
@amp-bundle-size amp-bundle-size bot requested a review from samouri March 10, 2020 17:31
Copy link
Author

@dreamofabear dreamofabear left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good questions.

src/service/resources-impl.js Outdated Show resolved Hide resolved
src/service/resources-impl.js Outdated Show resolved Hide resolved
src/service/resources-impl.js Outdated Show resolved Hide resolved
src/service/resources-impl.js Outdated Show resolved Hide resolved
@dreamofabear
Copy link
Author

@jridgewell Friendly ping.

@@ -193,8 +193,17 @@ export class ResourcesImpl {
this.ampdoc.getVisibilityState()
);

/** @private {?IntersectionObserver} */
this.intersectionObserver_ = null;
/**
Copy link
Contributor

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?

Copy link
Author

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.

@dreamofabear dreamofabear changed the title intersect-resources: Support prerender mode intersect-resources: Support prerender mode, revert to fix stale layout boxes Mar 17, 2020
@dreamofabear dreamofabear changed the title intersect-resources: Support prerender mode, revert to fix stale layout boxes intersect-resources: Support prerender mode, patch for stale rects Mar 17, 2020
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);
Copy link
Contributor

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?

Copy link
Author

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.

Copy link
Contributor

@jridgewell jridgewell left a 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.

@dreamofabear
Copy link
Author

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.

@dreamofabear
Copy link
Author

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).

@dreamofabear
Copy link
Author

@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.

Copy link
Contributor

@dvoytenko dvoytenko left a 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);
Copy link
Contributor

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?

Copy link
Author

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).

@dreamofabear dreamofabear force-pushed the intobs-two-observers branch from 9d506d1 to 7148444 Compare March 25, 2020 00:46
@dreamofabear
Copy link
Author

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 discoverWork_ codepath intact for MVP.

Closing this PR for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants