A client sent me a Lighthouse screenshot at 11pm on a Tuesday. Performance 99, green ring, the whole trophy cabinet. Their Search Console page experience report had been failing Core Web Vitals for six weeks straight.
Both screens were telling the truth.
That gap is the part most writing about Webflow site speed skips, because the advice stops at "compress your images" while the scoring model quietly decides the outcome. So this is the version I would want before promising a client a sub-one-second load on Webflow: which numbers count, and what order I work in when they do not.
What Actually Makes a Webflow Site Slow?

Webflow sites are slow because of what gets added to them, almost never because of what Webflow ships by default. Oversized hero images, a lazy-load default in the wrong place, and pasted third-party tags cover most cases.
The platform baseline is genuinely strong. AWS-backed CDN, minified output on publish, automatic responsive image variants, Brotli compression. Then someone drops a chat widget, a heatmap recorder, two ad pixels and a font from a fourth domain into site-wide custom code, and the baseline stops being the story.
The weighting is what makes this asymmetric. Lighthouse scores Total Blocking Time at 30% of the performance number, more than any other single metric, with Largest Contentful Paint and Cumulative Layout Shift at 25% each and First Contentful Paint and Speed Index at 10% each, according to Chrome's Lighthouse scoring documentation. Third-party JavaScript lands squarely on the heaviest-weighted metric on the board. Your image compression pass improves a 25% metric; the chat widget nobody audited is sitting on a 30% one.
Lighthouse 99 Is a Vanity Number

Google does not rank you on your Lighthouse score. It ranks on field data collected from real Chrome users, and those two things disagree constantly.
The Core Web Vitals thresholds are public and specific: LCP within 2.5 seconds, INP at or under 200 milliseconds, CLS at or under 0.1, evaluated at the 75th percentile of page loads, segmented across mobile and desktop. That percentile is the whole argument. Lighthouse runs one simulated load on one throttled profile in a data centre. The 75th percentile is your slowest quarter of real visitors, on real phones, on hotel wifi, with a background tab decoding video. web.dev states the position plainly: lab measurement is not a substitute for field measurement, and only field measurement captures the complete picture.
There is a second reason the number misleads, and it is baked into the scoring curve. Chrome's own documentation admits that taking a score from 99 to 100 needs roughly the same metric improvement as taking one from 90 to 94. The top of the range is compressed almost flat. Two sites can both report 99 while one renders its hero at 1.2 seconds and the other at 1.9, because top-performing sites render LCP in about 1,220ms and that value already maps to 99. A client chasing the last point is buying a rounding artefact.
Actually, let me soften that slightly. The score is a fine diagnostic. Open the audit list, read the opportunities, fix what it flags. What it cannot do is tell you whether your visitors in Bosnia on a mid-range Android are having a good time, and that is the number Google is grading.
Your Hero Image Is Lazy-Loaded by Default, and It Is Your LCP

