HTML and CSS course Β· Module 11: Developer Tools
Performance Optimization - Speed of the Caravan
In this lesson6
In Ancient Egypt, the speed of material delivery determined the pace of pyramid construction. In web development, page loading speed determines whether a user will stay on the page or leave. According to a 2016 Google study, 53% of visits to mobile sites are abandoned if loading takes longer than 3 seconds. Every unnecessary byte is an extra camel in the caravan - the lighter the load, the faster it reaches its destination. You will learn three ways to slim down a page: minification, compression and lazy loading.
Minification - Compressing Hieroglyphs
Minification is the process of removing unnecessary characters from code (spaces, comments, new lines) without changing its functionality:
1/* BEFORE minification - readable version */
2body {
3 font-family: Georgia, serif;
4 max-width: 800px;
5 margin: 0 auto;
6 padding: 20px;
7 /* Sand-colored background */
8 background: #f5f1e3;
9}
10
11/* AFTER minification - optimized version */
12/* body{font-family:Georgia,serif;max-width:800px;margin:0 auto;padding:20px;background:#f5f1e3} */Both versions work identically, because the browser needs neither indentation nor comments. Only what helps a human disappears, which is why you always work on the readable version and let a tool generate the minified one when you publish.
Minification tools:
- cssnano - CSS minification
- Terser - JavaScript minification
- html-minifier - HTML minification
- Bundlers like Webpack or Vite do this automatically
Transfer Compression
Minification is easy to confuse with compression. Minification changes the file itself, while compression happens during transfer: the server packs text files (HTML, CSS, JS) with the gzip or Brotli algorithm, and the browser unpacks them on its own. You can see the algorithm used in the Network panel, in the Content-Encoding response header. The two techniques complement each other - the best result comes from a minified file sent compressed.
Image Compression
Images are usually the heaviest resources on a page. Image optimization is a key step:
Image Formats:
- JPEG - photos, gradient backgrounds (lossy compression)
- PNG - graphics with transparency, icons (lossless)
- WebP - modern format; according to Google, lossy WebP is 25-34% smaller than a comparable JPEG, and lossless WebP is 26% smaller than PNG
- AVIF - the newest of the popular formats, usually even smaller than WebP
- SVG - vector graphics, icons (scalable)
So, from the lightest to the heaviest, photos usually line up like this: AVIF, WebP, JPEG. Older browsers do not know the new formats, however, so you need a fallback plan.
The picture Element - Modern Approach:
The <picture> element lets you provide several versions of the same image and leave the choice to the browser:
1<picture>
2 <!-- The browser will choose the best format -->
3 <source srcset="pyramid.avif" type="image/avif">
4 <source srcset="pyramid.webp" type="image/webp">
5 <img src="pyramid.jpg" alt="The Great Pyramid of Giza"
6 width="800" height="600">
7</picture>The browser reads the <source> elements from the top and takes the first format it understands. If it knows none of them, it uses the <img> - that is the required fallback, and that is where alt, width and height stay. Always put the lightest format at the top.
Lazy Loading
Lazy loading delays the loading of images that are not visible on screen. This way the page loads faster:
1<!-- Images below the screen load only when scrolling -->
2<img src="sphinx.jpg" alt="The Great Sphinx" loading="lazy"
3 width="800" height="600">
4
5<!-- First image on the page - DO NOT use lazy loading -->
6<img src="hero.jpg" alt="Pyramids at sunset" loading="eager"
7 width="1200" height="600">loading="lazy" tells the browser to wait until the image gets close to the visible area, and loading="eager" (the default value) loads it right away. Do not delay the main image at the top of the page - it is usually the largest element of the first screen, and the time it takes to appear is measured by the LCP (Largest Contentful Paint) metric.
Width and Height Attributes
Always specify image dimensions - this prevents the page from "jumping" during loading (CLS - Cumulative Layout Shift):
1<!-- GOOD - the browser reserves space -->
2<img src="pyramid.jpg" alt="Pyramid" width="800" height="600">
3
4<!-- BAD - the page "jumps" during loading -->
5<img src="pyramid.jpg" alt="Pyramid">From the attributes, the browser calculates the image's aspect ratio and reserves space for it before the file arrives, so the text below does not jump. The dimensions do not block responsiveness: add max-width: 100% and height: auto in CSS, and the image will still scale. LCP and CLS are Core Web Vitals metrics, which you can measure with Lighthouse from the first lesson of this module.
My order: first dimensions and lazy loading, because those are two attributes with no cost at all, then modern formats in <picture>, and leave minification to tools. In the next lesson you will see that fonts have weight too - and learn to load them wisely.
Practice
Open the Network panel, scroll the page from the editor below and watch when the images with loading="lazy" are downloaded:
Code for this lesson: index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Performance Optimization</title>
7 <link rel="stylesheet" href="style.css">
8</head>
9<body>
10 <h1>Page Performance Optimization</h1>
11
12 <section>
13 <h2>Lazy loading of images</h2>
14 <p>Scroll down - images will load only
15 when they are visible on screen.</p>
16
17 <img src="https://placehold.co/600x300/d4af37/1a1a2e?text=Pyramid+1"
18 alt="Pyramid of Cheops" width="600" height="300"
19 loading="eager">
20 <p class="caption">Image 1: loading="eager" (loads immediately)</p>
21 </section>
22
23 <section>
24 <h2>Images with lazy loading</h2>
25
26 <img src="https://placehold.co/600x300/8b6914/f5f1e3?text=Pyramid+2"
27 alt="Pyramid of Khafre" width="600" height="300"
28 loading="lazy">
29 <p class="caption">Image 2: loading="lazy" (loads on scroll)</p>
30
31 <img src="https://placehold.co/600x300/3d2914/d4af37?text=Sphinx"
32 alt="Great Sphinx" width="600" height="300"
33 loading="lazy">
34 <p class="caption">Image 3: loading="lazy"</p>
35 </section>
36
37 <section>
38 <h2>Picture element - different formats</h2>
39 <picture>
40 <source srcset="https://placehold.co/600x300/1a1a2e/d4af37?text=WebP+Format"
41 type="image/webp">
42 <img src="https://placehold.co/600x300/1a1a2e/d4af37?text=JPEG+Fallback"
43 alt="Valley of the Kings" width="600" height="300"
44 loading="lazy">
45 </picture>
46 <p class="caption">The <picture> element with WebP format and a JPEG fallback</p>
47 </section>
48</body>
49</html>Remember: a fast page is a light caravan - without unnecessary bytes, it reaches its destination before the traveler has time to grow impatient.
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. What is CSS/JavaScript code minification?
2. Which optimization technique delays loading images that are not yet visible on screen?
These are 2 of 3 questions for this lesson. Solve the rest in the game.
Hands-on tasks in the game
- Code editor
Add loading, width, and height attributes to three images on the page.
- Vertical ordering
Arrange image formats from newest (smallest file size) to oldest (largest file size):
- Code editor
Replace the img element with a picture element containing two source elements (avif, webp) and img as a fallback.
- Click in order
How do you build a picture element with WebP format and a JPEG fallback?
- Horizontal ordering
What does an img with lazy loading and dimensions look like?