Optimizing HTTP Requests in 1C-Bitrix
During Bitrix project audits we regularly encounter pages with 180–250 HTTP requests on load. This is no exaggeration: each component can add 2–4 CSS files and 3–5 JS files, plus icons as separate PNGs, plus analytics trackers, plus widgets. Each request means DNS, TCP, TLS, response headers. With HTTP/1.1 the browser holds 6 parallel connections per domain. HTTP/2 multiplexing helps but does not eliminate overhead entirely. With over 10 years of Bitrix development experience, we see that clients often have no idea how many extra requests a typical template generates. We can audit and reduce requests by a factor of 2–3, saving your site maintenance budget. The cost of optimization is calculated individually based on scope.
Audit of the Current State
The first step is to measure, not guess. Tools:
- Chrome DevTools → Network: look at Requests, Transferred, DOMContentLoaded, Load columns
- WebPageTest — waterfall grouped by type
- Lighthouse: metrics "Serve static assets with an efficient cache policy" + "Avoid chaining critical requests"
A typical waterfall: HTML → CSS (×5) → fonts (×6) → JS (×8) → images (×40+) → component Ajax requests (×3–5). We analyze each chain and find reduction points. We guarantee that after optimization the request count will not exceed 100 for a typical catalog.
How to Merge CSS and JS Without Losing Functionality?
Built-in Bitrix Combiner
In the main module settings (/bitrix/admin/settings.php?lang=en) there are options "Combine CSS files" and "Combine JS files". The combiner merges files into one request /bitrix/cache/css/[hash].css. It works but has nuances:
- It merges only files from
AddCSS()/AddHeadScript(), not inline component styles. - Cache invalidation (editing any file) changes the hash — browsers download anew.
- It does not minify CSS/JS — only concatenation.
Webpack/Vite for Custom Resources
For your own code (not Bitrix kernel) we configure a bundler:
// vite.config.js export default { build: { rollupOptions: { input: { main: 'local/templates/main/src/main.js', catalog: 'local/templates/main/src/catalog.js', } } } } We get 2 bundles instead of 15+ separate files. Splitting into main and catalog is important: don't load catalog JS on static pages.
How to Reduce Icon Requests with SVG Sprites?
Each icon as a separate file is the fastest way to get 30–50 extra requests. CSS sprites (one large image) reduce requests by 40 times compared to individual PNGs. In practice, SVG sprites are better:
<!-- sprite.svg --> <svg xmlns="http://www.w3.org/2000/svg"> <symbol id="icon-cart" viewBox="0 0 24 24">...</symbol> <symbol id="icon-search" viewBox="0 0 24 24">...</symbol> </svg> <!-- usage --> <svg><use href="/local/templates/main/img/sprite.svg#icon-cart"></use></svg> One HTTP request for the entire site iconography. Cached long-term. Inline SVG via PHP helper gives 0 requests but increases HTML size. The choice depends on the number of first-screen icons.
Why Do Component Ajax Requests Slow Down Loading?
Bitrix components with 'AJAX_MODE' => 'Y' make a separate XHR when navigating catalog pages. That's normal, but during page initialization we often see several parallel Ajax requests to ajax.php with different parameters. The solution is batching: combine multiple requests into one via a queue:
// Accumulate requests for 50 ms, then send batch const queue = []; function batchRequest(params) { queue.push(params); if (queue.length === 1) { setTimeout(() => { const batch = [...queue]; queue.length = 0; fetch('/api/batch', { method: 'POST', body: JSON.stringify(batch) }); }, 50); } } On the server side — an endpoint /api/batch that dispatches requests and returns an array of responses. Certified Bitrix specialists ensure correct integration.
Images: Lazy Loading and Sprites
Catalog images are the largest source of requests. Minimal requirement:
// In catalog.element component template echo '<img src="' . $arItem['PREVIEW_PICTURE']['SRC'] . '" loading="lazy" width="' . $arItem['PREVIEW_PICTURE']['WIDTH'] . '" height="' . $arItem['PREVIEW_PICTURE']['HEIGHT'] . '" alt="' . htmlspecialchars($arItem['NAME']) . '">'; loading="lazy" is native lazy loading. The browser does not request images below viewport until scrolling. On a catalog page with 48 product cards, this removes 30–40 requests from the critical path.
How to Measure Optimization Results?
We use metrics: total request count, Load Time, and LCP. A practical example: an electronics online store on Bitrix. Home page: 214 HTTP requests, Load time 8.3 s. After our actions: enabling CSS/JS combiner, SVG sprite of 64 icons, loading="lazy" for below-the-fold images, deferring trackers, merging custom JS via Vite. Result: 214 → 88 requests, Load time: 8.3 s → 3.1 s, LCP: 5.2 s → 1.9 s.
| Metric | Before | After |
|---|---|---|
| Number of HTTP requests | 214 | 88 |
| Load Time | 8.3 s | 3.1 s |
| LCP | 5.2 s | 1.9 s |
| CSS files | 12 | 2 |
| JS files | 15 | 3 |
According to Wikipedia, reducing requests is critical for mobile networks.
What Is Included in the Work?
- Audit of current request count and load waterfall.
- Enabling the built-in combiner, cache configuration.
- Building an SVG sprite and replacing icons.
- Configuring Vite/Webpack for custom resources.
- Implementing a batch mechanism for Ajax.
- Adding
loading="lazy"and image optimization. - Deploying HTTP/2 Push (example Nginx config:
add_header Link "...";). - Documentation of results, training your team.
- 1 month of support after optimization.
| Scope | Composition | Timeline |
|---|---|---|
| Basic | Combiner, lazy loading, defer trackers | 1–2 days |
| Medium | SVG sprite, Vite bundling of custom code, HTTP/2 | 4–7 days |
| Full | Batch API for Ajax, full audit and elimination of all redundant requests | 8–14 days |
Contact us to start optimizing your site. Order an audit and get personalized recommendations. We guarantee results, enshrined in the contract.

