Case study · W-02 · Website · Tracking
A portfolio site that loads in 2.3 seconds on a slow phone.
How this site was built in Astro to load in about 2.3 seconds on a throttled phone connection, with animation, under 65 KB of JavaScript and no layout shift.
- Lighthouse performance (mobile)
- 97–98
- Largest Contentful Paint
- 2.3 s
- Layout shift (CLS)
- 0.007
- JavaScript
- 60–65 KB
Write-up
01 · The brief
A website for someone who sells websites is the sample. It had to say in five seconds what I do, show real work, and make one action obvious: book a free 15-minute review. It also had to be fast on the phones and connections most visitors actually use, because that is the promise I make to clients.
The design called for motion: an opening sequence, page transitions, text that reveals as you scroll. Motion is usually where speed goes to die, so the rule was simple: nothing animates until the content is already on screen, and nothing animates that would move the layout.
02 · What I built
The site is hand-written in Astro, which sends plain HTML and only loads JavaScript where something moves. The animation library (GSAP) and smooth scrolling (Lenis) load after the page is visible, and only on pages that use them. People who set “reduce motion” on their device get no movement at all.
Each page’s critical CSS is inlined into the HTML, so nothing blocks the first paint. The two fonts the first screen needs are preloaded. Images are served as AVIF or WebP at the size the screen needs, with their dimensions set so nothing jumps when they arrive.
Analytics load only after the first tap or scroll, so they never count against first-load speed.
03 · What the numbers said
Lighthouse in mobile mode simulates a slow 4G connection and a CPU four times slower than a laptop. Across eight pages, the median of three runs each:
- Performance score 97–98
- Largest Contentful Paint 2.3–2.4 s (Google’s “good” threshold is 2.5 s)
- Cumulative Layout Shift under 0.01 (threshold 0.1)
- 60–65 KB of JavaScript on the home page, including all the animation
The slowest tap or click took about 60 ms even with the CPU slowed four times; Google’s threshold for “good” responsiveness is 200 ms.
04 · What changed along the way
The first version hid the headline until the animation started, which cost about a second of LCP. The headline now paints immediately and only slides in when the script arrives early enough to do it without a flash. The remaining limit is the fonts: five font files of about 22 KB each.
05 · What it means for your site
Most of what made this fast is not special: one clear job per page, images sized properly, scripts that wait their turn. The same checks are part of every site I build, and part of the free review if you already have one.