How to Serve Static Assets With an Efficient Cache Policy

Last updated on Nov 22nd, 2024 | 7 min

TL;DR: The “Serve static assets with an efficient cache policy” warning means your website’s static files aren’t cached properly, slowing load times for repeat visitors. This happens due to missing or misconfigured cache headers, short cache durations, frequent updates without cache-busting, or inefficient third-party caching. Fix it by setting Cache-Control and Expires headers, using cache-busting, leveraging a CDN, or automating the process with an optimization tool like NitroPack.

 

Although it sounds too technical and impossible to fix, “Server static assets with an efficient cache policy” is one of those PageSpeed Insights warnings that can be easily resolved.

Serve static assets with an efficient cache policy PSI warning

In the following lines, you will learn everything you need to know about static assets, cache policies, and how to fix this issue and improve your performance.

Read on.
 

What Does “Serve Static Assets with An Efficient Cache Policy” Mean?

One of the reasons why many business owners neglect their site performance is because they get overwhelmed by all the BIG words used in the PSI and GTmetrix reports. 

That’s why, before delving into the strategies for fixing this warning, let’s decipher it.
 

What are static assets?

Static assets are files a web server delivers to a user's browser without modification. In other words, their content does not change dynamically based on user interactions or input. These assets are essential for rendering web pages and maintaining the site's design and functionality.

Common static assets include:

  • Images: .jpg, .png, .svg, .gif, .webp
  • Stylesheets: .css
  • JavaScripts: .js.
  • Fonts: .woff, .woff2, .ttf, .eot
  • Media files: .pdf, .docx, favicon.ico

Static assets

For instance, here’s the NitroPack home page above the fold and some of the static assets that our site is loading:

NitroPack home page static assets
 

What is browser caching?

Browser caching is a powerful technique that enhances website performance by storing copies of website (static) assets locally on a user's device. When a user visits your website for the first time, the browser downloads these assets from the server and temporarily saves them in a local cache. 

What happens when there's no cache in place

On subsequent visits or when navigating between pages on the same website, the browser retrieves these cached assets instead of downloading them again. This process reduces load times, conserves bandwidth, and improves the overall user experience.

Browser cache

Interestingly, the previous name of the sophisticated “Server static assets with an efficient cache policy” warning was actually “Leverage browser caching.”

Simply put, you only need to enable browser caching on your website so repeat visitors can benefit from a faster experience. 

When you enable caching, you need to set rules for how your statics assets will be used in the web browsers. 

This is called cache policy.
 

What is cache policy?

A cache policy is a set of rules or directives that dictate how web assets (like images, CSS, JavaScript, and other resources) should be stored, reused, and refreshed in a web browser or Content Delivery Network (CDN). It determines how long assets can remain in a cache before they are revalidated or downloaded again, helping to optimize performance and reduce bandwidth usage.

 

Cache policies are implemented through HTTP headers such as Cache-Control, Expires, ETag, and Last-Modified, which communicate instructions between the server and the browser on how to handle caching.

