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

Convert ad iframes to get initialIntersection async #31753

Merged
merged 8 commits into from
Jan 14, 2021

Conversation

samouri
Copy link
Member

@samouri samouri commented Dec 28, 2020

summary
Alternative to #31714
Partial for #31540

AFAIK, only ads are supposed to use initialIntersection. The gltf extension happened to be using it as well, but IMO it shouldn't have since the message from viewportCallback should be more than good enough.

Changes:

  • Introduces new util for async measure with signature: measureIntersection(el) --> Promise<IntersectionObserverEntry
  • Uses it to measure initialIntersection for ad iframes.
  • Removes usage of initialIntersection from 3d gltf viewer

Breaking change: rootBounds and intersectionRatio are now according to spec as opposed to the definition we had been using. That means width/height is relative to viewport instead of the document's viewport.

TODO: figure out a less brittle solution for the tests. potentially just delete the assertions on intersectionRect etc. now that we are using the real InOb, so likely not worth testing.

I recommend viewing the changes with whitespace removed

@samouri samouri marked this pull request as draft December 28, 2020 22:25
@amp-owners-bot amp-owners-bot bot requested a review from nainar December 28, 2020 22:25
@amp-owners-bot
Copy link

Hey @alanorozco! These files were changed:

extensions/amp-viqeo-player/0.1/amp-viqeo-player.js

@samouri samouri removed the request for review from nainar December 28, 2020 22:25
@samouri samouri self-assigned this Dec 28, 2020
@samouri samouri changed the title Mio Convert iframes to get initialIntersection async Dec 28, 2020
@samouri samouri changed the title Convert iframes to get initialIntersection async Convert ad iframes to get initialIntersection async Dec 30, 2020
@samouri samouri requested a review from dvoytenko December 30, 2020 21:58
@samouri samouri marked this pull request as ready for review December 30, 2020 21:58
@samouri
Copy link
Member Author

samouri commented Dec 30, 2020

I found one surprising attribute about IntersectionObserver intersectionRect while working on this PR. For an implicit-root (root:null) InOb observing an element in a subframe: all of the intersectionRect's have a width/height that equals "how much of the element is currently visible in the main viewport" whereas the positional properties (top/left/right/bottom) are all relative to the subdocument.

Most likely according to spec, but I'm having trouble figuring out why that makes sense.

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.

This is awesome! But one question. PTAL.

3p/3d-gltf/viewer.js Show resolved Hide resolved
extensions/amp-a4a/0.1/amp-a4a.js Outdated Show resolved Hide resolved
test/integration/test-amp-ad-3p.js Outdated Show resolved Hide resolved
test/integration/test-amp-ad-3p.js Outdated Show resolved Hide resolved
@samouri
Copy link
Member Author

samouri commented Jan 8, 2021

In order to merge the helper without blocking on the ads changes, I've split it into its own PR (#31858)

@lannka
Copy link
Contributor

lannka commented Jan 11, 2021

Breaking change: rootBounds and intersectionRatio are now according to spec as opposed to the definition we had been using. That means width/height is relative to viewport instead of the document's viewport.

@samouri could you further elaborate on the change? shouldn't width/height be absolute values?

@samouri
Copy link
Member Author

samouri commented Jan 11, 2021

Breaking change: rootBounds and intersectionRatio are now according to spec as opposed to the definition we had been using. That means width/height is relative to viewport instead of the document's viewport.

@samouri could you further elaborate on the change? shouldn't width/height be absolute values?

I believe that both the rootBounds and intersectionRatio will not have an affect on any AMP Viewer that takes up 100% of the browser viewport (which SRP Viewer does). In any other situation, they would behave differently than current implementation. Here are the differences:

Current rootBounds: the height/width of the document
New rootBounds: the height/width of the viewport

Current intersectionRect: the height/width of intersection rectangle between the observed element and the document's viewport (i.e. is it visible within the iframe).
New intersectionRect: the height/width of the intersection rectangle between the observed element and the viewport. (even if it is visible in the iframe, maybe the iframe is offscreen and will therefore be 0/0)