Webflow sets every new image to loading="lazy" by default, which is correct for the whole page except the one element the LCP metric is measuring.
The platform shipped that default deliberately and it is the right call for a page of below-fold content. On the hero it is self-sabotage: the browser reaches the image, sees the lazy attribute, defers it, finishes layout, discovers the image is in the viewport after all, and only then goes to fetch it. You have added a full round trip to the exact element being timed.
The fix takes about forty seconds per page. Select the hero image, open Element Settings, change the load setting from Lazy to Eager. Then add a custom attribute of fetchpriority with value high so the request starts at high priority instead of being promoted after layout.
That second half is not a micro-optimisation. Google Flights ran exactly this change on their hero image and watched LCP fall from 2.6s to 1.9s. The same article documents the reverse move on the Oodle demo app, where marking offscreen carousel images fetchpriority="low" cut two seconds off page load by getting them out of the way of things that mattered.
| Image role | Webflow load setting | Extra attribute | Reasoning |
|---|---|---|---|
| Hero / LCP element | Eager | fetchpriority="high" | Starts at high priority instead of waiting for layout |
| Above-fold logo or nav mark | Eager | none | Small, needed immediately, not worth a priority fight |
| Below-fold section images | Lazy (default) | none | Correct use of the default |
| Offscreen slider or carousel frames | Lazy | fetchpriority="low" | Actively yields bandwidth to the LCP element |
| CSS background images | No setting exists | Preload with fetchpriority="high" | Background images cannot be lazy-loaded or given srcset |
That last row catches people. A background image has no loading attribute and no srcset, so if your hero is a div with a background rather than an image element, none of the platform's automatic work applies to it.
Where Webflow's Image Pipeline Silently Stops Working
Webflow generates responsive variants automatically, but only for images uploaded through the Designer or a CMS image field. Anything arriving another way ships at full size to every device.
Upload an image wider than 3200px through the Assets panel and Webflow builds seven variants: 3200, 2600, 2000, 1600, 1080, 800 and 500 pixels wide, wired up through srcset so a phone downloads the 500 and not the 3200. Uploads cap at 4MB. AVIF has been a supported upload format for a while now, and the Assets panel carries a bulk conversion tool that will re-encode existing JPEG and PNG assets in place.
Now the part that is not in any listicle. Images that arrive via CSV import or through the Data API do not get variants generated. Neither do CSS background images, because background-image has no mechanism to carry a srcset. If you populated a 400-item blog collection by importing a spreadsheet full of image URLs, every one of those images is being served at whatever size the original file happened to be, on every device, forever. The site will look fine in the Designer. It will fail on a phone.
The failure mode is easy to misdiagnose. Lighthouse reports "properly size images", so the obvious response is to open the Assets panel and start compressing, and nothing improves, because the offending files were never in the Assets panel. They arrived with the import and they still live at whatever URL the spreadsheet pointed at. Check it directly rather than trusting the audit: open a CMS image from the live page in a new tab and look at whether the URL carries a variant size in it.
The Font Tax
Self-hosted fonts served from Webflow's own CDN beat Google Fonts on a third domain, every time. One fewer DNS lookup and one fewer connection to negotiate before any text can paint. Upload the WOFF2, subset it to the weights you actually use, and delete the two weights the designer added and nobody ever applied.
How Do You Cut Webflow's Own JavaScript?
You mostly cannot, because Webflow ships jQuery on every published site and offers no dashboard switch to turn it off. Pretending otherwise is how these guides lose credibility.
There is an open wishlist request to add that switch, filed in March 2024, still sitting open with a handful of votes and a comment calling jQuery the biggest remaining performance blocker on that person's site. Two and a half years is a reasonable signal about roadmap priority.
So every gain has to come from your side of the line. Every script you paste in is a script you can defer, move to the footer, load on interaction, or delete. That is where the Total Blocking Time savings live, and it is unglamorous work: open the network panel, sort by transfer size, and justify each third-party domain out loud to whoever asked for it. Half of them will turn out to be from a campaign that ended in 2024.
What Order Should You Fix Things In?
Fix the LCP element first, third-party scripts second, and everything else after, because that ordering follows the metric weights rather than the audit list.
- Identify the actual LCP element. Chrome DevTools performance panel, reload, look at the LCP marker. It is usually the hero image and occasionally a heading in a webfont you have not preloaded. Guessing here wastes the rest of the work.
- Set that element to Eager and give it
fetchpriority="high". If it is a background image, add a preload tag in page-level custom code instead. - Audit third-party scripts. Anything that is not needed for first paint goes to footer custom code with
defer, or gets loaded on first interaction. Chat widgets are the usual worst offender. - Convert oversized assets to AVIF or WebP using the built-in conversion tool, and re-upload anything that entered via CSV so it picks up responsive variants.
- Self-host and subset fonts, then preload only the single face used above the fold.
- Re-measure in the field, not the lab. Chrome User Experience report data, or a real-user monitoring script, over at least 28 days.
Steps one through three account for most of the improvement on most sites I have looked at. Steps four through six are what separate a good score from a fast site.
Bandwidth Just Became a Speed Constraint
Webflow's May 2026 plan changes fold the old CMS and Business tiers into a single Premium plan, and the included bandwidth on that plan is half what Business carried.
The BRIX Templates breakdown of the change has the numbers: Premium at $25 per month billed yearly or $39 monthly, with 50GB of included bandwidth against the old Business plan's 100GB, and add-on bandwidth at $20 per month yearly for another 50GB. New purchases moved to the new plans on 13 May 2026, most existing sites transition from 29 June 2026, and Freelancer and Agency workspace sites follow from 16 November 2026.
Unoptimised images used to cost you a Lighthouse point. On the new plans they cost that plus a line item. A 2400px hero served to 40,000 mobile visitors is now a billing decision as much as a performance one, which is the first time I can remember Webflow's pricing model and its performance guidance pointing in exactly the same direction.
When Webflow Is the Wrong Answer
Sometimes the honest answer is that the platform is not the constraint and neither is the image pipeline. If your marketing site needs per-request personalisation, a heavy interactive product demo, or a component library shared with your app, you are fighting the tool rather than tuning it. I have laid out that fork in more detail in my comparison of WordPress against a custom website build, and if the decision is still open at the platform level, my rundown of the best CMS platforms for marketing sites covers where Webflow genuinely wins.
For most small business sites it does win, and the sensible move is to keep the visual builder and push the logic elsewhere. Pairing Webflow with Zapier handles a surprising amount of that without touching page weight, since the automation runs off-page entirely.
If you are earlier than that and still costing the project, what a website build actually costs sets realistic expectations before performance work is even on the table, and the practical advice for running a successful website build covers the process decisions that cause most of the damage. Performance is cheap when it is designed in and expensive when it is retrofitted.
Open your site in Chrome DevTools right now, reload with the performance panel recording, and find the LCP marker. Is it the element you expected? On roughly half the sites I check, it is not, and everything downstream of that assumption was aimed at the wrong image.