Here’s how to leverage each header:

  1. Cache-Control
    • What it Does: This header tells the browser (and any intermediaries like CDNs) how to handle the caching of a resource.
    • How it Works: It includes instructions like how long to keep a resource in the cache or whether it should check back with the server before using the cached version.
    • Common Directives:
      • public and private:
        • public: The file can be cached by any device (browser, CDN, etc.).
        • private: The file should only be cached by the user's browser.
      • no-store: Prevents the file from being cached at all.
      • no-cache: The browser must check with the server to see if the resource is still valid before using the cached version.
      • max-age: Defines how long (in seconds) the file can be cached. Example: Cache-Control: max-age=86400 (cache the file for 1 day).
         
  2. Expires
    • What it Does: Sets a specific date and time when the resource should stop being used from the cache.
    • How it Works: After the specified time, the browser will fetch a fresh copy from the server.
    • Example: Expires: Fri, 19 Nov 2024 08:00:00 GMT
    • Limitations: It uses absolute time, which can cause issues if the client and server clocks are not synchronized. It’s often replaced by Cache-Control.
       
  3. ETag
    • What it Does: Acts as a unique identifier (like a fingerprint) for a resource. The server uses it to tell the browser whether a cached file has changed.
    • How it Works: When the browser requests the file, it sends the ETag value it previously received. The server compares it with the current file’s ETag. If they match, the server responds with a "304 Not Modified" status, meaning the cached version is still good.
    • Example: ETag: "abc123"
    • Use Case Example: For a product image that might occasionally change, use an ETag to avoid unnecessary downloads.
       
  4. Last-Modified
    • What it Does: Indicates the date and time when the resource was last changed.
    • How it Works: When the browser requests the resource, it can ask if the file has been modified since the last date it was received. If not modified, the server responds with "304 Not Modified."
    • Example: Last-Modified: Wed, 18 Nov 2024 20:00:00 GMT
    • Use Case Example: For blog images that are rarely updated, this tells the browser when the image was last changed to minimize unnecessary downloads.

That said, for static assets that rarely change, the configuration would like this:

Cache policy example

This means that the specific asset can be cached by any device and should stored for one year. 

But here comes the question:

Are all static assets cachable?
 

What makes a static asset cachable?

Lighthouse, the tool that powers PageSpeed Insights and GTmetrix, considers a resource cacheable if all the following conditions are met:

  • The resource is a font, image, media file, script, or style sheet.
  • The resource has a 200, 203, or 206 HTTP status code.
  • The resource doesn't have an explicit no-cache policy.
     

Why Do You See the “Serve Static Assets With An Efficient Cache Policy” Issue? 

“But I have browser caching enabled on my website. Why on earth am I still triggering this warning?”

We feel you.

One would think leveraging browser caching would be enough to fix an issue with the same name (historically speaking).

Unfortunately, there are other reasons that might cause PSI and GTmetrix to flag the issue. 

Here are the most common ones:
 

1. No Cache-Control Header Set (Missing browser caching setup)

Some of your static assets don’t have a Cache-Control header. Without it, the browser might keep re-downloading the same resources unnecessarily.
 

2. Short Cache Duration

The max-age directive in the Cache-Control header is set to a very short duration, causing browsers to frequently revalidate or download assets, leading to increased page load times.
 

3. Frequent Changes to Static Assets

If assets (e.g., CSS, JavaScript, or images) are updated frequently without implementing cache-busting techniques, browsers may serve outdated versions of the files.

Cache busting is like a signal to your browser that something has changed, and it needs to grab the latest version of a file instead of reusing an older, stored one. For example, if you update a website’s design or fix a bug in its code, the browser might still show the old version because it saved it for faster loading. 

Cache busting ensures the browser fetches the new version by adding something unique, like a version number or timestamp, to the file’s name (e.g., changing style.css to style-v2.css). This way, the browser knows it’s dealing with something new.

Cache busting
 

4. Use of Query Strings for Static Resources

Building upon the cache-busting technique, some tools might flag assets with query strings (e.g., style.css?v=1.2) as having inefficient caching, which can be misleading. Query strings—those little ?v=1.2 bits added to file names—are often used for cache busting. 

However, the downside is that not all caching systems handle query strings efficiently. Some CDNs or proxy servers might ignore query strings altogether and still cache the original file, leading to unexpected behavior. 

This is why a good cache-busting practice is to include the version directly in the file name (e.g., style-v2.css), which tends to work more reliably across all caching systems.
 

5. Third-Party Resources

Third-party resources, such as scripts, fonts, or tracking pixels, often don’t follow efficient cache policies because they’re managed by external providers rather than your own server. This lack of control can make it challenging to optimize how these resources are cached. 

For example, a popular font library might have a shorter cache duration than ideal, causing browsers to download the same files repeatedly. Similarly, analytics or ad tracking scripts often prioritize real-time updates over caching efficiency, which can slow down your site.

