When I added the live previews to this portfolio, scrolling started to feel wrong. On a phone the page seemed to catch on each project, then stutter for a moment. I did not want to guess at the cause, so I measured it.
How I measured
I used a script that drives a real browser in phone mode with the processor slowed to a quarter of normal speed, so problems show up clearly. It scrolls the page with a steady stream of wheel input, records how long every frame takes, watches for slow script tasks, and notes any moment where the page stops moving. I could not make the headless browser send true touch swipes, so I used wheel input in phone mode, which is what a trackpad or a mouse in a browser’s device emulation sends.
What I found
Two things were going wrong at once.
- The previews swallowed the scroll. Each preview was an embedded copy of a real page, and it grabbed the wheel so you could scroll inside it. If your pointer was over a preview, the page stopped until you had scrolled all the way through the preview. In 21 of 35 samples the page did not move at all.
- Too many pages ran at once. The home page was loading seven live websites inside itself. Their own start-up work landed in the middle of scrolling and caused dropped frames.
What I changed
- A preview no longer touches the wheel until you click it. Pressing Escape or moving away lets go.
- On phones there are no embedded pages at all. Each preview is a still image with an Explore button that opens a full-screen view you can scroll with your thumb.
- On larger screens a preview only loads when it is near the screen, loads one at a time, and waits until scrolling pauses. When it is far away it unloads again.
- Scroll-triggered animations are off on phones, and the hero photo went from 324 KB to 45 KB.
The numbers
| Measure (4x slower processor) | Before | After |
|---|---|---|
| Samples where the page was stuck (phone mode) | 21 of 35 | 0 |
| Worst dropped frame, desktop | 300 ms | 33 ms |
| Frames slower than 50 ms, desktop | 15 | 0 |
| Slow script tasks, desktop | 8 | 0 |
The page was also about 3,000 pixels taller by then, with three more projects on it, and still scrolled from top to bottom in roughly a quarter of the time.
A test that lied to me
While checking my work I wrote a test to confirm every preview image loaded. It passed even when an image was missing, because it returned the list of broken files as text and my pass-or-fail logic treated any text as a pass. A link checker caught the missing file. I fixed the test, confirmed that it now failed on the broken image, and then fixed the image. Verifying the checker is part of the job.
What I have not tested
I have not tried this on a physical phone or in Safari. Measuring in an emulated browser told me what to fix, but it is not the same as the real device in your hand. Those are the next things to check.
The result is what you are scrolling through now. For more on how I work, see what AI-assisted development looks like in practice.