Stop the page from jumping around (CLS) and make it feel fast with reserved space, skeletons, and streaming.
Why: layout shift (the CLS you measured) happens when something loads late and pushes content that was already on screen — an image with no size, a banner inserted at the top, a font swap that changes text width. It’s jarring and causes mis-clicks. Note: the fix is always the same idea — reserve the space before the thing arrives.
Why: give every image, video, ad, or embed a known size so the browser holds its spot. The CSS aspect-ratio property reserves a shape even when you don’t know the exact pixels. Note: this is the #1 fix for a bad CLS score.
/* Holds a 16:9 box so the video doesn't shove content when it loads */
.video-embed {
aspect-ratio: 16 / 9;
width: 100%;
}Why: adding a cookie banner, promo bar, or "loaded" content above what the user is already reading shoves everything down — a guaranteed layout shift. Reserve its space ahead of time, or overlay it instead of pushing. Note: late-arriving content should never move content the user can already see.
Why: a blank screen feels broken; a skeleton (grey placeholder shapes) tells users content is coming and reserves the right space, so there’s no shift when real data arrives. This is "perceived performance" — feeling fast matters as much as being fast.
<!-- A placeholder card shown until the real data loads -->
<div class="card skeleton" aria-hidden="true">
<div class="skeleton-line"></div>
<div class="skeleton-line short"></div>
</div>
<style>
.skeleton-line { height: 12px; background: #e5e7eb; border-radius: 4px; }
.skeleton-line.short { width: 60%; }
</style>Why: instead of building the whole HTML page on the server and sending it all at once, streaming sends it in pieces as they’re ready — so users see the header and main content while slower parts (comments, recommendations) are still loading. Note: modern frameworks do this for you; the win is users see something sooner.