Files sent uncompressed, without a cache lifetime or unminified
Have your web server or CDN compress HTML, CSS and JavaScript with Brotli or gzip. Send images, scripts and stylesheets with a Cache-Control max-age, a year for files whose names change with each version. Minify scripts and stylesheets when the site is built or with your platform's setting. Shopify compresses and minifies theme files itself.
Why it matters
Text files shrink a lot when compressed. The browser says which compression it accepts and the server picks one; Chrome's documentation calls Brotli the more efficient choice and gzip the fallback every major browser supports. Google's crawlers accept gzip, deflate and Brotli too.
A Cache-Control lifetime lets a returning visitor's browser reuse a file without asking for it again. Without one, browsers still cache the file, for a time they guess. With no-store they never keep it, and with no-cache they check with the server before every use. Chrome's documentation advises caching static files that never change for a year or longer, with a hash in each file's name so a new version gets a new address.
Minifying removes what only people need: comments, indentation and line breaks; a minifier also shortens names. Lighthouse estimates the saving from comments and whitespace and calls that a conservative estimate. Ours is the same kind of lower bound.
Our own site had this finding. The audit of serpcompass.com at 17:58 UTC on 28 October 2026 estimated that minifying would take about 19 KB off our 106 KB stylesheet (19%) and about 2 KB off our 5 KB consent script (37%).
SERPCompass rates all three as notices: they make pages lighter, above all on phones and repeat visits, but a page that is slow for other reasons stays slow, so check the Largest Contentful Paint guide too. The thresholds are ours: HTML over 10 KB sent without compression, and a minifying saving of at least 2 KB and 10% of the file. Files without a cache lifetime and unminified files are each one finding for the whole site, because one server or build setting usually fixes them all.
The audit findings this guide fixes: HTML served without compression (over 10 KB); Static files served without a cache lifetime; Scripts and stylesheets that look unminified (estimate).
Find every page with this problem
Run the free scan on your domain. For every page it crawls, it notes whether the HTML arrived compressed: the crawler asks for compression as browsers do, and a page over 10 KB that comes back without a Content-Encoding is flagged. It also checks the images, scripts and stylesheets your pages load from your own domain and its subdomains, up to 176 files in the free scan; files on other domains, such as a site builder's or a CDN's, are not checked. A file is flagged as having no cache lifetime when its Cache-Control has no max-age (or s-maxage) above 0, no immutable and there is no Expires date, or when it says no-store or no-cache. Scripts and stylesheets are read up to their first 256 KB, and the scan works out what removing comments and runs of whitespace would save; at least 2 KB and 10% of the file is flagged, with the estimate. The Gap Report and a SERPCompass workspace list the pages and files, each file with a page that loads it. To check one file yourself, open your browser's developer tools, choose the Network panel, reload, select the file and read content-encoding and cache-control under Response Headers.
How to fix it on your platform
WordPress
- WordPress loads minified copies of its own scripts and stylesheets unless
wp-config.phpsetsSCRIPT_DEBUGtotrue, which loads the readable development versions. If the audit lists files of WordPress itself, check that line: the default isfalse. - For your theme's and plugins' files, use the minify option of a caching or optimization plugin; WordPress's optimization handbook notes that some caching plugins minify and combine stylesheets and scripts. Check the site still works after turning it on.
- For compression, Chrome's advice for WordPress sites is to enable it in your web server's configuration (Apache and NGINX below); on managed hosting, ask your host.
- For cache lifetimes, WordPress's handbook points to
Cache-Control(max-age) andExpiresheaders on files that do not change, such as images, CSS and JavaScript. Some caching plugins set them; otherwise set them in the server.
Sources: Debugging in WordPress (WordPress advanced administration handbook); Optimization (WordPress advanced administration handbook); Enable text compression (Chrome for Developers).
Shopify
- Files delivered through the Shopify CDN are compressed with Brotli and gzip, and Shopify minifies CSS files and JavaScript written in ES5 syntax when the storefront requests them, automatically.
- Shopify serves a file as it is when its name ends in
.min.jsor.min.css, or when the minified copy would be larger, and does not minify JavaScript beyond ES5 syntax. If the audit lists such a theme file, minify it yourself before you upload it, and keep.minnames for files that really are minified. - Load theme files with the
asset_urlfilter. It adds a version number to each file's address, so browsers fetch the new file after you update it.
Sources: The Shopify platform (Shopify.dev); Serve assets from Shopify CDN (Shopify.dev).
Webflow
- Open Site settings > Publishing > Advanced publishing options (the same options are in the publishing dropdown in the Designer).
- Under Minify HTML, CSS, JS, turn on each of the three that is off: Webflow minifies them separately. Save, then publish your site.
Sources: Advanced publishing options (Webflow Help Center); Minified code (Webflow glossary).
Cloudflare
- Cloudflare compresses responses to visitors itself, with Zstandard, Brotli or gzip depending on your plan and what the browser accepts, for HTML, CSS, JavaScript and other text types. Your server's own compression is not required.
- Auto Minify no longer exists: Cloudflare deprecated it on 5 August 2024. Minify files in your build, CMS or plugin instead.
- By default Cloudflare keeps your server's
Cache-ControlandExpires, but replaces them when your server sends neither, or a shorter lifetime than the Browser Cache TTL setting (4 hours by default). For a year on versioned files, send that from your server or raise the Browser Cache TTL.
Sources: Content compression (Cloudflare docs); API deprecations (Cloudflare docs); Edge and Browser Cache TTL (Cloudflare docs).
Apache
- With mod_deflate enabled, compress text types:
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript. - With mod_expires, give static files a lifetime:
ExpiresActive On, then a line per type, such asExpiresByType text/css "access plus 1 month". It sets both theExpiresheader and themax-ageofCache-Control. - mod_expires leaves alone a response that already carries an
Expiresheader, such as one made by a script or a proxied server: set the lifetime there.
Sources: mod_deflate (Apache HTTP Server documentation); mod_expires (Apache HTTP Server documentation).
NGINX
- Turn compression on with
gzip on;; it is off by default. HTML is then always compressed; add other types withgzip_types, for examplegzip_types text/css application/javascript;. - In the
locationthat serves your static files,expires 365d;sets anExpiresheader andCache-Control: max-ageof a year. A negative time sendsno-cache, so avoid that for static files.
Sources: ngx_http_gzip_module (nginx documentation); ngx_http_headers_module (nginx documentation).
Plain HTML
- Minify CSS and JavaScript as a step of your build, with a tool such as Terser for JavaScript; for a small site you rarely change, an online minifier is enough. Keep the readable files as your source and publish the minified ones.
- Put a version or a hash in the name of each static file, such as
style.3f9a1c.css, and send it withCache-Control: max-age=31536000. When the file changes, its name changes, so visitors fetch the new one. - For files whose names never change, use a shorter lifetime or
no-cache, which lets the browser keep the file but check with the server before using it.
Sources: Minify JavaScript (Chrome for Developers); Minify CSS (Chrome for Developers); Serve static assets with an efficient cache policy (Chrome for Developers); Prevent unnecessary network requests with the HTTP Cache (web.dev).
Examples
-
Bad
HTTP/1.1 200 OK Content-Type: text/css Content-Length: 108544A stylesheet sent uncompressed and with no cache lifetime: every new visit downloads all 106 KB, and returning visitors depend on the browser's guess.
-
Good
HTTP/2 200 content-type: text/css content-encoding: br cache-control: max-age=31536000, immutableCompressed with Brotli and kept for a year. The file's name carries a hash, so a new version gets a new address.
-
Bad
/* Header styles */ .site-header { display: flex; padding: 16px 24px; }Readable source: fine to write, wasteful to send.
-
Good
.site-header{display:flex;padding:16px 24px}The same rule, minified when the site is built.
-
Good
AddOutputFilterByType DEFLATE text/html text/css application/javascript ExpiresActive On ExpiresByType text/css "access plus 1 month" ExpiresByType application/javascript "access plus 1 month" ExpiresByType image/* "access plus 1 month"Compression for text and a month's lifetime for stylesheets, scripts and images. Use a year only for files whose names change with each version.
-
Good
gzip on; gzip_types text/css application/javascript; location /static/ { expires 365d; }HTML, CSS and JavaScript compressed; versioned static files kept for a year.
Common mistakes
- Giving a year-long lifetime to files whose names never change. Visitors keep the old copy after you update it; Chrome's documentation pairs long lifetimes with a hash in the file name.
- Naming a file
.min.jsor.min.csswhen it is not minified. Shopify serves such files as they are, and people assume they are done. - Looking for Cloudflare's Auto Minify switch: Cloudflare deprecated it in August 2024.
- Turning compression on for HTML only. NGINX's
gzip_typescompresses HTML alone until you add CSS and JavaScript. - Setting
no-storeon every response, static files included, so browsers never keep them. - Leaving
SCRIPT_DEBUGset totrueon a live WordPress site after debugging. - Turning on a minify option and not checking the site afterwards. Test the pages with forms, menus and checkout before you leave it on.
Questions and answers
Should I use gzip or Brotli?
Offer both if you can. Chrome's documentation says Brotli makes files smaller than the other algorithms, and that gzip, though less efficient, is supported by every major browser. The browser lists the encodings it accepts and the server or CDN picks one, so offering both costs nothing.
How long should browsers cache CSS, JavaScript and images?
A year, max-age=31536000, for files whose names change whenever their content does, as Chrome's documentation and web.dev advise. For files whose names never change, use a shorter lifetime or no-cache, so visitors are not stuck with an old copy. SERPCompass only flags files with no lifetime at all, or with no-store or no-cache.
What happened to Cloudflare's Auto Minify?
Cloudflare deprecated it on 5 August 2024, along with the API that set it. Minify your scripts and stylesheets in your build, your CMS or a plugin instead. Cloudflare still compresses responses to visitors.
Is the saving SERPCompass shows for unminified files exact?
No, it is an estimate and a lower bound. The scan counts the comments and runs of whitespace a minifier would remove from the first 256 KB of each file; a real minifier also shortens names and saves more. Lighthouse estimates its own figure the same way and calls it conservative.
Will compression and caching improve my Google rankings?
We make no ranking promise. These fixes make files smaller and repeat visits faster, which helps people on slow connections. Google's crawlers accept gzip, deflate and Brotli. For what Google says about page speed and ranking, see our Largest Contentful Paint guide.
More guides
- Slow-loading pages and a poor Largest Contentful Paint
- Images that are too large or in an older format
- Layout shift: content that jumps while the page loads
- All guides
- Free tools: checks for robots.txt and llms.txt that need no account.
Sources
- Overview of Google crawlers and fetchers (Google Crawling Infrastructure)
- Enable text compression (Chrome for Developers)
- Serve static assets with an efficient cache policy (Chrome for Developers)
- Minify CSS (Chrome for Developers)
- Minify JavaScript (Chrome for Developers)
- Prevent unnecessary network requests with the HTTP Cache (web.dev)
- Debugging in WordPress (WordPress advanced administration handbook)
- Optimization (WordPress advanced administration handbook)
- The Shopify platform (Shopify.dev)
- Serve assets from Shopify CDN (Shopify.dev)
- Advanced publishing options (Webflow Help Center)
- Minified code (Webflow glossary)
- Content compression (Cloudflare docs)
- API deprecations (Cloudflare docs)
- Edge and Browser Cache TTL (Cloudflare docs)
- mod_deflate (Apache HTTP Server documentation)
- mod_expires (Apache HTTP Server documentation)
- ngx_http_gzip_module (nginx documentation)
- ngx_http_headers_module (nginx documentation)
Start with a free scan of your site.
Two to five minutes, no account. You get your three most urgent findings, and the exact count of everything else.