Two frontend techniques deliver outsized Magento performance wins for modest effort: lazy loading (do not load what is not visible) and critical CSS (inline what the first paint needs, defer the rest). Both fight the platform’s defaults in specific ways worth understanding before you flip the switches.
Lazy Loading Images
Modern browsers make the basics free: loading="lazy" on <img>. Magento 2.4+ themes add this to product images, but audit your actual theme - custom templates and older overrides often lack it. The rules:
- Everything below the fold lazy-loads: product grids, banners, footer imagery
- The LCP image never lazy-loads: lazy-loading your hero is a classic self-own - it delays the very metric you are protecting.
loading="eager"plusfetchpriority="high"and a preload hint for that one - Background images need a JS lazyloader (the
loadingattribute does not apply); swapdata-bgforbackground-imageon intersection, or convert key backgrounds to real<img>elements where semantics allow
Iframes too: YouTube embeds and maps below the fold get loading="lazy" for free wins.
Lazy Loading JavaScript
The heavier half of the problem on Luma. Practical moves:
- Defer non-critical widgets (sliders, carousels, marketing popups) behind
IntersectionObserveror first interaction - Audit RequireJS deps that eagerly load heavy modules on every page (see our RequireJS post for the mechanics)
- Gate third-party scripts behind consent and visibility where lawful and sensible
Critical CSS
Magento’s full stylesheet is hundreds of KB; the browser blocks first paint on all of it. Critical CSS inlines the small subset needed for the initial viewport and defers the rest:
The pipeline: extract above-the-fold CSS per page type (home, category, product, checkout) with a tool (critical, penthouse), output per-template <style> blocks, and load the full CSS asynchronously:
<style>/* inlined critical rules */</style>
<link rel="preload" href="/static/.../styles.css" as="style" onload="this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="/static/.../styles.css"></noscript>
Magento specifics that bite:
- Per-page-type critical CSS is essential - one global critical file either misses category-page layout (CLS) or bloats the homepage with checkout CSS
- Regenerate on every theme change - stale critical CSS after a header redesign is a layout-shift generator
- Font loading is part of the critical path: inline
font-display: swapdeclarations and preload the primary webfont
Measuring the Win
Before/after on WebPageTest filmstrips and field LCP: lazy loading primarily saves bandwidth and speeds long pages; critical CSS cuts first paint, sometimes dramatically on slow connections. Together they routinely move LCP from “needs improvement” into “good” without touching the server.
Neither technique is exotic - but on Magento they interact with theme inheritance and static deploy in ways that reward care. Implement per page type, verify visually across breakpoints, and regenerate on change. That discipline is the whole job.