Brotli compression is on: why is PageSpeed / LCP still slow?

Brotli compression is on: why is PageSpeed / LCP still slow?

BackerLeader ●5 ●33 ●268
calendar_today ago • schedule6 min read
— Originally published at devlog.apogeewatcher.com

A green compression toggle is not an LCP fix. Confirm Content-Encoding on the critical path, then check the LCP element and Time to First Byte that still dominate the lab run.

The CDN panel shows Brotli enabled and the host checklist ticks compression, yet PageSpeed Insights on the homepage or checkout URL still shows a slow Largest Contentful Paint, or the Performance score barely moves after the change. Those two facts can both be true. Brotli compression shrinks text on the wire; it does not change the LCP element, a slow origin response, or a lab path that never negotiated br on the files that matter.

How to turn compression on without breaking scores is already covered on our blog in Brotli and Gzip Compression: Shrink Text Assets Without Breaking PageSpeed Scores. Caching and reuse sit beside that work in Cache-Control Headers for Web Performance. What follows here is the triage we run when the toggle is already green and the lab result is still poor: confirm encoding on the critical path, then address the bottlenecks compression was never going to fix.

Confirm Brotli is actually on the critical path

A dashboard labelled “Brotli” often means the edge can compress. Lighthouse and PageSpeed Insights care whether the HTML document and the render-blocking CSS and JavaScript on that URL arrived with Content-Encoding: br or gzip. Those are different claims. Open the Network panel (or curl -sI with Accept-Encoding: br, gzip) on the document URL and on each large text resource in the critical path. Look for content-encoding and for transfer size versus content size. If the document is compressed but the main stylesheet is not, the Enable text compression audit can still fail, and paint can still wait on uncompressed bytes.

Partial coverage is the usual miss after a “we enabled Brotli” ticket. Origin middleware compresses HTML; the CDN serves fingerprinted CSS from a bucket that never negotiated Brotli; fonts and JSON follow yet another path. Agencies also see the reverse: the lab client hits a cache or region where encoding differs from the URL the engineer tested by hand. Until you can name the encoding on the document and the two or three largest text blockers, treat the toggle as incomplete evidence.

Why Brotli can leave Largest Contentful Paint unchanged

LCP measures when the largest visible element finishes rendering, not when every text file is as small as possible. Compression helps when download time for HTML, CSS, or critical JavaScript was a meaningful slice of that path. It does nothing useful for an LCP image that is still a multi-megabyte JPEG, lazy-loaded by mistake, or discovered late after client-side rendering. Decode and layout work on the main thread also sit outside what compression can fix: a smaller JavaScript transfer still costs the same parse and execute time once the bytes arrive.

In our experience, teams over-credit the compression ticket because it is easy to mark done. The lab waterfall still shows a late LCP resource, a long Time to First Byte, or render-blocking scripts that compression only shortened by tens of milliseconds. When transfer size was never the bottleneck, expecting a Core Web Vitals step-change from Brotli alone is the wrong bet. Use the LCP element detail in PageSpeed Insights or Lighthouse: if the element is an image or a late text block waiting on fonts and scripts, compression is support work, not the fix.

When enabling Brotli makes PageSpeed Insights worse

Compression can raise Time to First Byte (TTFB) when the origin or edge encodes HTML on every request at a high Brotli quality level. Smaller bodies help only after the first byte is available. If CPU queues behind dynamic compression, every paint metric starts later even though transfer size looks healthier in the waterfall. That pattern shows up after someone raised Brotli quality to the maximum on dynamic pages without precompressing static assets or without a moderate quality setting for HTML.

Other regressions are quieter. Double compression (a gzip wrapper around an already-Brotli body, or filters stacked at origin and edge) burns CPU without shrinking useful bytes. Compressing JPEG, PNG, WebP, AVIF, or MP4 as if they were text adds work for almost no gain. Missing or wrong Vary: Accept-Encoding on shared caches can mix encodings across clients and produce flaky lab runs that look like random PageSpeed noise. When the score drops after the toggle, compare Time to First Byte and the server-response audit before chasing image formats again.

What to fix next when the LCP element is not a text file