While you can’t directly control the caching behavior of these resources, you can take steps to mitigate their impact. For instance, you can self-host certain third-party assets like fonts or implement lazy-loading techniques for scripts that aren’t immediately necessary. 
 

6. Absence of CDN or Caching Infrastructure

Serving static assets directly from the origin server can significantly impact performance due to geographic latency and server strain. 

Network latency

Geographic latency occurs when user requests must travel long distances to reach the server, resulting in slower loading times, especially for users far from the server's location. Additionally, during periods of high traffic, the origin server can become overwhelmed by requests, leading to delays or even outages.

Without CDN

A CDN addresses these issues by distributing assets across a network of servers located around the world. When a user requests a resource, the CDN serves it from the server closest to them, reducing latency and speeding up load times.

With CDN

This also reduces the load on the origin server, ensuring it can handle other critical tasks more efficiently. 
 

7. No Cache Validation Headers

As we discussed earlier, validation headers like ETag and Last-Modified are crucial in ensuring efficient caching. They help the browser determine whether a cached resource is still valid without re-downloading it entirely.

When these headers are missing, the browser cannot confirm if a file's cached version is up-to-date. This can lead to two potential issues: 

  1. Either the browser unnecessarily downloads the same resource again, wasting bandwidth and slowing down load times, or 
  2. It continues to use an outdated version of the file, potentially causing users to miss critical updates. 

Without proper validation headers, the caching mechanism becomes less effective, undermining both performance and reliability.
 

8. Use of HTTP Protocol Instead of HTTPS

Using HTTPS instead of HTTP is not just a security best practice—it also has significant implications for caching. Many modern browsers and tools offer better caching optimizations when assets are delivered over HTTPS. 

For instance, HTTPS supports advanced protocols like HTTP/2, which can handle multiple asset requests simultaneously, leading to faster load times and more efficient caching. HTTP, on the other hand, lacks these capabilities, making it less effective for delivering assets quickly and reliably.

Moreover, some browsers and performance tools explicitly flag HTTP resources as problematic, warning users and developers about potential security and caching inefficiencies. These warnings can impact both your website’s perceived reliability and performance scores.

No HTTPs
 

How to Fix “Serve Static Assets With an Efficient Cache Policy” with a WordPress Plugin

Although it may seem like a lot of technical work, if you’re on WordPress, there are tons of plugins available that will set up browser caching for you. 

The only downside is that the majority of them do only that. Hence, you will need 2-3 more plugins for image optimization, font subsetting, code minification and compression. All of a sudden, you’re bloating your website with third-party tools that were supposed to speed up your website, but they do the opposite. 

There’s a better way. 

Enter NitroPack

NitroPack is the leading all-in-one web performance optimization solution for passed Core Web Vitals, load times under 3s, and more sales. Trusted by 230,000+ websites globally, our solution will provide you with an advanced caching mechanism and 50+ performance optimizations. 

CWV Tech Report ranks NitroPack first

When it comes to fixing the “Server static assets with an efficient cache policy” warning, NitroPack will automatically set up the appropriate caching headers, such as Cache-Control and Expires, for your website's assets. 

Furthermore, you get a ton of extra caching features like:

  • Cache expiration time – allows you to define the lifespan of your cache for optimal website management
  • Ignored parameters – you can specify a list of URL parameters that do not modify the page content and can be safely ignored
  • Must include headers – list all HTTP response headers that must be preserved in the optimized page
  • Built-in CDN – server your content from more than 100 servers distributed all around the world

NitroPack Cache settings

On top of all that, NitroPack also provides you with:

  • Complete image optimization stack
  • Font optimization
  • Code compression and minification
  • Lazy loading
  • Critical CSS
  • Reduce Unused CSS

Fix all your speed performance issues. Get NitroPack for FREE →

How to Fix “Serve Static Assets With an Efficient Cache Policy” Manually

Important: Do not apply server changes manually if you do not have the technical expertise. Adding HTTP response headers incorrectly could lead to website issues. Instead, contact your hosting provider or an experienced web developer. 