@lannka
Copy link
Contributor

lannka commented Jan 11, 2021

Thansk @samouri . That sounds like not a problem to me for those ads.

Another thing:

export function intersectionEntryToJson(entry) {
return {
time: entry.time,
rootBounds: layoutRectFromDomRect(entry.rootBounds),
boundingClientRect: layoutRectFromDomRect(entry.boundingClientRect),
intersectionRect: layoutRectFromDomRect(entry.intersectionRect),
intersectionRatio: entry.intersectionRatio,
};
}

We are normalizing the inob entry data object using layoutRectFromDomRect . Did we have that in consideration in the new code?

@samouri
Copy link
Member Author

samouri commented Jan 11, 2021

We are normalizing the inob entry data object using layoutRectFromDomRect . Did we have that in consideration in the new code?

Unless I'm missing something, that is the new code :). Previously we didn't need to do anything special since the entries were calculated inside of JS. Now are are using real InObEntry objects which are not serializable, and so we need to convert them here to be plain object (and therefore eligible for postMessage)

@lannka
Copy link
Contributor

lannka commented Jan 11, 2021

oh, my bad. then it looks great

Copy link
Contributor

@lannka lannka left a comment

Choose a reason for hiding this comment

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

oh wait a second. just saw this PR also touches amp-a4a.
would this change introduce latency to the rendering of an ad?

if it does, to avoid debugging an ads metric regression while promoting RC to prod, we'd better to run an explicit experiment for this change.

@samouri
Copy link
Member Author

samouri commented Jan 11, 2021

would this change introduce latency to the rendering of an ad?

I'd expect it to create an ~10ms async delay. Likely unnoticeable in most circumstances (e.g. the resources system already often forces ~2s deprioritization on ads, which would be the rate-limiting factor)

@lannka
Copy link
Contributor

lannka commented Jan 12, 2021

For changes that might affect ads performance, we need to run experiment to measure the impact before launch it.
Eventually, we might be fine to launch it as is but just need to be aware of the stats change.
In the past, we had many times seeing regressions on our Beta channel and have to bisect PRs to find which was the cause.

@calebcordry could you give some guidance for setting up such an experiment?

@samouri
Copy link
Member Author

samouri commented Jan 12, 2021

@lannka: do you only want the experiment for a4a, or also for name-frame-renderer + amp-ad?

@calebcordry
Copy link
Member

Agree with @lannka. I would recommend wrapping the a4a/nameframe/safeframe/iframeGet all in an isExperimentOn('exp-name)` block for this PR and then I can help you with a follow up PR to divert/report. Unfortunately we don't have ads metrics for 3p impl, but it still might be good to run as exp in canary first.

@samouri
Copy link
Member Author

samouri commented Jan 13, 2021

Agree with @lannka. I would recommend wrapping the a4a/nameframe/safeframe/iframeGet all in an isExperimentOn('exp-name)` block for this PR and then I can help you with a follow up PR to divert/report. Unfortunately we don't have ads metrics for 3p impl, but it still might be good to run as exp in canary first.

done! PTAL

@samouri samouri requested a review from lannka January 14, 2021 18:11
@samouri
Copy link
Member Author

samouri commented Jan 14, 2021

Just performed a sanity check and gltf viewer still behaves as expected + ad context still contains intialIntersection.
@ampproject/wg-performance: can I get a bundle-size approval?

@samouri samouri merged commit 75abc6b into ampproject:master Jan 14, 2021
@samouri samouri deleted the mio branch January 14, 2021 21:05
PetrBlaha pushed a commit to PetrBlaha/amphtml that referenced this pull request Jan 28, 2021
* getContextMetadata --> Promise

* ad iframes gather initialIntersection async

* use experiments

* remove log / fix test

* revert test change now that under expeirment.

* fix test-amp-ad-custom

* caleb updates

* toggle intersection needs win
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants