PLAINFINCH learn by building

Fewer, smaller requests

You will cut a page's requests by combining stylesheets, drawing icons inline and deleting unused files, then see what really helps.

Does the number of requests still matter?

Less than it used to. With HTTP/1.1, a browser opened about six connections per site and each could carry one request at a time, so a page with 60 small files waited in line. Developers combined everything into a few big files and packed icons into sprite sheets to work around it.

HTTP/2 and HTTP/3, which nearly every site uses in 2026, send many requests over one connection at the same time. A request for a 3 KB icon now costs little more than its bytes and a small header. The simulator works the same way: each site gets one shared connection and every file on it downloads in parallel, sharing the bandwidth by priority.

Requests still cost something, in two cases worth knowing. The first is when one request can only start after another finishes, because the browser found it late. The second is when the file should not be there at all. Both show up clearly in the Waterfall on the bike shop page.

Which requests on this page actually cost time?

The page makes 13 requests and the first paint happens at about 1.5 seconds. The eight icons are not the reason. They are low priority and finish at about 1.25 seconds, while the stylesheets are still loading, so the first paint never waits for them. On a page like this they add bytes but almost no waiting.

The cost is in the stylesheets. base.css starts with @import url(/css/layout.css), and layout.css starts with @import url(/css/buttons.css). The browser cannot know about the second file until the first arrives, or the third until the second arrives. Each link in the chain is a full round trip, 150 ms on this phone, plus server time, and the first paint waits for the last one.

Meanwhile christmas-2023.css blocks the first paint too. It is 34 KB of rules for a banner and falling snow that were removed after the holidays. The Waterfall marks it "blocks paint" like the others.

FigureWaterfall of the bike shop repairs page. base.css imports layout.css, which imports buttons.css, three trips in a row, so the first paint waits until 1.48 s. One linked shop.css paints at 1.03 s.Waterfall of the bike shop repairs page. base.css imports layout.css, which imports buttons.css, three trips in a row, so the first paint waits until 1.48 s. One linked shop.css paints at 1.03 s.
Each @import can only start when its parent sheet finishes, so the three stylesheets form a staircase. The icons finish early and never hold up the paint.

How do you combine stylesheets safely?

Put the rules from the chained files into one file, in the same order the imports would have applied them, and link that file from the HTML. The server already has /css/shop.css for this page, with every rule from base.css, layout.css and buttons.css. Order affects the result because later rules win over earlier ones of the same strength, so a combined file in the wrong order can change how the page looks.

Most build tools combine CSS for you, and many inline @import automatically. If you write CSS by hand, avoid @import in files that the page loads, or list each file with its own <link> in the HTML so the preload scanner finds them all at once.

Do not merge everything into one giant file for the whole site either. A stylesheet that holds the checkout, the blog and the hire calendar makes every page download rules it never uses. One shared file for the common look, plus a small file per kind of page, is a good balance.

<!-- Before: a chain of three, plus an unused theme -->
<link rel="stylesheet" href="/css/base.css">
<link rel="stylesheet" href="/css/christmas-2023.css">

<!-- After -->
<link rel="stylesheet" href="/css/shop.css">

When is inline SVG better than an icon file?

Small, simple icons are often a few hundred bytes as SVG markup. Placed inline in the HTML, they arrive with the page, draw at any size without blurring, and can take their colour from the text with fill="currentColor". There is nothing to request and nothing to wait for.

Inline SVG suits icons that appear once or twice and are small. It suits less well an icon repeated fifty times in a long list, where the same markup repeated adds up and cannot be cached separately. For those, an SVG file used by many <img> elements is downloaded once and cached, and with HTTP/2 the single request is cheap.

Decorative icons next to text need aria-hidden="true" so screen readers do not announce them. An icon that is the only content of a button needs a text alternative instead, such as aria-label on the button.

<li>
  <svg width="24" height="24" viewBox="0 0 24 24" aria-hidden="true">
    <circle cx="12" cy="12" r="9" fill="currentColor"/>
  </svg>
  Puncture repair
