Combining CSS and JS files in 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

CSS and JS File Bundling for 1C-Bitrix

On a project developed over several years by multiple teams, a typical situation arises: every module, every component, every widget includes its own CSS and JS files. Chrome DevTools → Network shows 60–120 requests for stylesheets and scripts alone. Even with HTTP/2 (which theoretically multiplexes requests), this creates overhead: DNS lookups, TCP handshakes, TLS negotiation for each domain, and request prioritization. On mobile networks, 100 small requests are always worse than 5 large ones.

Bitrix Built-in Bundling Mechanism

Bitrix provides two tools for file bundling: via CMain::AddCSSLink() / CMain::AddHeadScript() with minification enabled (Settings → Performance → Compression), and via the bitrix:main.include component with bundling parameters.

With minification enabled, Bitrix groups CSS into one file /bitrix/cache/css/<hash>.css and JS into /bitrix/cache/js/<hash>.js. The key limitation: only files registered through the PHP API before ShowHead() is called are bundled. Files included directly via <link> in templates will not be part of the bundle.

Problems and Solutions

Include order. Bundling changes the order of CSS rules, which breaks styles that rely on cascade specificity. Solution: explicitly control order via \Bitrix\Main\Page\Asset::addCss() with priorities, or split into two bundles — "base" (reset, grid, typography) and "component".

Inline styles and scripts. Many Bitrix components output <style> and <script> tags directly into HTML — these are not bundled automatically. For custom components, move them to files via $this->addExternalCSS() and $this->addExternalJS().

Conditional loading. Some scripts are only needed on specific pages (form editor, homepage slider, contact page map). Bundling everything into one file increases its size. The right approach: split into a critical bundle (loaded everywhere) and page-specific bundles (loaded conditionally).

Webpack/Vite as an Alternative to Built-in Tools

For projects with active frontend development, Bitrix's built-in bundler is not enough. The modern approach is to build via Webpack or Vite with a dedicated webpack.config.js for the Bitrix template. Benefits: tree shaking (removal of unused code), code splitting, SCSS/LESS processing, TypeScript transpilation.

Example structure for Vite + Bitrix template:

local/templates/mytemplate/
├── src/
│   ├── css/
│   │   ├── main.scss
│   │   └── components/
│   ├── js/
│   │   ├── app.js
│   │   └── pages/
├── dist/       ← Vite build output
│   ├── app.[hash].css
│   └── app.[hash].js
├── header.php  ← loads from dist/
└── vite.config.js

header.php includes files from dist/ via CMain::AddCSSLink() — so they participate in Bitrix's standard caching mechanism.

Case Study: Portal with Multiple Development Teams

A B2B portal, 5 years in development, three different teams. On the catalog page: 47 CSS requests (890 KB uncompressed), 68 JS requests (1.4 MB). Audit revealed: 12 CSS files were duplicated (the same normalizers included in different components), 8 JS libraries loaded in multiple versions simultaneously (jQuery 1.9, 2.1, and 3.6 on the same page).

What was done:

  • Audit of all includes by intercepting CMain::AddCSSLink() and AddHeadScript() with logging
  • Library unification: single jQuery version, removal of duplicates
  • Migration of all direct <link> tags to the Bitrix API
  • Vite build configuration for new code, legacy packaged into a single bundle
  • Code splitting: critical bundle + 4 page-specific bundles

Result: 47 CSS requests → 3, 68 JS requests → 5. Total CSS+JS weight (after gzip) dropped from 850 KB to 210 KB due to deduplication and tree shaking.

Timeline

Project Type Scope Duration
Simple site (1 template, <30 components) Migrate includes to API, enable minification 1–2 days
Mid-size project (custom frontend, multiple templates) Audit + library unification + build setup 3–7 days
Large portal (multiple teams, legacy code) Full audit, include refactoring, Webpack/Vite setup 7–20 days

Load testing after bundling is mandatory — in rare cases script load order matters, and violating it causes JS errors on specific pages.