Faster Pages with HTML

Make pages load faster with HTML alone: lazy-load images and iframes, set image sizes to stop layout shifts, preload key files, preconnect to other servers and load scripts without blocking.

Lesson 41 of 44Intermediate15 min read

Speed is a feature. Visitors leave slow sites, especially on phones, and search engines include page experience in their rankings through Core Web Vitals: how quickly the main content appears (LCP, Largest Contentful Paint), how quickly the page responds to taps and clicks (INP, Interaction to Next Paint) and how much the layout jumps around while loading (CLS, Cumulative Layout Shift).

Many of the biggest improvements need only HTML attributes. Telling the browser an image's size stops text jumping when it loads. Marking images below the fold as lazy stops them competing with what's on screen. Preloading the hero image or a key font makes the first view appear sooner. Preconnecting to another server saves time before its files are requested.

In this lesson you'll learn these techniques, when each helps and when it backfires, and how to measure the difference with browser tools such as Lighthouse and PageSpeed Insights.

Images and iframes

HTML
<img src="hero.jpg" alt="..." width="1200" height="600" fetchpriority="high">
<img src="gallery-5.jpg" alt="..." width="400" height="300" loading="lazy" decoding="async">
<iframe src="..." title="..." loading="lazy"></iframe>
  • width and height let the browser reserve space before the image arrives, preventing layout shift. CSS can still resize it with max-width: 100%; height: auto;.
  • loading="lazy" delays images and iframes until they're near the screen. Never lazy-load the main image at the top of the page.
  • fetchpriority="high" tells the browser that an image, usually the hero or LCP image, is the most important download.
  • Use modern formats such as WebP and AVIF with <picture>, and responsive srcset, covered in the responsive images lesson.

Resource hints

HintDoesUse for
<link rel="preload" href="..." as="...">Downloads a file early, at high priorityThe hero image, a key font, critical CSS
<link rel="preconnect" href="https://...">Opens the connection to a server earlyFont, image or API servers you'll use soon
<link rel="dns-prefetch" href="...">Looks up a server's address earlyLighter version of preconnect
<link rel="prefetch" href="...">Downloads a file at low priority for the next pageThe page a user will probably visit next

Preload only one or two truly critical files. Preloading everything means nothing is prioritised, and it slows the page down.

Scripts, styles and measuring

  • Load scripts with defer or async so they don't block the page, as in the scripts lesson.
  • Keep CSS in a few files in the <head>; CSS is needed before the page can be shown, so smaller is faster.
  • Every font file, third-party widget and tracking script adds weight. Ask whether each one earns its place.
  • Measure: run Lighthouse in Chrome DevTools, check PageSpeed Insights for real-user data, and watch the Network panel to see what loads and when.

HTML Performance Syntax

Performance attributes

<link rel="preconnect" href="https://fonts.example.com" crossorigin>
<link rel="preload" href="/img/hero.webp" as="image" fetchpriority="high">
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
<img src="/img/hero.webp" alt="..." width="1200" height="630" fetchpriority="high">
<img src="/img/photo.webp" alt="..." width="600" height="400" loading="lazy" decoding="async">
<iframe src="..." title="..." loading="lazy"></iframe>
<script src="/js/app.js" defer></script>

HTML Performance Summary

  • Core Web Vitals measure loading (LCP), responsiveness (INP) and visual stability (CLS).
  • Always set image width and height to prevent layout shift.
  • Lazy-load images and iframes below the fold, never the hero image.
  • Use fetchpriority="high" and preload sparingly for the most important files.
  • Preconnect to servers you'll need soon, defer scripts, and measure with Lighthouse.

HTML Performance Examples

Each example runs in the page. Edit the code and press Run to see what changes.

Example 1

Reserving space to stop layout shift

