As your static site starts to grow and become asset-heavy, with lots of images and other files that might go over bandwidth quotas such as those set by Netlify or Vercel, it’s a good idea to offload those resources to a fully-fledged CDN.
BunnyCDN is my personal choice here, since they’re very easy to use and have unbeatable pricing across the industry. Their feature set and network is customizable enough for websites of any size. I won’t go into setting up a Pull Zone as BunnyCDN’s Documentation is pretty robust.
Instead, this short guide focuses on how to integrate your CDN Pull Zone easily within Jekyll.
Global URLs
For places where the CDN can be hard-coded (such as icons or assets that won’t change much), you can add the CDN URL to your _config.yml
file as a global variable:
cdn: "https://cdn.paramdeo.com"
Then, where ever you need to reference the URL you can simply use the site-wide Jekyll variable as the string:
<link rel="shortcut icon" type="image/png" href="{{ site.cdn }}/img/favicon.png">
URLs by Environment
When making changes to your Jekyll site, often times you’ll want the local asset URLs to be referenced when building/serving locally, and to have the CDN links only used in production.
{% if jekyll.environment == "production" %}
{% capture cdn %}https://cdn.paramdeo.com{% endcapture %}
{% endif %}
The capture
Liquid tag assigns (captures) a string to the variable cdn
. In this case, the string is the CDN URL itself, and it’s also wrapped within a conditional if
statement that only resolves when the Jekyll environment is set to production
.
Personally, I set the environment to production
only in the build command that’s run by Netlify:
The process to use such a conditional variable is the same as the statically-linked one. Simply use the variable name within Liquid syntax:
<link href="{{ cdn }}/css/style.css" rel="stylesheet">
In the above example the compiled CSS needs to be reloaded if I made any styling changes. Without using the if
statement to determine the Jekyll build environment, a globally-defined cdn
URL string would load the CSS from the CDN each time time; preventing any changes from being shown when testing locally.
It’s worth noting that because of Jekyll’s order of interpretation when building a site, declaring such variables within files contained in the _layouts
folder is not going to work since those files are processed last in line. Basically, you’ll have to place the if
statement within each page where you want the variable to be referenced.
In my site for example, I place the if
statement in my _includes/head.html
so I can conditionally have my CSS, JS, and other assets defined in my <head>
load via BunnyCDN when in production
.
I also place the statement in all of my pages that use images, placing it just below the front matter. This isn’t really a chore, and is done once — much in the same way that front matter itself is added to a page or post.
---
layout: post
title: Optimize Jekyll using BunnyCDN
excerpt: "Offload assets and images using BunnyCDN for a more scalable Jekyll website."
date: 2020-08-21
categories: guides
---
{% if jekyll.environment == "production" %}
{% capture cdn %}https://cdn.paramdeo.com{% endcapture %}
{% endif %}
After pushing a lot of asset changes to your repo, it’s also a good idea to purge the pull zone’s cache, especially if you’ve set cache-control
headers in your Netlify configuration file since BunnyCDN will respect those headers by default.
BunnyCDN offers a plethora of granular customizations for HTTP Requests, IPs, Referrers, Edge Rules, Authentication, Routing, and more. I suggest you give them a try as their trial doesn’t require a credit card, and lasts for 14 days with 1TB of usage. Getting up and running takes a few minutes at most.
Links
- BunnyCDN — https://bunnycdn.com
- Liquid
capture
tag — https://shopify.github.io/liquid/tags/variable/#capture - Jekyll’s Order of Interpretation — https://jekyllrb.com/tutorials/orderofinterpretation/