Skip to content

Use resizeobserver when available #213

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

Merged
merged 7 commits into from
Mar 1, 2018
Merged

Use resizeobserver when available #213

merged 7 commits into from
Mar 1, 2018

Conversation

movedoa
Copy link
Contributor

@movedoa movedoa commented Feb 6, 2018

This fixes #210 and #184 by using resizeobserver when available (afaik only chrome 64+ supports this at the moment)

The native resizeobserver is way faster than the current implementation.
This pr is based on #212

@marcj
Copy link
Owner

marcj commented Mar 1, 2018

Cool, can you pls remove that tabs?

@movedoa
Copy link
Contributor Author

movedoa commented Mar 1, 2018

Done

};
var reset = function() {
// Check if element is hidden
if (initialHiddenCheck){
Copy link
Owner

Choose a reason for hiding this comment

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

missing space ) {

return;
}
// Stop checking
else{
Copy link
Owner

Choose a reason for hiding this comment

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

} else { please

var initialHiddenCheck = true, resetRAF_id;


var resetExpandShrink_ = function () {
Copy link
Owner

Choose a reason for hiding this comment

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

Please remove underscore.

if (invisible) {
element.style.display = saveDisplay;
};
var reset = function() {
Copy link
Owner

Choose a reason for hiding this comment

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

newline before pls

{
width: lastWidth,
height: lastHeight
});
Copy link
Owner

Choose a reason for hiding this comment

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

element.resizedAttached.call(size) should be enough, no?

requestAnimationFrame(reset);
}

if (typeof ResizeObserver != "undefined") {
Copy link
Owner

Choose a reason for hiding this comment

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

!==

width: elem.contentRect.width,
height: elem.contentRect.height
}
);
Copy link
Owner

@marcj marcj Mar 1, 2018

Choose a reason for hiding this comment

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

how about callback.call(this, elem.contentRect)?
Don't know the definition of contentRect tho.

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 construct my own object because contentRect has more properties (like top,left,...)
So to avoid errors and keep it in line with the current implementation, I just pass these two

Copy link
Owner

Choose a reason for hiding this comment

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

Alright!

@marcj
Copy link
Owner

marcj commented Mar 1, 2018

Just saw that you included the commit of #208, that should really not be part of this PR.

Copy link
Owner

@marcj marcj left a comment

Choose a reason for hiding this comment

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

Please adjust requested changed and remove unrelated changes of #208. You can ignore the comments from the code of #208.

@movedoa
Copy link
Contributor Author

movedoa commented Mar 1, 2018

The problem is that this includes #212 which needs #208 to work, so i am not shure what to do now
I can change this pr to be standalone but I can't do the same for #212

@marcj
Copy link
Owner

marcj commented Mar 1, 2018

Alright, then lets keep it simple and keep it. We close then both other PRs when this is merged. Please adjust then the requested changes that were coming in from the other PRs. :)

@movedoa
Copy link
Contributor Author

movedoa commented Mar 1, 2018

I hope i got everything ;-)

// Check in next frame
if (!resetRAF_id){
resetRAF_id = requestAnimationFrame(function(){
resetRAF_id = 0;
Copy link
Owner

Choose a reason for hiding this comment

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

that variable name is not so great, but I'll adjust it in master directly after merge.

Copy link
Owner

@marcj marcj Mar 1, 2018

Choose a reason for hiding this comment

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

I also would like to throttle the calls, so maybe only every 100th requestAnimationFrame call do something, because I guess reading scrollTop and scrollLeft can be expensive. will adjust afterwards

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 agree, didn't think about that

Copy link
Contributor

Choose a reason for hiding this comment

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

@marcj you might want to consider that throttling to that level (1 every 100 animationFrame) will be to slow to detect the resizing.
1 frame is around 1/60th of a second, so that makes it's around 1 check every 1,6 sec.

Use cases for this Initial detection are mostly for cases where something takes time to load, so it's hidden for 1 or 2 seconds at most.
But it's important to correctly detect when it's visible. (That is, at least, my own use case, where it's important to not miss the timing).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

1 check every 10th frame or so would be a good middle ground
every frame is to much 1/100 is not enough

Copy link
Owner

@marcj marcj Mar 1, 2018

Choose a reason for hiding this comment

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

Not always. When I use stuff in Angular for example, I have plenty of objects in the DOM but not visible (display: none). If there's a resize-sensor attached it will check for each element for its scrollTop/scrollLeft option every 1/100 second, so if I have some elements like that then the CPU will be molten, I guess.

Copy link
Owner

Choose a reason for hiding this comment

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

I meant by since scrollTop/scrollTop === 0 is valid use-case, right, that when I have a initial hidden element lying at 0,0 (position: absolute; left: 0; top: 0), then scrollTop will always return 0, right? So it will never be detected as "it's now visible". Is my assumption wrong?

Copy link
Contributor

Choose a reason for hiding this comment

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

well, HTML resize notification, while not native, should not be used extensively, and with great care.

In my case, I prefer exact performance instead of delayed detection. Maybe you can manage that with a configuration object ?

Copy link
Owner

Choose a reason for hiding this comment

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

yeah if we don't find a good balanced value, we should go with a configuration option.

Copy link
Contributor

Choose a reason for hiding this comment

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

about 2nd comment:
I think not, because the scrollTop will detect scrolling area positioning, not the element absolute positioning.
And this very property is being set to 10000 by the reset() function.

Here I'm exploiting a "bug" in how the browser manage the scroll properties: when an element is not visible, you can't set its scrollTop propertie: it will be immediately reset to 0.

So taking advantage of this and as it's on "our" detection HTML element, this will correctly detect when the element will become visible, without much cpu cost.

@marcj
Copy link
Owner

marcj commented Mar 1, 2018

Looks very good, thank you very much! : )

@rayshan
Copy link

rayshan commented Apr 5, 2018

Thanks all, this is huge! Can we cut a new release with ResizeObserver?

marcj added a commit that referenced this pull request Oct 16, 2018
due to incompatibility with dom elements detection
@marcj
Copy link
Owner

marcj commented Oct 16, 2018

This has been reverted in 45334e9 due to errors

@teuf22
Copy link

teuf22 commented Oct 16, 2018

Just curious: what kind of errors ? I had been using this patch with no problems so far. Thank you!

@marcj
Copy link
Owner

marcj commented Oct 16, 2018

This line broke since the ResizeObserver does not inject a new HTML element as property called resizeSensor to element,

var sensorStyles = window.getComputedStyle(element.resizeSensor, null);

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.

ResizeObserver in Chrome 64
5 participants