<style>
  img { max-width: 100%; height: auto; display: block; background: #e5e7eb; }
</style>
<h3>Without size attributes the text below would jump when the photo loads.</h3>
<img src="https://picsum.photos/seed/speed/600/300" alt="Mountains under a clear sky" width="600" height="300">
<p>This paragraph stays put, because the browser reserved a 2:1 space for the image before it arrived.</p>
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 2Images shrink to fit small screens while keeping their shape.
  2. Line 5width and height give the browser the image's proportions in advance.
  3. Line 6The text below doesn't move when the image finishes loading.
Example 2

Lazy loading a long gallery

<style>.gallery img { width: 100%; max-width: 300px; height: auto; margin: 6px 0; display: block; }</style>
<div class="gallery">
  <img src="https://picsum.photos/seed/g1/300/200" alt="Gallery photo 1" width="300" height="200" fetchpriority="high">
  <img src="https://picsum.photos/seed/g2/300/200" alt="Gallery photo 2" width="300" height="200" loading="lazy">
  <img src="https://picsum.photos/seed/g3/300/200" alt="Gallery photo 3" width="300" height="200" loading="lazy">
  <img src="https://picsum.photos/seed/g4/300/200" alt="Gallery photo 4" width="300" height="200" loading="lazy">
  <img src="https://picsum.photos/seed/g5/300/200" alt="Gallery photo 5" width="300" height="200" loading="lazy">
</div>
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 3The first, visible image loads immediately with high priority.
  2. Lines 4 to 7Later images load only as the visitor scrolls towards them, saving data on mobile.
Example 3

A fast head section

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Coffee Beans | Codevra Roasters</title>
  <link rel="preconnect" href="https://images.example-cdn.com">
  <link rel="preload" href="https://images.example-cdn.com/hero.webp" as="image" fetchpriority="high">
  <link rel="stylesheet" href="/css/site.css">
  <script src="/js/app.js" defer></script>
  <script src="https://analytics.example.com/a.js" async></script>
</head>
ResultEdit the code, then press Run or Ctrl+Enter
Line-by-line explanation
  1. Line 5The connection to the image server starts straight away.
  2. Line 6The hero image, the largest thing on screen, downloads early.
  3. Line 7A single style sheet in the head.
  4. Lines 8 to 9Scripts don't block the page: deferred for the app, async for analytics.

Common HTML Performance Mistakes

Lazy-loading the hero image

Don't
<img src="hero.jpg" alt="Our bakery" loading="lazy">
Do
<img src="hero.jpg" alt="Our bakery" width="1200" height="600" fetchpriority="high">

Lazy-loading the first image delays the most important content on the page.

Images without dimensions

Don't
<img src="product.jpg" alt="Desk lamp">
Do
<img src="product.jpg" alt="Desk lamp" width="800" height="800">

Without dimensions, the page jumps when the image loads, hurting CLS.

Preloading everything

Don't
<link rel="preload" href="a.jpg" as="image">
<link rel="preload" href="b.jpg" as="image">
<link rel="preload" href="c.jpg" as="image">
<link rel="preload" href="d.jpg" as="image">
Do
<link rel="preload" href="hero.jpg" as="image">

When everything is a priority, nothing is.

HTML Performance in Real Projects

Speed in practice

News sites, shops and travel sites watch Core Web Vitals in Google Search Console, because slow pages lose both rankings and sales. Image CDNs serve WebP and AVIF automatically, frameworks add fetchpriority and lazy loading by default, and teams run Lighthouse in their release checks so a heavy new image or script is caught before it reaches visitors.

HTML Performance Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Fill in the blankseasy

Delay loading an image that's far down the page.

<img src="footer-map.png" alt="Map" width="600" height="300" loading="">
Multiple choiceeasy

What do width and height attributes on an image prevent?

Multiple choicemedium

Which image should get fetchpriority="high"?

Multiple choicemedium

What does rel="preconnect" do?

Fix the bugmedium

Fix the images: the hero (first) image must not be lazy and should have high priority, and the second image needs width and height (400 by 300) and lazy loading.

<img class="hero" src="https://picsum.photos/seed/h/800/400" alt="Hero" width="800" height="400" loading="lazy">
<img class="second" src="https://picsum.photos/seed/s/400/300" alt="Second">
ResultEdit the code, then press Run or Ctrl+Enter
Checks
  • Hero is not lazy and has high priority
  • Second image has dimensions
  • Second image is lazy

HTML Performance Quiz

5 questions to check what you learned.

  1. What does CLS measure?

    • Load time
    • Server speed
    • Image quality
    • How much the layout jumps around while loading
  2. What does LCP measure?

    • The number of links
    • How long the largest visible element takes to appear
    • Code length
    • Colour contrast
  3. Which tool can audit a page's performance in Chrome?

    • View source
    • The address bar
    • Lighthouse in DevTools
    • Print preview
  4. Why is preloading many files a bad idea?

    • It removes the priority benefit and competes with critical downloads
    • Preload is deprecated
    • Browsers ignore more than one
    • It breaks images
  5. What does decoding="async" on an image suggest?

    • Download later
    • Lower quality
    • The browser may decode the image off the main thread so it doesn't hold up other work
    • Convert the format

HTML Performance Challenge

A fast product section

Create:

  1. A hero <img> with width, height and fetchpriority="high"
  2. Two more images with width, height and loading="lazy"
  3. A <link rel="preconnect"> to https://picsum.photos
ResultEdit the code, then press Run or Ctrl+Enter
Checks
  • Preconnect to picsum
  • Hero image has high priority and dimensions
  • Two lazy images with dimensions