Home Blog How to Make Your Jekyll Site Load Under 1 Second
Tutorial

How to Make Your Jekyll Site Load Under 1 Second

Practical techniques to optimise Jekyll site performance — image compression, CSS/JS minification, lazy loading, caching headers, and Core Web Vitals improvements.

How to Make Your Jekyll Site Load Under 1 Second

Jekyll sites are inherently fast — there’s no PHP, no database, no server-side rendering. But “fast” isn’t automatic. Poor image handling, unminified CSS, and render-blocking scripts can slow even a static site to a crawl. This guide covers practical techniques to get your Jekyll site loading in under a second.


Measure First

Before optimising, measure your current performance so you know what actually needs fixing.

Tools:

  • PageSpeed Insights — Google’s official tool, shows Core Web Vitals scores
  • GTmetrix — detailed waterfall charts showing exactly what’s slow
  • WebPageTest — advanced testing from multiple locations

Run your homepage and a typical post through PageSpeed Insights. The report will highlight your biggest opportunities.


1. Choose a Fast Hosting Platform

The hosting provider has the biggest impact on time-to-first-byte (TTFB).

Platform Free Plan CDN TTFB
Cloudflare Pages Yes Global (300+ PoPs) Excellent
Netlify Yes Global Very good
GitHub Pages Yes Limited Good
Vercel Yes Global Very good

For the fastest possible Jekyll hosting, use Cloudflare Pages. It has the most distributed CDN, meaning files are served from the closest location to each user worldwide.


2. Optimise Images (Biggest Win)

Images are the #1 cause of slow pages. A single unoptimised photo can be 3–5MB — more than all your HTML, CSS, and JS combined.

Convert to WebP

WebP images are 25–35% smaller than JPEG at the same quality.

# Convert a single image
cwebp -q 85 photo.jpg -o photo.webp

# Batch convert all JPEGs
for f in assets/images/*.jpg; do
  cwebp -q 85 "$f" -o "${f%.jpg}.webp"
done

Serve WebP with a JPEG fallback:


<picture>
  <source srcset="{{ image | replace: '.jpg', '.webp' }}" type="image/webp">
  <img src="{{ image }}" alt="{{ alt }}" loading="lazy">
</picture>

Lazy Load Images

Add loading="lazy" to all images that are not in the initial viewport:


<img src="{{ post.image }}" alt="{{ post.title }}" loading="lazy" width="800" height="450">

Always include width and height to prevent Cumulative Layout Shift (CLS).

Responsive Images

Serve appropriately-sized images for each screen size:

<img
  srcset="/assets/images/hero-400.webp 400w,
          /assets/images/hero-800.webp 800w,
          /assets/images/hero-1200.webp 1200w"
  sizes="(max-width: 600px) 400px,
         (max-width: 1000px) 800px,
         1200px"
  src="/assets/images/hero-800.webp"
  alt="Hero image"
  loading="lazy">

The jekyll-picture-tag plugin automates this.


3. Minify CSS and JavaScript

Minify Sass

Jekyll compiles Sass automatically. Set it to compressed output:

# _config.yml
sass:
  style: compressed
  sourcemap: never

This removes whitespace and comments from all CSS. Typically reduces CSS size by 20–30%.

Minify HTML

Add the jekyll-minifier plugin:

gem "jekyll-minifier"
# _config.yml
jekyll-minifier:
  compress_javascript: true
  compress_css: false  # Already handled by Sass
  remove_comments: true
  remove_intertag_spaces: true

Defer JavaScript

Any script that doesn’t need to run before the page renders should be deferred:

<!-- In your layout's </body> or with defer -->
<script src="/assets/js/main.js" defer></script>

Never block rendering with scripts in <head> unless absolutely necessary.


4. Optimise Font Loading

Google Fonts are a common performance culprit. Each font family adds an extra DNS lookup and CSS request.

Self-Host Fonts

Download fonts and serve them from your own server:

  1. Download fonts from Google Fonts Helper
  2. Place in assets/fonts/
  3. Define with @font-face in your CSS
@font-face {
  font-family: 'Inter';
  src: url('/assets/fonts/inter-v13-latin-regular.woff2') format('woff2');
  font-display: swap;
  font-weight: 400;
}

Preload Critical Fonts

<link rel="preload" href="/assets/fonts/inter-regular.woff2" 
      as="font" type="font/woff2" crossorigin>

Use font-display: swap

This renders text in a fallback font while the custom font loads, preventing invisible text (FOIT):

@font-face {
  font-display: swap;  // Always include this
}

5. Reduce Render-Blocking Resources

Inline Critical CSS

For the fastest possible First Contentful Paint, inline the CSS needed to render above-the-fold content:

<!-- In your <head> -->
<style>
  /* Critical CSS — only what's needed to render the visible part of the page */
  body { margin: 0; font-family: sans-serif; }
  .header { background: #fff; padding: 1rem 2rem; }
  /* etc. */
</style>
<!-- Load the rest asynchronously -->
<link rel="stylesheet" href="/assets/css/main.css" media="print" onload="this.media='all'">

Tools like Critical can extract critical CSS automatically.


6. Set Caching Headers

Static files don’t change — tell browsers to cache them aggressively.

On Netlify (netlify.toml):

[[headers]]
  for = "/assets/*"
  [headers.values]
    Cache-Control = "public, max-age=31536000, immutable"

[[headers]]
  for = "/*.html"
  [headers.values]
    Cache-Control = "public, max-age=0, must-revalidate"

On Cloudflare Pages, caching is configured automatically — static assets get long cache lifetimes, HTML files are always fresh.


7. Enable Compression

All major hosts (Cloudflare, Netlify, Vercel) compress responses with Brotli or gzip automatically. If self-hosting with Nginx:

gzip on;
gzip_types text/html text/css application/javascript image/svg+xml;
brotli on;
brotli_types text/html text/css application/javascript image/svg+xml;

Compression reduces HTML/CSS/JS transfer size by 60–80%.


Core Web Vitals Targets

Metric Target Common Cause of Failure
LCP (load) < 2.5s Unoptimised hero image
INP (interactivity) < 200ms Heavy JavaScript
CLS (stability) < 0.1 Images without dimensions, late-loading fonts

With a Jekyll static site on Cloudflare Pages, hitting green on all three is achievable with the optimisations above.


Looking for a fast, well-optimised Jekyll theme? All themes on JekyllHub are tested for performance — browse the collection and filter by your use case.

Share LinkedIn