← All builds

Dead Stick Baits

Two videos, a film that plays as you scroll, a nine-bait carousel and a wholesale form. One page, 11 requests, 99 on a phone.

What it does now

PageSpeedmobile
99
PageSpeeddesktop
100
Largest paintmobile, slow 4G
2.0 s
Page weighton first load
185 KB
Requestson first load
11
Videosplaying on it
2
Google's own report, on a Moto G Power over slow 4G, not my screenshot of a speed test I chose. First paint 1.7 s, largest paint 2.0 s, speed index 1.7 s, no blocking time, nothing shifting.

The brief

A bait brand with strong product photography and a site that buried it: a slow, heavy page that took eleven seconds to become useful on a phone.

What I built

  • A scroll-film hero where the film is the page, rebuilt by hand rather than with a page builder
  • 612 requests and 10.7 MB cut to 11 requests and 185 KB on first load, with the film kept in the hero
  • A real poster image as the largest element, so the page is readable before any video loads
  • Two videos, scroll-synced animation, a sticky nav and a wholesale form that posts without a third-party embed, and it still scores 99 on a phone

What a customer walks into

  1. The end of the Dead Stick Baits scroll film, where the bait settles
    Then they scroll, and the film keeps playing. One continuous shot, no stop, no second page to load.
    • Seedance 2.0 generated the film in Mode B: one continuous take. Say that out loud or it invents camera cuts.
    • On a desktop the film is one video encoded twice: WebM/VP9 at 4.7 MB for Chrome, Edge and Firefox, H.264 at 5.5 MB as the fallback. Phones get a 9:16 cut at 3.8 MB.
    • Both at GOP 8, so scrubbing to any point in the film decodes at most eight frames.
    • Scroll position drives the playhead. Nothing autoplays, nothing buffers ahead of where you are.
    • A real WebP poster (33 KB, 14 KB on a phone) is the element the browser measures, so the headline reads before a single film byte loads.
    • On a phone the film does not download until you scroll or tap. Nobody who bounces pays for 3.8 MB they never watched.
    • Claude Code wrote the scrubber by hand. The version it replaced scrubbed 612 JPEG frames, one request each.
  2. The Dead Stick Baits lineup carousel, showing the Savage Craw in Junebug The same lineup carousel on a phone
    Nine baits, one carousel. Shape, color, size and pack count without ever leaving the page.
    • Every bait is my own photography, poured and shot here. Nothing about the product is generated.
    • WebP at several widths, with loading="lazy" and decoding="async" on everything below the fold.
    • Shape, color, size and pack count sit on the card, so nobody opens a detail page just to compare two baits.
    • Nine baits in one carousel and the page never reloads: no variant round-trip, no second request.
  3. The Dead Stick Baits wholesale contact form
    A wholesale buyer lands in one form. No third-party embed, nothing extra to load.
    • Netlify Forms: data-netlify="true", a hidden form-name input and a bot-field honeypot.
    • No Typeform, no HubSpot, no iframe. The form costs the page zero extra requests.
    • Because it is part of the page, it inherits the site's own type and color instead of an embed's.
    • Live and capturing since September 9. Submissions land in the Netlify dashboard.
    • A wholesale buyer fills one form instead of hunting for an email address.

Want one that performs like this?

You tell me what the site has to do. I build it, you watch it get built, and you get the numbers on this page for your own business.

Get a quote

Usually a reply the same day.

How it was built, and what broke

How it was built

The received wisdom is that a video hero kills your ranking, so the film goes below the fold. That turned out to be wrong, and the fix was not moving the film. It was building it properly.

A real poster <img> is the element the browser measures, the copy is in HTML rather than painted into the canvas, and the whole thing is one video file instead of a folder of JPEG frames.

On a phone the film is not fetched at all until the visitor scrolls or taps. The page arrives in 185 KB over 11 requests; the 3.8 MB film is only spent on someone who stays to watch it.

What broke

The first version shipped 612 requests and 10.7 MB because the scroll was scrubbing a frame sequence: one image per frame, every one of them a separate request. It worked on a desktop with a fast connection and was unusable on a phone, which is where the traffic is.

Measuring on pagespeed.web.dev against the deployed URL, rather than trusting a local build, is what surfaced it.

The second thing was quieter. Every metric on the phone report was green except Speed Index, which sat at 4.2 s and held the score at 96. The cause was the film being fetched the moment the page loaded: 3.8 MB, about 95% of everything the page weighed. Waiting for a scroll took Speed Index to 1.7 s and the score to 99.

Finding that took one wrong turn worth recording. Lighthouse run from a laptop against a live CDN gave 4.47 s and 5.83 s for the same build minutes apart, and on the strength of that I said the change had done nothing. The swing between two runs was larger than the effect. Byte counts and request counts from that tool are solid; its timings, against the open internet, are not. Judge a shipped change with the same tool on both sides of it.