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

An experiment to substitute onMeasureChanged with ResizeObserver #31554

Closed
wants to merge 2 commits into from

Conversation

dvoytenko
Copy link
Contributor

Partial for #31540

TODO:

  • Tests

@dvoytenko dvoytenko requested a review from samouri December 11, 2020 00:53
@lgtm-com
Copy link

lgtm-com bot commented Dec 11, 2020

This pull request introduces 1 alert when merging a7d8741 into 35d3569 - view on LGTM.com

new alerts:

  • 1 for Invocation of non-function

processEntries_(entries) {
for (let i = entries.length - 1; i >= 0; i--) {
const {target, clientRect} = entries[i];
let seenTarget = false;
Copy link
Member

@samouri samouri Dec 11, 2020

Choose a reason for hiding this comment

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

seenTarget is to ensure it only gives the latest size? are you confident about the ordering of the array? (newest first)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The ordering is per spect. But the newest are last. That's why I'm going through array in the reverse order.

const size = {width, height};
this.lastSizes_.set(target, size);
for (let k = 0; k < callbacks.length; k++) {
callCallbackNoInline(callbacks[k], size);
Copy link
Member

Choose a reason for hiding this comment

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

nit: this is cleaner imo if you pass in the whole thunk. E.g.

callNoInline(() => callbacks[k](size))

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was trying to reduce number of function allocations.

if (!pushIfNotExist(callbacks, callback)) {
return;
}
const lastSize = this.lastSizes_.get(element);
Copy link
Member

@samouri samouri Dec 11, 2020

Choose a reason for hiding this comment

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

Can we ensure the lastSize logic only occurs in the case of an element with a non-empty callbacks array?
I want to protect from a very stale value being used and then quickly corrected after observation.

E.g.:

  1. Observe el1. After some time, unobserve el1
  2. While not observed, size changes happen to el1
  3. Observe el1 again. The stale lastSize is used initially.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I clean out the lastSize after the unobserve call, thus there shouldn't be stale values here.

* Pools resize observers. Eventually the hope is that the call sites can
* instantiate their own resize observers. But currently there are some
* performance issues and pooling is desired. For more info, see
* https://bugs.chromium.org/p/chromium/issues/detail?id=1157544
Copy link
Member

Choose a reason for hiding this comment

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

Thanks for linking this bug! Very interesting results with a significant impact on how to structure our ResOb code.

@samouri
Copy link
Member

samouri commented Dec 11, 2020

Shouldn't we merge the ResizeObserver polyfill before making the changes in extensions? Its fine to create the new helper service behind a server-side flag though

@dvoytenko
Copy link
Contributor Author

Shouldn't we merge the ResizeObserver polyfill before making the changes in extensions? Its fine to create the new helper service behind a server-side flag though

I added the build flag just for this reason. Polyfill itself is pretty easy and we can do it as early as we want. But the polyfill suffers from the similar issues that we've previously fixed for IntersectionObserver - namely working across the boundary of a shadow root and a same-origin iframe boundary.

@dvoytenko
Copy link
Contributor Author

Closed in favor of #31899

@dvoytenko dvoytenko closed this Jan 12, 2021
@dvoytenko dvoytenko deleted the run3/on-measure branch January 12, 2021 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants