Why does a small favicon take 10 times as long to load?

464 Views Asked by At

I am using GTMetrix to analyze our website.

I find a strange thing. It takes 221 ms to load the 1.32k favicon.png. But takes only 26ms to load 1.61k logo.png, see below:

enter image description here

Why favicon.png needs so long to load? I test for many times, and favicon.png always takes about 10 times than other files with similar sizes.

All these resources are cached by Cloudflare and converted to webp format:

enter image description here

Update:

I checked carefully with logo.png and favicon, and indeed the response header of logo.png has an age, but favicon does not.

So I proceed to disable "Tiered Cache", but my option is unlike the answer:

enter image description here

After that, I make several tests via GTMetrix.

  1. For about half of the tests, the result is better, all resources are cached and delivered with a short time.
  2. However, for the remaining tests, the result is worse. several resources are "MISS" which take a long time to load, even in the previous test(from the same location), the same resource is "HIT" which indicates it has been cached already.

enter image description here

So, I just wonder why a previously "HIT" resource will become "MISS" after several seconds? Does Cloudflare clear edge cache very quickly? I checked Cloudflare document at https://blog.cloudflare.com/edge-cache-expire-ttl-easiest-way-to-override/ and it shows my plan(Pro) will use 1 hour as the TTL.

Also I see Cloudflare provides a "Cache Reserve" service which will increase the lifetime of the cached objects, seems just to solve this issue?

Update2:

To prevent cache eviction, I enable "Cache Reserve" in my Cloudflare. However, as I have disabled "Tired Cache", I get the following warning:

enter image description here

So, whether this is the best practice of disabling "Tried Cache" meanwhile enabling "Cache Reserve"?

Update 3:

After enabling "Cache Reserve" and disabling "Tired Cache", I made several tests and find a strange phenomena: The first several tests are normal, but then a test will lead to a very long load time, as below:

enter image description here

Below are the first several tests:

https://gtmetrix.com/reports/www.datanumen.com/VjtAGiyz/
https://gtmetrix.com/reports/www.datanumen.com/PRuta7WK/
https://gtmetrix.com/reports/www.datanumen.com/2hdYzL2B/

And this is the final one:

https://gtmetrix.com/reports/www.datanumen.com/8wKD5y9T/

I analyze the waterfall of the final one, and find the slowness is caused by some resources. They are cached, but do not contain "age", as below:

enter image description here

But I have already disabled the "Tied Cache", why this still occurs?

3

There are 3 best solutions below

10
VonC On

The Cloudflare thread mentions:

I’m running into an odd caching issue. On random page loads, some of my resources will display the cf-cache-status: HIT header but no age header. When this happens, the load takes a long time, between 1 to 2 seconds.

This is for static assets, images, fonts, JS, CSS, etc.

The solution there was:

The issue was “Tiered Caching” I had it enabled, and the second I disabled it everything was acting normal. The backend was a serverless nuxt app, but the origin never got requested after the initial cache, the delay was internal to Cloudflare.

But ya Tiered Caching was the culprit in this case.

That was also mentioned in this htread.

It could help in some scenarions, in others (depending on your setup) it can slightly decrease performance for getting a higher Cache-Hit ratio.
Keep it off for now.

https://developers.cloudflare.com/assets/tiered_cache_topology_hu06598bd295cd061af1cb3373da31c3d5_270009_1188x870_resize_q75_box_3-efc0b571.png


So, I just wonder why a previously "HIT" resource will become "MISS" after several seconds? Does Cloudflare clear edge cache very quickly?

