How We Hit 99 on Lighthouse Without Sacrificing Design
Most theme developers treat performance as a checkbox. We treat it as a design constraint from day one. Here is how.
When we started building Lumen, we set a non-negotiable: 99 on Lighthouse, out of the box, on a fully-designed store with real content. Not a demo store with three products and no apps -- a realistic merchant setup. That constraint shaped every technical decision we made.
The font problem
Custom web fonts are one of the biggest Lighthouse killers. Our solution: preload the most critical font file, use font-display: swap to prevent invisible text during load, and limit the font stack to two weights of a single family. We also host fonts locally via next/font rather than pulling from Google Fonts at runtime -- this eliminates an extra DNS lookup and network round-trip on every page load.
Performance is not a feature you add at the end. It is a constraint you design around from the first wireframe.
Images and layout shift
Cumulative Layout Shift (CLS) is often caused by images loading without explicit dimensions. We enforce explicit width and height on every image in the theme, which allows the browser to reserve space before the image loads. We also lazy-load everything below the fold using the native loading="lazy" attribute, and we serve WebP with JPEG fallback for every product image via Shopify's image transformation pipeline.
JavaScript discipline
Every JavaScript interaction in our themes is defer-loaded. The initial page render contains zero render-blocking scripts. We use intersection observers for scroll effects rather than scroll event listeners, and we avoid global state management frameworks. The result is a Time to Interactive under 2 seconds on a mid-range mobile device on a 4G connection -- the real test that Lighthouse is approximating.
More from the blog
Ready to convert more?
Stop leaving revenue on the table.
Your theme is the highest-leverage conversion tool you have.


