Optimizing 1C-Bitrix page rendering

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

Optimizing Page Rendering in 1C-Bitrix

Optimizing Page Rendering in 1C-Bitrix

PageSpeed Insights shows a score of 38 with an LCP of 4.2 seconds. TTFB is 1.8 s, yet the full HTML content has already been delivered. The problem is not the network or client-side JS — the page is being assembled slowly on the server. Bitrix provides diagnostic tools, but they are rarely used correctly.

Diagnosing with Standard Bitrix Tools

Enable the debug panel: $_GET["show_page_exec_time"] or via a constant in dbconn.php:

define('SHOW_PAGE_EXEC_TIME', true);
define('SHOW_SQL_STAT', true);

The panel in the page footer will show:

  • total execution time
  • number of SQL queries and their total time
  • memory consumed

A typical picture of a problematic page: 400+ SQL queries, 1.5–2.5 s on SQL with only 0.3 s on PHP. Components are running in inconsistent caching modes.

Profiling Components

Bitrix does not have a built-in profiler at the component level. Use microtime() around component calls:

// local/php_interface/init.php
AddEventHandler('main', 'OnBeforeEpilog', function() {
    global $APPLICATION;
    if (defined('SHOW_PAGE_EXEC_TIME') && SHOW_PAGE_EXEC_TIME) {
        $timers = \Bitrix\Main\Diag\Helper::getTimers();
        arsort($timers);
        echo '<pre>Top components by time:';
        array_splice($timers, 10);
        print_r($timers);
        echo '</pre>';
    }
});

An alternative is Bitrix Performance Monitor (a Marketplace module) or xhprof/Tideways via a wrapper.

The Main Causes of Slow Rendering

Component with No Cache or CACHE_TYPE = NONE

$APPLICATION->IncludeComponent('bitrix:catalog', '.default', [
    'CACHE_TYPE' => 'N', // <- performance killer
]);

Change to:

'CACHE_TYPE' => 'A',  // automatic based on site settings
'CACHE_TIME' => 3600, // seconds

For components that depend on user context (cart, personal account), component-level caching does not work — use an AJAX approach here: serve the template from cache and load personal data in a separate request.

N+1 in Component Templates

The most common cause of 400+ queries — a loop over results with a query inside:

// Bad: one query per element
foreach ($arResult['ITEMS'] as &$item) {
    $item['SECTION'] = \CIBlockSection::GetByID($item['IBLOCK_SECTION_ID'])->GetNext();
}

Fix — an aggregated query before the loop:

$sectionIds = array_unique(array_column($arResult['ITEMS'], 'IBLOCK_SECTION_ID'));
$sections = [];
$res = \CIBlockSection::GetList([], ['ID' => $sectionIds], false, ['ID', 'NAME', 'CODE']);
while ($s = $res->GetNext()) {
    $sections[$s['ID']] = $s;
}
foreach ($arResult['ITEMS'] as &$item) {
    $item['SECTION'] = $sections[$item['IBLOCK_SECTION_ID']] ?? null;
}

Disabled Caching in a Composite Component

A composite component (e.g., bitrix:catalog) manages caching for its children. If the section settings have "Do not cache" selected — caching is disabled for the entire tree, including the product listing sections.

Check in site settings: Settings → Product Settings → Caching.

Template Optimization

PHP template minification. Bitrix assembles a page from dozens of include calls. Each include hits the filesystem. On HDD servers this is 5–15 ms per file. Solution — OPcache with opcache.validate_timestamps=0 in production (manual cache invalidation after deploy).

Moving heavy blocks to AJAX. Widgets like "similar products," "recently viewed," and "popular in category" are candidates for AJAX loading. The main page renders quickly; widgets are loaded in parallel.

Composite site. The built-in Bitrix mechanism for caching entire pages with dynamic block substitution (cart, authentication). Delivers TTFB of 50–100 ms for authenticated users. Requires setup per specific template — it cannot be enabled with a single button without adapting components.

Example Result

An online building materials store, 180,000 SKUs. Before optimization: TTFB 2.1 s, 380 SQL queries on a category page. After: CACHE_TYPE=N disabled in three components, two N+1 issues fixed, OPcache validate_timestamps=0 enabled. Result: TTFB 420 ms, 38 SQL queries, LCP 1.9 s.

Scope of Work and Timeline

Phase Content Timeline
Audit Profiling top 5 pages, identifying bottlenecks 1–2 days
Cache optimization Configuring component caching 1–2 days
N+1 elimination Refactoring templates with aggregated queries 2–5 days
Composite Template setup and adaptation 2–4 days