Once Content-Encoding looks correct on the critical path, return to ordinary LCP triage. Identify the LCP element. If it is an image, check discovery (preload or early HTML), format and dimensions, and whether loading="lazy" was applied to the hero by mistake. If Time to First Byte is high, compression will not hide a cold origin, an uncached HTML document, or a slow application query. If render-blocking CSS and JavaScript dominate, shrinking them with Brotli helps a little; removing or deferring work that is not needed for first paint usually helps more.

Keep compression and caching as paired delivery checks rather than as a substitute for element-level work. Cache-Control decides whether repeat views reuse bytes; Brotli and gzip decide how small the first download of text is. Neither replaces a late LCP image or a client-only render of the hero. For agencies, a clear client update is: compression is done and verified; the remaining LCP risk is named (image, Time to First Byte, or blocking scripts) with an owner and a retest plan.

How agencies verify compression and LCP across a client portfolio

One curl on staging is not enough evidence across a client portfolio. After deploys that touch CDN, origin, or build output, re-check Content-Encoding on each client’s homepage and other priority pages, then re-run the same lab profile you use for monthly reporting. Scheduled PageSpeed monitoring catches the case where Brotli is on in one region and missing in another, or where a theme update reintroduces uncompressed CSS while the dashboard still says compression is enabled. Pair those runs with a short note in the monthly report: encoding verified on the document and main CSS/JavaScript; LCP element and Time to First Byte trend unchanged or improved.

That habit keeps the compression ticket from being closed while LCP is still slow. It also stops the next quarterly review from reopening “we turned Brotli on months ago” when the real issue was always the hero image or the origin. Include compression checks in the same monitoring cadence you already use for Core Web Vitals regressions. A separate ritual that nobody opens after launch week does not help.

FAQ

Does Brotli always improve Largest Contentful Paint?
No. It can shorten download time for text on the critical path when that download was a real bottleneck. It will not fix a slow LCP image, a late-discovered hero, or a high Time to First Byte caused by origin work. Before-and-after lab runs on the same profile show whether the change mattered.

Why does Enable text compression still fail after we turned Brotli on?
The Lighthouse audit looks at individual text resources above a size threshold, not at a single CDN toggle. HTML may be compressed while CSS or JavaScript is not, or the lab path may differ from the URL you checked by hand. Confirm Content-Encoding on each flagged URL.

Can Brotli make PageSpeed scores worse?
Yes. High-quality dynamic compression on every HTML response can raise Time to First Byte. Double compression and compressing already-compressed media waste CPU without helping LCP. Prefer precompressed static assets and moderate settings for dynamic HTML, then retest.

Is gzip still needed if Brotli is enabled?
Yes as a fallback. Keep gzip for clients or hops that do not take br. Verify both encodings on the homepage and other priority pages rather than assuming the dashboard covers every path after a CDN or origin change.

CTA

If the toggle is green and LCP is still slow, treat compression as verified delivery work and name the next bottleneck in plain language. Confirm encoding on the critical path, then put image discovery, Time to First Byte, and render-blocking scripts on the work item with an owner. For enablement detail and MIME allow-lists, use the Watcher compression guide linked above; for caching that sticks beside those bytes, use the Cache-Control piece. When you need scheduled lab history across many client URLs so the next deploy cannot silently drop Content-Encoding, run continuous PageSpeed checks in Apogee Watcher rather than another one-off Insights paste.

References

Originally published on Hashnode.

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

Why is PageSpeed Insights worse than my local Lighthouse score?

ApogeeWatcherverified - Oct 2

How to increase PageSpeed/performance of a website that makes heavy use of interactive maps?

ApogeeWatcherverified - Sep 4

How we tuned apogee.lu for a 95 mobile PageSpeed score

ApogeeWatcherverified - Aug 31

Is PageSpeed Insights a good reference for web page structure/performance?

ApogeeWatcherverified - Aug 28

How Lighthouse Performance Scores Are Recorded and Calculated

ApogeeWatcherverified - Aug 18
chevron_left
9.5k Points • 306 Badges
184Posts
37Comments
110Connections
We bring quality & creative intelligence since 2002. We design, develop and operate custom informati... Show more

Related Jobs

View all jobs →

Commenters (This Week)

4 comments
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!