Web Performance

Zero to Hero: Achieving a Perfect 100 Lighthouse Score in Optimizely CMS 12

By Ginbok4 min read
Zero to Hero: Achieving a Perfect 100 Lighthouse Score in Optimizely CMS 12

In the world of Enterprise CMS, "performance" is often a checkbox that gets overlooked in the rush to ship features. Recently, I embarked on a mission to push an Optimizely CMS 12 site to its absolute limits—targeting a perfect 100 on Lighthouse and a Cumulative Layout Shift (CLS) of zero.

Here’s how we did it, and the technical strategies you can steal for your next project.

1. The "No-Font" Diet: System Font Stack

External font requests (like Google Fonts) are performance killers. They introduce extra DNS lookups and cause the dreaded Flash of Unstyled Text (FOUT).

We migrated to a Modern System Font Stack:

 
:root {
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
}

The result? Zero font-related network requests and instant text rendering.

2. CLS Zero: The Art of Space Reservation

Cumulative Layout Shift (CLS) is often caused by late-loading images or dynamic containers. We achieved a CLS of 0 by using "Locked Reservation" techniques.

Instead of letting the browser guess the size of our header or blog cards, we reserved exact pixels in our Critical CSS:

 
.page-header {
min-height: 180px; /* Locked reserved space */
text-align: center;
}

By defining these metrics in CSS that is inlined in the <head>, the page layout is "frozen" the moment the HTML arrives.

3. Breaking the Render Block: CSS & JS Defer

One of the biggest hurdles for FCP (First Contentful Paint) is render-blocking resources. If the browser stops to download a 200KB CSS file or a heavy JS bundle, your user sees a white screen.

We implemented a Non-Blocking Delivery Strategy:

JavaScript Deferment

We moved all non-essential scripts to use the defer attribute. Unlike asyncdefer ensures the script is downloaded in parallel but only executed after the HTML document has been fully parsed. This keeps the main thread free for rendering.

<script src="~/js/script.js" asp-append-version="true" defer></script>

CSS Preloading

For our main stylesheet, we used a high-performance pattern: we preload the style as a low-priority resource and switch its relation to stylesheet only once it's loaded. This prevents the browser from waiting on the file to start rendering the initial "Critical" HTML.

 
<link rel="preload" as="style" href="~/css/styles.css" asp-append-version="true" onload="this.onload=null;this.rel='stylesheet'"/>
<noscript><link rel="stylesheet" href="~/css/styles.css" asp-append-version="true"/></noscript>

4. Critical CSS Inlining

To make the site feel "instant," we split our styles into two categories:

By giving the browser the bare minimum CSS it needs to render the initial viewport, we achieved a near-zero FCP.

5. The Content Strategy: Adaptive Excerpts

For our blog listing, we realized that varying text lengths were causing subtle shifts between viewports. We implemented an Adaptive Excerpt strategy:

This ensured our "Read More" buttons always sat on the same vertical line, eliminating shifts during render.

6. Accessibility as a Performance Metric

Good performance is useless if your site isn't accessible. We audited all colors for WCAG AA compliance (darkening our primary blue to #0062af) and added proper ARIA labels to every interactive element.

Performance and Accessibility are two sides of the same coin: User Experience.

Key Takeaways

By focusing on these "micro-wins," we transformed a standard enterprise site into a high-performance benchmark. Performance isn't a one-time task—it's a mindset.

#core-web-vitals#performance#seo
← Back to Articles