Scroller memory repro

jantimon/repro-scroller-memory

A long list where every row is its own scroller kills the tab on iOS 18 and later. Around 200 rows is enough. The same phone on iOS 17 renders 5000

The pages below are the same 1000 flex rows of 10 full-width slides, no images and no libraries. They differ only in how the row is made scrollable

Scroll containers and memory

Five pages, the same 1000 rows of ten slides. They differ only in how the row is made scrollable

Filed as WebKit bug 322930

Scroll timelines and frame rate

A separate problem, on a page that survives. The inview page above is its control: same rows, same scroll containers, no timelines

Filed as WebKit bug 322931, alongside the earlier 322283 on shared timeline names

Experiments ran

In addition to the example cases above the following cases were also tested:

CSS on the rowWhat happens
overflow-x: auto ☠️ tab crashes at 250 rows
overflow-y: auto ☠️ tab crashes at 250 rows
overflow: auto ☠️ tab crashes at 250 rows
overflow-x: scroll ☠️ tab crashes at 250 rows
display: grid + overflow-x: auto ☠️ tab crashes at 250 rows
display: block + overflow-x: auto ☠️ tab crashes at 250 rows
overflow-x: auto, 100 slides per row ☠️ tab crashes at 250 rows
overflow-x: auto, 2 slides per row ✅ 5000 rows, no crash
overflow-x: auto, slides narrow enough to fit ✅ 5000 rows, no crash
overflow: hidden ✅ 5000 rows, no crash

One row

What every row on these pages is built from. Only the two marked declarations differ between the demos

HTML

<div class="tile"> <div class="scroller"> <div class="slide"><div class="box"></div></div> <!-- ...10 slides --> </div> </div>

CSS

.tile { padding: 8px 16px 24px; content-visibility: auto; /* content-visibility only */ contain-intrinsic-size: auto 400px; } .scroller { display: flex; gap: 16px; width: round(down, 100%, 1px); aspect-ratio: 1 / 1; overflow: hidden; overflow-x: auto; /* full + content-visibility */ } .slide { flex: 0 0 100%; display: flex; align-items: center; justify-content: center; } .box { width: 200px; height: 200px; }

Measured on BrowserStack

The experiments ran on a real BrowserStack test device. Each experiment ran 3 times to verify the results:

memorystatus: com.apple.WebKit.WebContent exceeded mem limit: ActiveSoft 1536 MB (non-fatal)
memorystatus: killing_highwater_process [com.apple.WebKit.WebContent] (highwater 100 17s) 8579568KB

Devices: iPhone SE 2022, 12 Pro, 13, 14, 15, 15 Pro Max, 17 Pro. OS versions: iOS 15, 16, 17, 18, 26, 27 Beta