Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 47 additions & 4 deletions gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,56 @@ module.exports = {
resolve: "gatsby-plugin-netlify",
options: {
headers: {
"/*": [
"X-Frame-Options: SAMEORIGIN",
"Content-Security-Policy: frame-ancestors 'self'",
// Cache static assets with content hashes for 1 year
"/static/*": [
"Cache-Control: public, max-age=0, must-revalidate",
],
"/*.js": [
"Cache-Control: public, max-age=2592000, immutable",
],
"/*.css": [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely, we change our CSS many times within the span of a year and will find ourselves in trouble if we don't age this content much more aggressively.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've looked into this further, and while Gatsby's content hashing technically prevents broken styles even with a 1-year cache, a shorter duration is indeed better to avoid "cache bloating" in users' browsers given our frequent updates. I propose lowering the max-age to 30 days. This seems to be the ideal sweet spot because it is the minimum duration required to pass Google PageSpeed Insight's "Serve static assets with an efficient cache policy" audit without warnings, while still keeping the cache size manageable compared to the 1-year default.

Here are the references supporting this approach, including the NitroPack guide and Google's documentation:
nitro
screamingfrog
developer.chrome

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 05901ad

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically, I have configured
HTML and page-data to always revalidate (max-age=0) so users immediately see new deployments
CSS and JavaScript files are now set to 30 days (max-age=2592000) to prevent cache bloat.
Fonts and images remain at 1 year (max-age=31536000) since these assets rarely change

"Cache-Control: public, max-age=2592000, immutable",
],
"/page-data/*": [
"Cache-Control: public, max-age=0, must-revalidate",
],
// Fonts should be cached for 1 year
"/*.woff": [
"Cache-Control: public, max-age=31536000, immutable",
],
"/*.woff2": [
"Cache-Control: public, max-age=31536000, immutable",
],
"/*.ttf": [
"Cache-Control: public, max-age=31536000, immutable",
],
// Images with hashes can be cached long-term
"/*.png": [
"Cache-Control: public, max-age=31536000, immutable",
],
"/*.jpg": [
"Cache-Control: public, max-age=31536000, immutable",
],
"/*.webp": [
"Cache-Control: public, max-age=31536000, immutable",
],
"/*.svg": [
"Cache-Control: public, max-age=31536000, immutable",
],
// HTML files should not be cached
"/*.html": [
"Cache-Control: public, max-age=0, must-revalidate",
],
"/": [
"Cache-Control: public, max-age=0, must-revalidate",
],
},
allPageHeaders: [
"X-Frame-Options: SAMEORIGIN",
"Content-Security-Policy: frame-ancestors 'self'",
],
mergeSecurityHeaders: true,
mergeCachingHeaders: true,
mergeCachingHeaders: false, // Disable default caching headers to use custom ones
},
},
{
Expand Down