When you see a HIT in the cf-cache-status header, it means the requested resource was served from Cloudflare's cache. A MISS, on the other hand, means the resource had to be fetched from the origin server because it was not in the cache, because of:

  • Expiration of the Cache Entry: Each cached resource has an associated Time To Live (TTL). When the TTL expires, the resource is removed from the cache and the next request for it will be a MISS. The TTL can be set by the cache-control or expires headers from the origin server, or it can be set by Cloudflare's caching rules. If the TTL is very short, a resource could become a MISS shortly after being a HIT.

  • Cache Eviction due to Limited Space: Cloudflare has a limited amount of space for caching resources on each of its edge servers. If the cache becomes full, Cloudflare may evict some resources to make room for new ones. That could cause a resource to become a MISS even if it was recently a HIT.
    See "Introducing Cache Reserve: massively extending Cloudflare’s cache" from Alex Krivit.

  • Different Edge Server: Each of Cloudflare's edge servers maintains its own cache. If your tests were handled by different edge servers, they could have different resources in their caches.

See more with "Third Time’s the Cache, No More" from Edward Wang.

Also, I see Cloudflare provides a "Cache Reserve" service which will increase the lifetime of the cached objects, seems just to solve this issue?

"Tiered Cache" and "Cache Reserve" are part of Cloudflare's Argo Smart Routing feature.

  • When Tiered Cache is enabled, an edge server that does not have a requested resource in its cache can fetch it from another edge server that does, instead of going all the way back to the origin server. That can make cache misses faster.

  • Cache Reserve, on the other hand, allows edge servers to keep a stale copy of a resource for a little longer after its TTL expires. If a request comes in for the resource right after it expires, the edge server can serve the slightly-stale cached copy instead of treating it as a MISS.

I checked Cloudflare document at "Edge Cache Expire TTL: Easiest way to override any existing headers" by Michelle Zatlyn, and it shows my plan (Pro) will use 1 hour as the TTL.

Note: this does not guarantee that a resource will stay in the cache for the full hour. As mentioned before, if the cache on a particular edge server becomes full, Cloudflare may remove some resources from the cache before their TTL expires to make room for new ones. That process is known as cache eviction.

In your case, if you see resources switching from HIT to MISS status within a shorter period of time, it could potentially be due to (as mentioned above) cache eviction, or due to the request being routed to a different edge server with a different cache state.

To control the cache behavior more precisely, you may want to set the cache-control headers on your origin server to specify the desired max-age for each resource. You can also use Cloudflare's Page Rules to set custom caching rules for different parts of your site.


To prevent cache eviction, I enable "Cache Reserve" in my Cloudflare. However, as I have disabled "Tired Cache", I get the following warning:

Using Cache Reserve without Tiered Cache is not recommended. 
You may observe increased origin load and significant
read/write operation charges. 
Please enable Tiered Cache Smart Topology or a compatible Custom Topology.

So, whether this is the best practice of disabling "Tried Cache" meanwhile enabling "Cache Reserve"?

By disabling Tiered Cache and enabling Cache Reserve, you are asking Cloudflare to keep stale resources in the cache (Cache Reserve) but not to share cached resources between edge servers (Tiered Cache).

The potential issue here is that if a resource is not in the cache of the edge server that receives a request (and it cannot get it from another edge server because Tiered Cache is disabled), it has to go all the way back to the origin server. That could increase load on your origin server and increase your bandwidth usage (hence the warning about "increased origin load and significant read/write operation charges").

In your case, if you are experiencing issues with Cloudflare's cache eviction and frequently getting MISS statuses, enabling Cache Reserve could indeed be beneficial. While your configuration is not generally recommended according to the warning message, it could potentially work in your situation.

From there, you would need to monitor the effects of this configuration on your server load, bandwidth usage, and website performance, and see if this setup is working for you.

1
Joseph Ishak On

First of all my apologies for adding this image as an answer but there isn't any way to post this in a comment that I know of. If someone lets me know, I will delete the answer.

Second of all, when I run GTMEtrix for your site. The difference is 12 ms for the logo vs 20 ms for the cropped image.

These results were received by running the test from GTMetrix using a test server in Vancouver Canada. Is it possible there is something network specific in play here. Have you run a similar test using Thousand Eyes to see what the results look like from multiple geographic locations?

enter image description here

0
David BS On

Try to convert it to .ICO (https://convertico.com/) and rename it to just "favicon.ico".

Some HTTPS/HTTPS servers can misunderstand different image types for page caching, due to wrong/poor configuration.