Content delivery networks, or CDNs, allow you to improve the delivery of your website’s static resources, most notably, with CDN caching. They do this by serving your content from edge locations, which are located all over the world. When a user browses to your site, and your site requests resources from the CDN, the CDN will route that request to the nearest edge location. If that location has the requested resources, either from that user’s prior visit, or from another person, then the content will be served from cache. If not, the CDN will request the content from your underlying domain, cache it, and serve it.
There are countless CDNs out there, but for this post we’ll be using AWS CloudFront. We’ll look at setting up a CloudFront distribution to serve all our site’s assets: JavaScript files, CSS files, font files, etc. Then we’ll see about integrating it into a Vite build. If you’d like to learn more about Vite, I have an introduction here.
Setting up a CloudFront CDN distribution
Let’s jump right in and set up our CloudFront CDN distribution.
For any serious project, you should be setting up your serverless infrastructure with code, using something like the Serverless Framework, or AWS’s CDK. But to keep things simple, here, we’ll set up our CDN using the AWS console.
Head on over to the CloudFront homepage. At the top right, you should see an orange button to create a new distribution.
The creation screen has a ton of options, but for the most part the default selections will be fine. First and foremost, add the domain where your resources are located.
Next, scroll down and find the Response headers policy dropdown, and choose “CORS-With-Preflight.”
Lastly, click the Create Distribution button at the bottom, and hopefully you’ll see your new distribution.
Integrating the CDN with Vite
It’s one thing for our CDN to be set up and ready to serve our files. But it’s another for our site to actually know how to request them from our CDN. I’ll walk through integrating with Vite, but other build systems, like webpack or Rollup, will be similar.
When Vite builds our site, it maintains a “graph” of all the JavaScript and CSS files that various parts of our site import, and it injects the appropriate <script>
tags, <link>
tags, or import()
statements to load what’s needed. What we need to do is tell Vite to request these assets from our CDN when in production. Let’s see how.
Open up your vite.config.ts
file. First, we’ll need to know if we’re on the live site (production) or in development (dev).
const isProduction = process.env.NODE_ENV === "production";
This works since Vite sets this environment variable when we run vite build
, which is what we do for production, as opposed to dev mode with hot module reloading.
Next we tell Vite to draw our assets from our CDN like so, setting the base
property of our config object:
export default defineConfig({ base: isProduction ? process.env.REACT_CDN : "",
Be sure to set your REACT_CDN
environment variable to your CDN’s location, which in this case, will be our CloudFront distribution’s location. Mine looks something (but not exactly) like this:
https://distributiondomainname.cloudfront.net
Watch your VitePWA settings!
As one final piece of cleanup, if you happen to be using the VitePWA plugin, be sure to reset your base
property like this:
VitePWA({ base: "/",
Otherwise, your web.manifest
file will have invalid settings and cause errors.
Let’s see the CDN work
Once you’re all set up, browse to your site, and inspect any of the network requests for your script or CSS files. For starters, the protocol should be h2.
From there, you can peek into the response headers of any one of those files, and you should see some CloudFront data in there:
Cache busting
It’s hard to talk about CDNs without mentioning cache busting. CDNs like CloudFront have functionality to manually “eject” items from cache. But for Vite-built assets, we get this “for free” since Vite adds fingerprinting, or hash codes, to the filenames of the assets it produces.
So Vite might turn a home.js
file into home-abc123.js
during a build, but then if you change that file and rebuild, it might become home-xyz987.js
. That’s good, as it will “break the cache,” and the newly built file will not be cached, so the CDN will have to turn to our host domain for the actual content.
CDN caching for other static assets
JavaScript, CSS, and font files aren’t the only kinds of assets that can benefit from CDN caching. If you have an S3 bucket you’re serving images out of, consider setting up a CloudFront distribution for it as well. There are options specifically for S3 which makes it a snap to create. Not only will you get the same edge caching, but HTTP/2 responses, which S3 does not provide.
Advanced CDN practices
Integrating a CDN here was reasonably straightforward, but we’re only enjoying a fraction of the potential benefits. Right now, users will browse to our app, our server will serve our root HTML file, and then the user’s browser will connect to our CDN to start pulling down all our static assets.
Going further, we would want to serve our entire site from a CDN. That way, it can communicate with our web server as needed for non-static and non-cached assets.
Conclusion
CDNs are a great way to improve the performance of your site. They provide edge caching and HTTP/2 out of the box. Not only that, but they’re reasonably easy to set up. Now you have a new tool in your belt to both set up a CDN and integrate it with Vite.
Adding CDN Caching to a Vite Build originally published on CSS-Tricks. You should get the newsletter.