</li>

How do you find files nothing uses?

Start with names. Files called christmas-2023.css, old-slider.js or v2-backup.css are often leftovers. Search the HTML for the classes and ids they target. The Christmas sheet styles .xmas-banner and .snow, and neither appears on the page.

In Chrome DevTools, the Coverage panel shows how many bytes of each CSS and JavaScript file were used while you loaded and clicked through the page. A file at 100% unused is a candidate for deletion. Check other pages that load it before you remove it from a shared template.

Removing an unused file is the best fix there is. It saves the bytes, the request, any blocking and the work of reading it, and no build step is needed.

What changes in the waterfall when you finish?

After the change, the Waterfall has two rows: the HTML and shop.css. The page downloads about 13 KB instead of about 74 KB, and the first paint arrives at about 1 second instead of 1.5. Most of that improvement came from ending the stylesheet chain and dropping the blocking Christmas sheet.

Try it in two steps to see this for yourself. Fix the stylesheets first and watch the first paint move. With the stylesheets fixed, the first paint is at about 1.09 seconds. Then replace the icons: the request count falls from 10 to 2, and the first paint moves only another 60 ms or so, because the icons were sharing the connection rather than holding anything up. That is the honest picture of requests in 2026. Count them, and then ask which ones the page is waiting for.

Where does the simulator differ from a real browser?

The simulator gives each site one connection and lets every file on it download at once. That matches HTTP/2 closely. It does not model the small header cost of each request, or the limits some servers place on how many requests run at once on a connection, so a page with hundreds of tiny files would do a little worse in a real browser than here.

Real browsers also have an HTTP cache and a memory cache. A shared icon file used on every page is downloaded once and then reused, which favours separate files when the same icons appear across the site. The caching lessons cover that trade-off with the simulator's second visit view.

What does AI speed advice often get wrong here?

AI assistants still repeat advice from the HTTP/1.1 era: "reduce HTTP requests", "combine all CSS and JavaScript into one file", "use CSS sprites for icons". Some of it still helps, for the reasons above. Followed blindly, it produces one huge bundle per site and sprite sheets that are harder to maintain than separate SVG files, for little gain.

AI-written pages also tend to use @import to organise CSS, because it looks tidy, and to add icon libraries that download a whole font or a hundreds-of-icons file to show five icons. When you review that code, open the Waterfall and look for files that start only after another file finishes, and for files the page never uses. Those are the requests worth removing.

Field notes

  • Request count is less important with HTTP/2, but chains and blocking files still cost time.
  • Combine chained stylesheets into one file, keeping the same rule order.
  • Small icons can be inline SVG, with nothing extra to download.
  • Search the page for a file's classes to find leftovers nothing uses.

Easy to get wrong

The browser cannot find an imported file until the parent sheet has downloaded, so each import adds a full round trip before the first paint.

With HTTP/2, extra requests are cheap. A giant bundle makes every page download code and styles it does not use.

A linked stylesheet blocks the first paint whether or not any rule in it matches. Version control keeps the file safe for next year.

Questions people ask

Is HTTP/2 on my site already?

Almost certainly, if it uses HTTPS on a modern host. In Chrome DevTools, right-click the column headers in the Network panel and turn on Protocol. You will see h2 or h3 for each request.

Are icon fonts a good idea?

Usually not now. An icon font downloads every icon to show a few, can show empty boxes while it loads, and is harder for screen readers. Inline SVG or SVG files are simpler and more accessible.

Should I inline small images as data URLs?

Rarely. A data URL makes the image about a third bigger, cannot be cached on its own, and is re-downloaded with every page. Inline SVG markup is a better fit for tiny icons.

How many requests is too many?

There is no fixed limit with HTTP/2. Look at what the first paint and the largest paint are waiting for in the Waterfall. A hundred lazy requests below the fold matter less than one chained stylesheet in the head.

Keep going