alexfoxy/lax.js

Performance issues and crashes on iOS

derwaldgeist opened this issue · 16 comments

Hi, we created a video-heavy site based on lax.js:

https://marblever.se/v2

It works perfectly on Chrome. But if I try it out on Safari iOS, the page tends to reset itself after a bit of scrolling, and eventually causes Safari to crash. This is on a pretty powerful device, an iPhone 12 Pro Max. I downsized the videos quite a bit to prevent this and even experimented with lazy-starting the videos. But nothing helped so far.

Any idea what I can to do performance-optimize the behavior on iOS?

Hey, do you have the source or an excerpt available anywhere? It would also be interesting to see the source files you’re using for the videos. I have an iPhone 13 pro and it does struggle pretty badly on both browsers. You have a lot of videos going which I imagine is overloading the GPU.

Thanks for the fast response! Do you have a Gitlab account, so I could give you access to the repo? The videos are transparent videos (HEVC for Safari and WebM for Chrome). They are converted from a H.265 transparent video via the Rotato app.

If I display the page without videos, it kinda works. Still a bit glitchy, but at least it won't crash. So it is definitely the combination of a lot of videos and controlled scrolling. I also tried deferred video loading. But this will cause too many delays, so the page does not show up correctly.

Hence, I tried to stop the videos after autoplaying them and to restart them once they are visible. My first approach was even more complex, I did not autoplay them but started them manually and immediately stopped them, so at least a couple of frames got preloaded. But neither approach worked.

Videos are tricky! My gitlab id is 12040941.

Videos are tricky! My gitlab id is 12040941.

Can't find you with that ID. It requires a username.

Just a quick update: I made an optimized version where I replaced most of the videos with a static PNG. But still Safari on iOS crashes after a couple of pages. The strange thing is: If this is the case, some of the images won't be displayed anymore, since lax.js does not restore the scrolling positions after reload.

You can find the optimized version here: https://marblever.se/v2

And as soon I have your gitlab user name, I can add you to the repo.

BTW: We have another landing page built with the very same approach, but less scrolling pages: https://marblever.se/nfts This one works as expected, with no issues, even if I enable all the videos. It seems as if the longer page https://marblever.se/v2 causes a crash at some scroll position and then the whole browser tab crashes (only on iOS).

Sorry, my user name is alexfoxy.

Sorry for the delay, I just invited you to the repo.

The full page can be accessed via https://localhost:3000/v2

It works perfectly on Google Chrome, but crashes my iOS devices.

I dug deeper into this issue and found quite a number of issues on Stackoverflow that suggested that Safari most of the time crashes due to memory issues. This especially happens if you have a lot of large elements on the page, which is the case in my page. Alll vertical scrolled elements are positioned outside of the viewport, on top of each other, but I guess even this matters.

The best solution I saw so far was to disable elements via display:none until they become visible. This would require lax.js to support a switch of the display state, which I think is currently not possible.

Did you have a chance to look at this?

Hey, just wanted to bump this, since we still have troubles on iOS. Do you still maintain this library?

Sorry it’s very difficult with my full time job. I think the issue like you said is memory. You could achieve the display css using the on update function I think => https://github.com/alexfoxy/lax.js#onupdate-drivervalues-object-domelement-domelement--void

The onUpdated() approach kind of works. But I ran into another problem now: Because the pages are shown on demand, the elHeight and elWidth properties don't reliable anymore, especially on Safari, iOS, Firefox (and on some pages even Chrome). They report false values (0) instead of the correct element sizes.

I noticed that things are ok if I wiggle the window size a bit, forcing the browser to recalculate everything.

Is there a way to trigger lax's rendering / element size calculation programmatically?

(Note that I only need these elWidth / elHeight paramters because of #173)

I was finally able to workround this, with an additional wrapper div that set an explicit aspect-ratio and using this div as an animation target instead.

Here's the first version that actually runs on iOS: https://marblever.se/v2

Still, the onUpdated() solution seems a bit quirky to me, as

  1. it causes a lot of additional function calls per frame
  2. I can't use lax's special values like screenHeight and have to mimic them in my own code

It would be much better if laxjs itself had a way to toggle the display property directly via the timeline.