Codeskill

Learn to code, step by step

Performance-minded markup

Markup choices that affect how fast a page feels and how much work the browser does before the user can read anything. Performance is often discussed in terms of images and JavaScript bundles, but HTML structure, resource hints, and loading attributes matter too.

Critical content first

Put the content users need to see early in the document. The main heading, primary text, and key call to action should not sit below kilobytes of navigation chrome, widget scripts, and tracking snippets. Use landmarks so the parser and assistive tech can find <main> quickly. Defer non-essential embeds to the bottom of <main> or load them lazily.

Images and media

You already know srcset and sizes from the intermediate tutorials. At this level, combine them with explicit dimensions and lazy loading for below-the-fold images:

<img src="hero-800.jpg"
     srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
     sizes="(min-width: 768px) 50vw, 100vw"
     width="800" height="450"
     alt="Workshop in progress"
     fetchpriority="high">

<img src="gallery-thumb.jpg"
     loading="lazy" decoding="async"
     width="320" height="240"
     alt="">

width and height reserve space so layout does not jump when images arrive. Use fetchpriority="high" sparingly on the LCP image. Use loading="lazy" on images the user may never scroll to – not on the hero. For video, prefer poster, preload="metadata", and do not autoplay with sound.

Scripts and styles in HTML

Blocking scripts in <head> delay rendering. Default to deferred scripts at the end of <body> unless you genuinely need synchronous execution:

<link rel="stylesheet" href="/css/main.css">
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>

<script src="/js/app.js" defer></script>
<script src="/js/analytics.js" async></script>

defer preserves order and runs after HTML is parsed. async runs when fetched – fine for independent snippets like analytics, risky for code that depends on DOM order. Preload only what you will use soon; over-preloading competes with real resources.

Resource hints

<link rel="preconnect" href="https://cdn.example.com" crossorigin>
<link rel="dns-prefetch" href="https://cdn.example.com">
<link rel="prefetch" href="/next-page.html" as="document">

preconnect opens early connections to critical third-party origins. prefetch is a low-priority fetch for likely next navigation – use it when you have evidence users go there often, not on every link.

DOM weight and markup smell

Deeply nested <div> soup increases memory and style recalculation cost. Prefer fewer, meaningful elements. Avoid duplicating hidden SEO paragraphs. Avoid enormous inline SVG when a referenced sprite or <img> would do. If a CMS outputs wrapper after wrapper, push back in the template layer.

Measuring, not guessing

Use Lighthouse, WebPageTest, or your browser’s Performance panel to see LCP, CLS, and total DOM nodes. Markup changes alone will not fix a two-megabyte hero image, but they can remove layout shift and shorten the path to readable content. Fix what the trace shows, not what blog posts guess at.

PreviousAccessible rich widgets – tabs, dialogs, menus (HTML+ARIA)