Text files served from cache with etags are not compressed with gzip or brotli
See original GitHub issuev0.0.11 added support for cache revalidation via etags. Per RFC2616, Cloudflare does not alter responses from cache that have a strongly-held etag
header, so resources that are not gzipped or brotli compressed by the origin server (or kv-asset-handler
) will either have their etags stripped or remain in their uncompressed state when delivered to a client.
Some requirements for implementing compression on text files:
- Must be able to serve files in both uncompressed and compressed form based on the client’s Accept-Encoding request header
- Must provide gzip compression (brotli is a nice-to-have)
- Must include
content-type
andcontent-encoding
response headers upon cache insertion - Each variant of content-encoding will need to produce a corresponding etag variant
- Must detect mime type of assets to determine which files can be compressed
Compression can be handled in one of three ways:
- Apply compression on-the-fly in Workers. This would probably require an NPM package and is the least resource-efficient option available
- Allow Cloudflare CDN to apply compression on-the-fly. This would require modifying both the format of the etag and the comparison validation function.
- Apply compression during upload to KV. This is probably the best solution and certainly the most resource efficient
Issue Analytics
- State:
- Created 3 years ago
- Comments:19 (17 by maintainers)
Top Results From Across the Web
Serving compressed files - Amazon CloudFront
CloudFront can compress objects using the Gzip and Brotli compression formats. ... If the compressed object is not in the cache, CloudFront forwards...
Read more >Enable dynamic compression | Cloud CDN - Google Cloud
Dynamic compression works with a global external HTTP(S) load balancer (classic) to automatically compress responses served by Cloud CDN between the origin ...
Read more >Lighthouse recommends compression even when enabled
Text -based resources should be served with compression (gzip, deflate or brotli) to minimize total network bytes. Learn more.
Read more >Cant cache resource when having both gzip and Etag
But no, I keep getting 200 OK, which means that apache keeps serving the file (albeit compressed) every time. Tested with Firefox, Chrome,...
Read more >Chapter 10. Fine-tuning asset delivery - Web Performance in ...
If you encounter a file type that you're not sure is compressible, ... TTFB performance of gzip versus Brotli when compressing the jQuery...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@SukkaW - can you please provide a detailed bug report if you believe the etag is not working as expected? Please bear in mind that:
cache-control
headers on the response are what dictate caching behavior. Settingcache-control: no-cache
on the request does not alter the outcome of the responsekv-asset-handler
For a point of reference, use this site: https://free.dinos.network/. It’s on the free plan, has no cache settings set in page rules and – importantly – sends
cache-control: must-revalidate, max-age=0
on the response. As outlined in the Stack Overflow post, this is the setting you need to set to get back consistent 304 responses from a remote server when using strong etags 😃@shagamemnon
I do know why
ETag
is retained whenAccept-Encoding: deflate
is presented: because Cloudflare won’t apply ANY compression (deflate is not supported).So far here is what I found:
When Cloudflare trying to run compression using
gzip
orbr
:W/
is added).“Origin” can be origin server or workers. I tested, their behavior are the same when handling ETag.
Here Cloudflare Web Server is doing the right thing: After compression using gzip/br the response will no longer be exactly identical, that’s why Strong ETag wrapped in quote will be transformed into Weak ETag (and Origin’s Weak ETag could be retained).
The origin’s response with Strong ETag (before compression is applied to the response and ETag being transformed into Weak Tag) will be stored into Cloudflare Cache. That’s why Cloudflare will sends Strong ETag to origin server for validation, am I right?
Don’t blame Cloudflare Cache, blame yourselves. Cloudflare Cache want to return a 304 response, but
kv-asset-handler
just use theresponse.body
(which in the case is empty) to build a 200 response:https://github.com/cloudflare/kv-asset-handler/blob/deda2296c920405bd377c3d17394ac611a49e548/src/index.ts#L164
https://github.com/cloudflare/kv-asset-handler/blob/deda2296c920405bd377c3d17394ac611a49e548/src/index.ts#L202
If
kv-asset-handler
usesresponse
object returned by Cloudflare Cache directly, it will be a empty response with 304 status code.https://github.com/cloudflare/kv-asset-handler/blob/deda2296c920405bd377c3d17394ac611a49e548/src/index.ts#L177-L182
In short, empty response is caused by
shouldRevalidate
algorithm is different compared with Cloudflare Cache, not caused the format of ETag.No, it is very easy. Cloudflare Cache
caches.default.match
will return aresponse
object, just use it directly instead of building a new response, then you will have correct status code (which is 304).Blame Cloudflare Staffs (your guys) again.