If you throttle the network in DevTools you can't always trust the metrics. @iamakulov.com explains why in his new article.
3perf.com/blog/chrome-...
Posts by Ivan Akulov
A few people around got recently confused by things being slow in DevTools but not in real life, so I explained why: 3perf.com/blog/chrome...
Doctor: Chrome DevTools throttling is real and can hurt you
Chrome DevTools throttling: [proceeds to not be real]
My Replay time-travel-based React+Redux perf reports experiments are coming together!
Just nailed sourcemapped component + selector identities, and I've got accurate timing details on dispatches + renders from a Replay DevTools E2E recording!
Early perf report example attached.
Something I worked on (with a few other wonderful folks) for the past few weeks :) www.framer.com/llm
the chart that I feel perhaps the proudest of is this
framerâs lcp (aka page loading time), across all sites, going lower and lower day by day, free for all framer customers
lots of work by our infra/canvas teams, @kurtextrem.de, and yours truly <3
(impressive how youâre monitoring ânext.jsâ and responding on every social network ever, i could never)
next.js (pages router) loads data for pages you navigate to, but never releases it, whoops: github.com/vercel/next...
ah yes itâs my favorite âiphone safari wraps every phone number with <a> â react has a hydration mismatch â it remounts the full dom â all images on the page flash, but only on iphoneâ type of day
Story behind the improvement:
Tomorrow, when you publish a Framer site, every pageâs HTML will get 10-20% smaller:
7) So now, when a site is published, it remains unoptimized only for seconds. Once bundling for top pages completes, every other page on the site starts using that bundle (+ modulepreloads, etc)!
Itâs still not as fast as optimized pages â not until the 1st visit â but itâs much faster than before.
5) 2 weeks ago, we looked at these pages and realized we can make them faster. We still canât optimize them â itâs too costly. But we can reuse something that other pages produce â for ~free.
6) Whatâs âsomethingâ? Itâs the bundle (plus a few other things, like <link rel="modulepreload">s etc.).
4) This made optimization much faster! But this also meant a very small % of visitors would hit pages that are not bundled and not SSR-ed.
3) In October, we rewrote our optimization stack â and made it so that on publish, only the most visited pages are optimized. Less popular ones would get lazily handled after the first visit. (H/t our Piotr Krawiec, who single-handedly did the whole rewrite: www.framer.com/updates/dyn...)
1) Framer sites are fully capable React apps
2) We used to SSR every page of every site on publish. As Framer grew, in 2025, this stopped scaling (a bundling + SSR + data injection pass, which we call âoptimizationâ, would take minutes on large sites)
Last week in Framer performance: the first view of unoptimized pages is now much faster, especially on large sites:
Responded! bsky.app/profile/did:...
And learned that this doesnât happen with every dep, only with some of them :D
(Is it a bad taste to quote-reply on bluesky btw? I havenât posted much in a while lol, mightâve missed the memo)
This doesnât happen with every package btw.
This happens with fast-deep-equal because itâs 1) written in CommonJS (so itâs not tree-shakable) and 2) doesnât have `sideEffects: false` (so the bundler cannot ignore the package if its imports arenât used).
But most packages have one of those :(
Whereas if Redux *wasnât* bundled, the bundler wonât even enter the file that imports fast-deep-equal. (This is thanks to `sideEffects: false` which Redux does.)
2) Make an index.js that imports and uses a completely different function:
import { compose } from "redux";
console.log(compose);
3) Bundle
4) Boom â fast-deep-equal is bundled, even though itâs not used
Yeah, Redux works great because it doesnât import anything!
Hereâs a case when this breaks:
1) Add a random dependency in Redux thatâs used in some random function:
- esm > cjs modules (bundlers still donât shake cjs well/at all)
- sideEffects: false ftw
- donât bundle a library into a single file for npm. kills shakeability
spent the day shaking the tree, shook 1.5 MB
just why
Using PerformanceObserver or manual timers/logs, I guess :D
Logging into the console while itâs closed still works
(But yup, somewhat annoying đ)
So turns out none of this was real
(which was pretty hard to tell because the only way to tell was to close DevTools lol)
Benchmark: codepen.io/iamakulov/pe.... Try with DevTools open vs closed â especially with call stack depth 1000.
(â1000 levels deepâ might seem like a lot, but itâs pretty realistic with Reactâs recursivelyTraversePassiveMountEffects. Thatâs how I ran into it â in TanStack Query!)
Welp, turns out itâs not real.
Just opening DevTools makes all timers 5-100Ă slower, due to the overhead of capturing stack traces. Even if you do nothing else (donât record performance, etc)!
Guess who accidentally spent a weekend optimizing this đ
(h/t @paul.irish for explaining why)