How to Get a Perfect Lighthouse Score on Your Website

February 12, 2024 · 4 min read

Having a fast website is not just nice to have; it’s important for keeping users interested and building a strong online presence. If you use Statamic for your CMS, aiming for a great Lighthouse score is key. A higher score improves performance, user experience, and search engine visibility. Let’s go over the steps we took to improve a client’s Statamic site performance by 80% and how you can do the same for your site.
Upgrade to Statamic v5
Upgrading your site from an older Statamic version, like v2 or v3, to the latest version, Statamic v5, can seriously improve your site’s performance. Every new release brings improvements that can optimize your site’s speed and efficiency. This step alone can make a big difference in how your site works.
Optimize website elements for performance
Optimize Sliders
Originally, the site had custom JavaScript for several sliders, which was inconvenient and prone to accessibility issues. By switching to Swiffy Slider, we took advantage on its small bundle size and accessibility features. This switch made a clear difference in performance and user experience.
Lazy Load with Async Alpine
By bringing in Async Alpine, we’re lazy-loading Alpine.js components, so JavaScript only loads when it’s needed for content on a specific page. This method makes everything run smoother by cutting down on loading JavaScript we don’t need.
import AsyncAlpine from 'async-alpine';
import Alpine from 'Alpine.js';
AsyncAlpine
.init(Alpine)
.data(
'slider',
() => import('./components/Slider.js')
)
.start();
Alpine.start();The following code ensures the slider only loads when it’s within the user’s viewport.
<div
x-ignore
ax-load="visible"
x-data="slider"
></div>Upgrade and Localize JavaScript Libraries
We updated critical JavaScript libraries like Alpine.js to the latest version, v3, and shifted away from using CDN script imports. By installing Alpine.js and Axios directly on the site, we minimized external requests and improved loading times. We also served fonts locally using Font Source for an extra speed boost. Plus, we set up lazy loading for non-essential scripts like Google Analytics and Bing to give performance another lift.
Enhance Video Embeds
To optimize YouTube video embeds, we developed a custom Statamic Tag that only loads videos when someone clicks on them. This approach saves bandwidth and boosts page speed, which is a win for user experience. We wrote a blog post about how to Optimize Video Embeds with a Custom Statamic Tag and Alpine.js.

Accessibility and User Experience improvements
Accessible mobile menu
We made huge accessibility improvements to the mobile menu, improving users’ navigation and positively impacting Google PageSpeed scores. Make sure you are using the nav tag and the necessary aria attributes. Here is a sample menu:
<nav class="py-5 bg-transparent md:py-6 shadow-nav" aria-labelledby="nav-heading" :aria-expanded="isOpen"
@keydown.escape="isOpen = false" x-data="{ isOpen: false }" @click.outside="isOpen = false">
<div class="container">
<div class="flex flex-wrap items-center justify-between">
<div class="flex items-center shrink-0">
<a aria-label="logo" href="/">
{{ svg src="logo" }}
</a>
</div>
{{ partial:partials.toggle_button }}
<div class="w-full lg:flex lg:items-center lg:w-auto {{ $menu_classes }}"
:class="{ 'block shadow-3xl': isOpen, 'hidden': !isOpen }">
<ul
class="flex flex-col w-full px-3 mt-5 divide-y-2 lg:flex-row lg:items-center lg:divide-y-0 md:mt-0 lg:px-0 lg:py-0 lg:space-x-8">
{{ nav:navigation include_home="true" }}
{{ partial:components.menu_item }}
{{ /nav:navigation }}
</ul>
</div>
</div>
</div>
</nav>Responsive image component
We switched all images over to Statamic’s Responsive Image component. This move really helped our Cumulative Layout Shift (CLS) score by making sure images fit the device they’re on, which is super important for user experience. Here is a sample Picture component:
{{ if image }}
<picture>
{{ asset :url="image" }}
{{ if extension == 'svg' || extension == 'gif' }}
<img class="{{ class }}" src="{{ url }}" alt="{{ alt }}" />
{{ else }}
<source
srcset="
{{ glide:url preset='xs-webp' }} 320w,
{{ glide:url preset='sm-webp' }} 480w,
{{ glide:url preset='md-webp' }} 768w,
{{ glide:url preset='lg-webp' }} 1280w,
{{ glide:url preset='xl-webp' }} 1440w,
{{ glide:url preset='2xl-webp' }} 1680w"
sizes="{{ sizes }}"
type="image/webp"
>
<source
srcset="
{{ glide:url preset='xs' }} 320w,
{{ glide:url preset='sm' }} 480w,
{{ glide:url preset='md' }} 768w,
{{ glide:url preset='lg' }} 1280w,
{{ glide:url preset='xl' }} 1440w,
{{ glide:url preset='2xl' }} 1680w"
sizes="{{ sizes }}"
type="{{ image.mime_type }}"
>
<img
{{ if cover }}
class="object-cover w-full h-full {{ class }}"
style="object-position: {{ focus | background_position }}"
{{ else }}
class="{{ class }}"
{{ /if }}
src="{{ glide:url preset='lg' }}"
alt="{{ alt ensure_right='.' }}"
{{ if lazy }}
loading="lazy"
{{ /if }}
>
{{ /if }}
{{ /asset }}
</picture>
{{ /if }}Cloud Services and Server Configurations
Using Cloudflare
By implementing services like Cloudflare, we were able to take advantage of its huge network to speed up response times. Cloudflare also adds an extra layer of security against malicious attacks, ensuring your site remains secure and reliable.
Statamic Static Caching
Whenever possible, we use full Static Caching on our Statamic sites. This approach minimizes server load, as every response is served as static HTML, enhancing speed and reliability.
Optimize NGINX configuration
Optimizing your server’s NGINX configuration to cache images and fonts can lead to a drastic reduction in load times. Effective caching strategies decrease the number of HTTP requests required, facilitating faster delivery of content to your audience. Here is a sample nginx config we use in our projects along with Static Caching:
# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/example.com/before/*;
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com;
server_tokens off;
root /home/forge/example.com/public;
# Expires
expires $expires;
index index.html index.htm index.php;
charset utf-8;
# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/example.com/server/*;
location / {
try_files /static${uri}_${args}.html $uri /index.php?$args;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/example.com-error.log error;
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
map $sent_http_content_type $expires {
default off;
text/css max;
~image/ max;
application/javascript max;
application/octet-stream max;
application/font-woff max;
application/font-woff2 max;
application/font-ttf max;
font/woff2 max;
}
# FORGE CONFIG (DO NOT REMOVE!)
include forge-conf/example.com/after/*;Conclusion
By carefully using these strategies, we greatly improved our client’s site performance. Remember that getting that perfect Lighthouse score is an ongoing process – it needs regular checks and updates. With these tips, you’re ready to start improving your Statamic site for better speed, efficiency, and a great user experience.
Bring Your Ideas to Life 🚀
Kickstart Your Statamic Project with the #1 Statamic Agency
Are you planning a new Statamic project or thinking about migrating your WordPress site to Statamic? Learn more about our expertise as a renowned Statamic development agency.
Technologies

Stay up-to-date
Be updated with all news, products and tips we share!
On this page

