Setting up preload/prefetch resources for 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
    1177
  • 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

Setting up preload/prefetch resources for 1C-Bitrix

The browser loads HTML, parses it, finds <link rel="stylesheet"> on the 5th line, goes for CSS, waits, parses CSS, finds fonts in @font-face, goes for fonts — this is a critical request chain that blocks rendering. preload tells the browser about needed resources in advance, before the parser discovers them. prefetch loads resources needed on the next page.

Difference between preload and prefetch

<link rel="preload"> — high priority, the resource is needed on the current page immediately. The browser starts loading before processing the main HTML. If the resource is not used within 3 seconds after loading — the browser will issue a warning in the console.

<link rel="prefetch"> — low priority, the resource will be needed on the next page. Loads in the background, placed in the cache. Works great for loading JS of the next catalog section while the user is reading the current page.

<link rel="preconnect"> — establishes TCP connection and TLS handshake before the resource is requested. Useful for external domains: CDN, Google Fonts, Yandex.Metrica.

Adding preload to Bitrix template

The site template in Bitrix is /bitrix/templates/[template_name]/header.php. Add to <head> before main tags:

<?php
// Get file hash version for cache busting
$cssVersion = filemtime($_SERVER['DOCUMENT_ROOT'] . '/bitrix/templates/.default/styles.css');
$jsVersion = filemtime($_SERVER['DOCUMENT_ROOT'] . '/bitrix/js/main/core/core.js');
?>
<head>
    <meta charset="utf-8">

    <!-- Preload critical CSS (rendering blocked without it) -->
    <link rel="preload" href="/bitrix/templates/.default/styles.css?v=<?=$cssVersion?>"
          as="style" onload="this.onload=null;this.rel='stylesheet'">
    <noscript>
        <link rel="stylesheet" href="/bitrix/templates/.default/styles.css?v=<?=$cssVersion?>">
    </noscript>

    <!-- Preload font (as="font" is mandatory, otherwise priority is incorrect) -->
    <link rel="preload" href="/bitrix/templates/.default/fonts/roboto.woff2"
          as="font" type="font/woff2" crossorigin>

    <!-- Preconnect to external resources -->
    <link rel="preconnect" href="https://mc.yandex.ru">
    <link rel="preconnect" href="https://www.googletagmanager.com">

    <!-- DNS-prefetch as fallback for old browsers -->
    <link rel="dns-prefetch" href="//mc.yandex.ru">
</head>

Programmatic preload via Bitrix API

Bitrix provides methods for managing Link headers through the \Bitrix\Main\Page\Asset class:

// In a component or template
$asset = \Bitrix\Main\Page\Asset::getInstance();

// Preload JS file
$asset->addJs('/bitrix/js/ui/ui.js', [
    'rel' => 'preload',
    'as' => 'script'
]);

// Preload CSS
$asset->addCss('/bitrix/templates/.default/critical.css', [
    'rel' => 'preload'
]);

Via HTTP header from OnPageStart event handler:

AddEventHandler('main', 'OnPageStart', function() {
    header('Link: </bitrix/templates/.default/styles.css>; rel=preload; as=style', false);
    header('Link: </bitrix/templates/.default/fonts/roboto.woff2>; rel=preload; as=font; crossorigin', false);
});

Prefetch for catalog

If the user is on the main page, there's a high probability of navigating to the catalog. Prefetch the main catalog JS:

<?php
// In footer.php of main page
if (defined('IS_INDEX_PAGE') && IS_INDEX_PAGE):
?>
<link rel="prefetch" href="/bitrix/js/catalog/catalog.js">
<link rel="prefetch" href="/catalog/">
<?php endif; ?>

Prefetch HTML page (/catalog/) places it in the browser cache — navigation will be instant. But this only works if the page has proper cache headers.

Critical CSS for Bitrix

The most significant gain comes from inline critical CSS — styles necessary for rendering the visible part of the page, embedded directly in HTML. This eliminates the blocking CSS request entirely.

Tool for extracting critical CSS:

npm install -g critical
critical --base /var/www/bitrix/public_html \
         --src index.html \
         --css bitrix/templates/.default/styles.css \
         --width 1300 --height 900 \
         --inline --extract

Insert the resulting critical CSS in the Bitrix template in a <style> tag in <head>, load the main CSS asynchronously via preload with onload as shown above.

Common mistakes

Preload without as — browser doesn't know the resource type, loads with incorrect priority and caches separately. Resource is loaded twice: once via preload, second — when the parser finds the <script> or <link> tag.

Preload fonts without crossorigin — CORS request to the same domain requires crossorigin for fonts. Without it the browser loads the font twice.

Too many preload — priority for everyone = priority for no one. Maximum 3–5 preload per page for truly critical resources.