Your caching plugin has a “combine CSS” checkbox. You tick it, and the menu breaks. An older blog post insists you must reduce HTTP requests by merging every file into one, someone in a forum says request counts stopped mattering with HTTP/2, and meanwhile the speed report counts well over a hundred requests on your home page.
Each of them is partly right. The advice to reduce HTTP requests is older than most current websites, and the reasons behind it have changed. Some requests still cost real time. Others barely matter. This post explains how to count them, why the old rules changed, which requests are worth cutting, and how to cut them without breaking the site.
What a request actually is
Every file a page needs is a separate request: the browser asks a server for it, waits for the answer, and downloads it. The HTML page is the first request. Then every stylesheet, script, image, font, icon, video file and tracking pixel referenced by that page, or by files it loads, adds one more. A tag manager loading five other tools adds those five. A chat widget may add a dozen of its own.
Request count and page weight are related but separate. Weight is how much data comes down in total; we cover it in our post on what page weight is made of. Request count is how many separate trips it takes. A page can be light but chatty, or heavy with only a few large files.
How to count requests on your own pages
- Chrome DevTools: the Network panel counts requests for you in its bottom bar after a reload. Switch off the browser cache in that panel first, so you see what a first-time visitor downloads, and show the Domain column so each row tells you which server sent it.
- GTmetrix and WebPageTest: both show a total request count and a waterfall listing every request, usually with a breakdown by type.
- PageSpeed Insights or Lighthouse: the detailed report lists network requests; the main view focuses on what affects the metrics, which is a useful hint about which requests matter.
Count with the same tool and settings each time, because the number moves between runs when ads or third-party widgets are involved. Our guide on how to test website speed with a fair method explains why that consistency matters.
Why the old advice to reduce HTTP requests changed
Under HTTP/1.1, the version of the web’s protocol that dominated for many years, browsers could only download a small number of files at once from each server, and each connection handled one request at a time. Every extra file risked waiting in a queue. So developers combined all CSS into one file, all JavaScript into another, merged small icons into one image (a “sprite”), and even spread files across several domains to get more parallel connections.
HTTP/2, now supported by all mainstream browsers and most hosts and CDNs, lets many requests share a single connection at the same time. Small files no longer queue up in the same way, so a page with many small files is not penalised as heavily as before. Spreading files across extra domains became counter-productive, because each domain needs its own connection. What HTTP/2 and HTTP/3 change in more detail, and how to check which your site uses, is covered in HTTP/2 versus HTTP/3.
What did not change: every request still has some overhead, every request to a new domain still needs a connection set up first, and some requests still block the page from appearing. So the modern advice is not “fewer requests at any cost”. It is “fewer of the requests that hold things up”.
Requests that matter most
Requests that block the first view
Stylesheets in the page head, and scripts loaded there without async or defer, must be downloaded and processed before the browser shows the page. Ten of these in a row delay the first paint far more than fifty lazy-loaded images further down the page. When you look at a request list, start with what loads before anything appears.
Requests to new domains
Each new domain (a font service, an analytics tool, a review widget, a map) typically needs a DNS lookup, a connection and a secure handshake before its first file arrives. On a mobile connection those steps add up. Ten requests from your own domain usually cost less than ten requests spread over ten different services.
Chains of requests
Some files only start loading after another file has arrived and run. A tag manager loads, then loads an analytics script, which then sends its own requests. A stylesheet loads, then asks for a font, which then downloads. Long chains are slow because each link waits for the one before. Waterfall charts make these visible as a staircase.
Requests on the path to the main content
If the biggest element at the top of the page is an image, its request, and anything it waits for, directly affects Largest Contentful Paint. That request deserves priority over everything else.
Requests that matter less
- Lazy-loaded images below the fold, which only load as the visitor scrolls.
- Scripts loaded with defer or async, or after the page has loaded, as long as they do not tie up the visitor’s device when they do run.
- Files served from your own domain over HTTP/2, which share a connection already open.
- Cached files on repeat visits, which a returning visitor’s browser does not need to fetch again if caching headers are set sensibly.
That does not make them free, but cutting them should not be your first job.
Practical ways to cut requests that count
Remove what nobody uses
The best request is one that does not happen. Go through your plugins and widgets and ask what each one loads on the front end. A social sharing plugin on pages nobody shares, a slider used on one page but loading on all of them, an old popup tool, a second analytics tag left over from an agency years ago. Removing them removes their requests completely.
Load plugin files only where they are needed
Many plugins load their scripts and styles on every page, even if they only work on one: a contact form plugin on the contact page, a booking plugin on the booking page. Performance plugins such as Perfmatters, and some caching plugins, include script managers that let you switch assets off per page. Test carefully after each change.
Review third-party tools
Third-party scripts are often the biggest source of requests and new domains. Keep a list of every outside tool on the site, who added it and why, and remove the ones nobody can justify. For the ones you keep, loading them later or only on relevant pages helps. This topic gets its own post: third-party scripts that slow a website down.
Replace heavy embeds with lighter stand-ins
An embedded video player, map or social feed brings many requests before anyone interacts with it. A preview image that loads the real player or map only when clicked removes those requests for everyone who never clicks.
Trim fonts and icons
Use fewer font families and fewer weights. Replace a whole icon font with the handful of SVG icons you actually use. Each change removes files and, where fonts come from an outside service, possibly a domain.
Switch off small defaults you do not need
WordPress loads a small script for emoji support on the front end by default, and themes or plugins often add extra stylesheets for features you never switched on. Many performance plugins let you disable these. They are minor individually, which is exactly why they pile up unnoticed.
Be careful with “combine files”
Combining CSS or JavaScript into one file used to be standard. Under HTTP/2 the gain is often small, and combining JavaScript in particular is a common cause of broken menus, sliders and forms, because scripts end up in the wrong order. If you try it, test the important pages and interactions afterwards, and be ready to switch it off.
Measure the result
Note the request count, the number of outside domains and the time to first paint before you start. After each change, retest the same pages with the same settings. A lower request count is satisfying, but the real check is whether the page appears sooner and responds faster. If you remove thirty lazy-loaded thumbnails and nothing else changes, the count drops and the visitor notices nothing. If you remove two blocking scripts from the head, the count barely moves and the page appears noticeably sooner. For how this fits into speed work as a whole, see our guide to improving website speed. Judge each cut by the page, not by the counter.
Frequently asked questions
How many HTTP requests is too many?
There is no fixed limit that applies to every site. A page with many small, lazy-loaded images can load quickly, while a page with fewer requests can be slow if several of them block the first view or come from many outside domains. Look at which requests load before the page appears rather than chasing a total.
Does HTTP/2 mean I can ignore the number of requests?
Not entirely. HTTP/2 removed much of the penalty for having many small files from the same server, because they can share one connection. But requests to new domains still need their own connections, blocking files still delay the page, and every request carries some overhead. Cutting unnecessary requests is still worthwhile, just with different priorities.
Why does my request count change every time I test?
Ads, tag managers, chat widgets and other third-party tools can load different files on each visit, depending on what they decide to show and how quickly they respond. Some tools also stop counting at different points in the load. Compare counts from the same tool and settings, and focus on your own files and on the outside domains you control.
Should I put all my JavaScript into one file?
Usually not as a first step. Under HTTP/2, combining scripts brings a smaller benefit than it used to, and it often breaks features because scripts load in the wrong order or depend on each other. Removing unused scripts and loading the rest only where needed tends to help more, with less risk.
If your request list is long and you are not sure which plugins and tags can safely go, our website speed optimisation service begins with an audit of what loads, gives you a prioritised list of what to remove, and makes changes only with your approval. It starts at ₹2,499 onwards.