Skip to content

Commit

Permalink
intersect-resources: Fix incorrect pre-layout assumption (#27684)
Browse files Browse the repository at this point in the history
* Fix incorrect pre-layout assumption.

* Fix types.

* Add unit tests.

* Clean up test-resources.js a bit.

* Remove obsolete experiment.

* Last bit of cleanup.

* Fix lint.

* Make test a bit more readable.
  • Loading branch information
William Chou committed Apr 13, 2020
1 parent 3c826d6 commit c21d89a
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 136 deletions.
11 changes: 7 additions & 4 deletions src/service/resource.js
Expand Up @@ -673,13 +673,16 @@ export class Resource {
/**
* Whether the resource is displayed, i.e. if it has non-zero width and
* height.
* @param {!ClientRect=} opt_premeasuredRect If provided, use this
* premeasured ClientRect instead of using the cached layout box.
* @param {boolean} usePremeasuredRect If true and a premeasured rect is
* available, use it. Otherwise, use the cached layout box.
* @return {boolean}
*/
isDisplayed(opt_premeasuredRect) {
isDisplayed(usePremeasuredRect = false) {
devAssert(!usePremeasuredRect || !this.intersect_);
const isFluid = this.element.getLayout() == Layout.FLUID;
const box = opt_premeasuredRect || this.getLayoutBox();
const box = usePremeasuredRect
? devAssert(this.premeasuredRect_)
: this.getLayoutBox();
const hasNonZeroSize = box.height > 0 && box.width > 0;
return (
(isFluid || hasNonZeroSize) &&
Expand Down
27 changes: 20 additions & 7 deletions src/service/resources-impl.js
Expand Up @@ -1431,14 +1431,28 @@ export class ResourcesImpl {
const reschedule = this.reschedule_.bind(this, task);
executing.promise.then(reschedule, reschedule);
} else {
// With IntersectionObserver, the element's client rect measurement
// is recent so immediate remeasuring shouldn't be necessary.
if (!this.intersectionObserver_) {
task.resource.measure();
const {resource} = task;

let stillDisplayed = true;
if (this.intersectionObserver_) {
// With IntersectionObserver, peek at the premeasured rect to see
// if the resource is still displayed (has a non-zero size).
// The premeasured rect is most analogous to an immediate measure.
if (resource.hasBeenPremeasured()) {
stillDisplayed = resource.isDisplayed(
/* usePremeasuredRect */ true
);
}
} else {
// Remeasure can only update isDisplayed(), not in-viewport state.
resource.measure();
}
// Check if the element has exited the viewport or the page has changed
// visibility since the layout was scheduled.
if (this.isLayoutAllowed_(task.resource, task.forceOutsideViewport)) {
if (
stillDisplayed &&
this.isLayoutAllowed_(resource, task.forceOutsideViewport)
) {
task.promise = task.callback();
task.startTime = now;
dev().fine(TAG_, 'exec:', task.id, 'at', task.startTime);
Expand All @@ -1450,9 +1464,8 @@ export class ResourcesImpl {
)
.catch(/** @type {function (*)} */ (reportError));
} else {
devAssert(!this.intersectionObserver_);
dev().fine(TAG_, 'cancelled', task.id);
task.resource.layoutCanceled();
resource.layoutCanceled();
}
}

Expand Down

0 comments on commit c21d89a

Please sign in to comment.