asscroll icon indicating copy to clipboard operation
asscroll copied to clipboard

Question about memory usage

Open SiddharthSham opened this issue 3 years ago • 5 comments

What would be the memory impact on the GPU when applying a 3d transform to the entire scrollable DOM element? Would it be significantly better to transform only sections of the DOM? (For instance, that is how Locomotive Scroll works.)

In my rudimentary tests, the memory consumption was greatly reduced by transforming only the required sections, and removing transforms as soon as possible. Is this something already documented/tested?

I'd love to know more.

SiddharthSham avatar Nov 16 '20 06:11 SiddharthSham

Hi @SiddharthSham, transforming individual sections has been something I've wanted to experiment with for some time. However my brief tests have shown that using the CSS property contain: content on the parent element of the transformed element increases performance. This of course only works when the parent element is no bigger than the size of the viewport, since it essentially tells the browser not to worry about calculating layout and paint regions outside of that element. (Unfortunately this CSS property isn't available on Safari currently but desktop usage isn't high at all, and the default on mobile is to disable the transformed element anyway)

This is what ASScroll uses. I've done some tests comparing this setup to a setup without it and saw some good performance increases. As well as testing it against a fairly basic setup that transforms sections separately which showed very similar performance between the two. So I've currently opted for the contain setup since it is usually much easier to deal with a single transformed element rather than multiple. I've also seen issues with Locomotive Scroll (and others) where the sections end up sitting at the top and bottom of the viewport due to miscalculations from things like resizing the window. Which this route avoids.

I do want to test this further, but if you wanted to run your own tests and provide your results I'd be very interested to see them.

ashthornton avatar Nov 17 '20 13:11 ashthornton

Hey @ashthornton, thanks for the detailed reply! I hadn't thought about using contain: content in order to improve performance; will definitely look into it more.

My concerns are more about the GPU memory usage. I tested two setups - one which works like ASScroll, (similar to this), and another where I transformed only the elements that had to be in viewport, and removed the transforms when not required.

What I noticed is that in the case of preserving the full scroll height, the GPU memory usage was directly proportional to the height of the page. (For a simple page about 2000vh tall, DevTools layers panel reported using ~300MB). Comparing this to the other setup, the memory usage was about 8-10MB max, which is a considerable improvement.

I'm not sure how to profile this properly, though. Is there something you would suggest?

SiddharthSham avatar Nov 17 '20 14:11 SiddharthSham

I'm interested in this too, in my own tests it was also appearent that the approach @SiddharthSham mentioned was quite a lot more performant.

iamlinkus avatar Oct 07 '21 10:10 iamlinkus

Only transforming the element(s) that are in the viewport is something that is on the roadmap. I experimented with using IntersectionObserver for this in order to keep the detection off the main thread and came up with some good results. I just need to find the time to fully test this and implement it.

ashthornton avatar Oct 07 '21 10:10 ashthornton

@ashthornton I'm very curious to see your implementation using IntersectionObserver - I attempted something similar and had a lot of bugs when the page was under load (IntersectionObserver didn't fire the callbacks in time). I finally had to scrap that approach in favor of running the logic on the main thread.

SiddharthSham avatar Oct 09 '21 05:10 SiddharthSham