Depending on your server configuration, you will have to insert the HTTP headers manually:
 

Add “Cache-Control” and “Expires” Headers in Nginx 

First, locate the Nginx configuration file you need to edit. This is typically found at 

  • /etc/nginx/nginx.conf – for global settings
  • /etc/nginx/sites-available/ or /etc/nginx/conf.d/ – for site-specific configurations. 

Use a text editor like nano or vim to open the relevant file. For example, to edit the configuration for a specific domain, run:

Nginx site configuration code example

Inside the configuration file, locate the server block or a specific location block corresponding to the directory serving your static assets. To add caching headers, you can define rules for specific file types, like this:

Nginx cache headers

In this example, static assets such as images, fonts, and stylesheets are cached for one year using Cache-Control: public, max-age=31536000, and an Expires header. Of course, you can set the expiration date to whatever works best for you.

At the same time, dynamic files like PHP or HTML are excluded from caching by setting Cache-Control: no-cache, no-store, must-revalidate, and disabling the Expires header. This ensures users always get the latest version of dynamic content.

Once you’ve added the caching rules, test the configuration to ensure there are no syntax errors. Run the following command:

Nginx syntax errors

If the test is successful, apply the changes by reloading Nginx:

Reload nginx
 

Add “Cache‑Control” and “Expires” Headers in Apache

First, locate the appropriate Apache configuration file:

  • For global settings, you can edit: /etc/httpd/conf/httpd.conf or /etc/apache2/apache2.conf
  • For a specific site, look for files like /etc/apache2/sites-available/example.com.conf

Alternatively, if you can only access .htaccess files, these are typically located in your site’s root directory, such as /var/www/html/.htaccess.

Before configuring the headers, ensure that the necessary Apache modules are enabled. To add Cache-Control headers, enable the mod_headers module by running:

Apache module headers

For Expires headers, you’ll also need the mod_expires module:

Apache expires module

With the modules enabled, you can now configure the caching headers. If you want to apply these settings globally, add the following to your configuration file inside the VirtualHost block:

Apache VirtualHost

This configuration tells browsers to cache static assets for one year, which is ideal for resources that don’t change frequently, like images or fonts.

If you’d rather target specific file types, use the FilesMatch directive. For example:

Apache filesmatch

This configuration applies caching rules only to assets like images, stylesheets, fonts, and scripts, ensuring efficient delivery of these static resources.

For dynamic content like PHP or HTML files, you may want to prevent caching entirely to ensure users always receive the latest version. Add the following rules:

Apache dynamic assets

After making these changes, restart Apache to apply the updated configuration:

Apache restart
 

FAQs

How long should I cache my static assets?

Cache static assets for as long as they don’t change frequently. For example, logos or fonts can be cached for a year, while frequently updated files like CSS or JavaScript might require shorter durations, such as a month.
 

How can I check if my cache policy is working correctly?

Use browser developer tools (e.g., Chrome DevTools) or performance analysis tools like PageSpeed Insights or GTmetrix to inspect caching headers and verify expiration times.
 

What if my static assets change before the cache expires?

Implement cache-busting techniques, such as adding version numbers or hashes to file names (e.g., style-v2.css). This ensures browsers download the updated file instead of serving the cached version.
 

Are there any downsides to using an efficient cache policy?

The main downside is the risk of serving outdated files if cache-busting isn’t implemented. However, with proper techniques, efficient caching provides significant performance and bandwidth benefits.
 

Can I use a Content Delivery Network (CDN) to improve my cache policy?

Yes, a CDN can significantly enhance caching by distributing assets to servers closer to users, reducing latency, and offloading traffic from your origin server.

Niko Kaleev
User Experience Content Expert

Niko has 5+ years of experience turning those “it’s too technical for me” topics into “I can’t believe I get it” content pieces. He specializes in dissecting nuanced topics like Core Web Vitals, web performance metrics, and site speed optimization techniques. When he’s taking a breather from researching his next content piece, you’ll find him deep into the latest performance news.