Pinterest rebuilt its mobile web experience in 2017 and reported time to interactive falling from about 23 seconds to 5.6 seconds, with the core bundle cut from roughly 650 KB to 150 KB against an old experience shipping over 2.5 MB of JavaScript. What was actually wrong, what did the rebuild change, and where would copying it be a mistake?
Show the full answer Hide the answer
The situation they were in
A desktop-first product with a mobile web surface that existed mainly to convert visitors into app installs. The published case study describes an old experience shipping over 2.5 MB of JavaScript, roughly 1.5 MB of it in the main bundle. On a mid-range Android phone over a mobile network, that is not a slow page; it is a page that does not work.
The economics made it worse than it looked. Mobile web was the entry point for people arriving from search and social links - the audience with the least commitment and the least patience - so the slowest surface was serving the users most likely to leave.
What they changed
Three moves, in the order that matters:
- A budget expressed in bytes on the critical path, not a vague goal. The core bundle went to roughly 150 KB, with everything else lazily loaded. A number that a build step can enforce is a different artefact from an aspiration in a document.
- A rewrite of the mobile surface rather than an optimisation of the existing one. This is the uncomfortable part: 2.5 MB of JavaScript is not reachable by incremental trimming, because the weight is in architecture - what renders where, what state the client holds, what ships before first paint.
- Service workers for network resilience, so repeat visits stop paying the full transfer cost.
Pinterest reported the result as time to interactive falling from about 23 s to 5.6 s and first meaningful paint from about 4.2 s to 1.8 s, alongside business figures it attributed to the change: time spent up about 40%, core engagements up about 60%, user-generated ad revenue up about 44%.
Why it fitted their constraints
The value per visit was low and the volume was enormous. That combination is what makes a percentage improvement in bounce worth a rewrite. It also meant the surface could be scoped narrowly - browse, search, pin detail - so a three-month rebuild was plausible.
The business numbers are the part worth carrying, not the technical ones. A performance budget survives contact with a product roadmap only when someone has attached it to revenue. Budgets that exist purely as an engineering preference are the ones that are exceeded on every page six months later.
What it cost
A rewrite is a second codebase until the old one is retired, and for the duration both must be maintained. Aggressive lazy loading moves work later rather than removing it, so interactions after the first paint can be slower unless prefetching is done carefully. A service worker is a cache with its own invalidation and its own class of "users stuck on an old version" incidents.
Where copying it would be a mistake
- High value per visit, low volume. A B2B application where each user represents thousands in contract value has different arithmetic: a 2 s improvement changes nothing measurable, and the same engineering spent on a feature does.
- Authenticated, long-session products. Load cost is amortised over a session lasting an hour; the first-load budget is not the binding constraint, and interaction latency is.
- Reaching for a rewrite when the weight is not architectural. If the bundle is 400 KB with 200 KB of it one date library and one icon set, that is an afternoon of work, not a quarter.
- Copying the number. 150 KB was right for that surface in 2017. The defensible version is to derive the budget from your own users' devices and networks, not to inherit someone else's.
Common weak answers
- "They made it a progressive web app." The service worker was the smallest of the three changes. The budget and the architecture did the work.
- "Performance improves conversion." True in this case with these numbers; the interesting claim is when it does, which depends on value per visit, traffic source and session length.