Optimizing LCP (Largest Contentful Paint) for 1C-Bitrix
LCP is the time to display the largest visible element on the page. Google considers good LCP < 2.5 seconds. Bitrix sites typically show 4–10 seconds, directly impacting search ranking and conversion.
What is an LCP Element
Browser determines LCP element automatically — it's the largest content by area in viewport on first load. In Bitrix store, typically:
- Hero banner/slider on homepage
- First product image on category page
- Hero image on landing page
Check: Chrome DevTools → Performance → record trace → in Timings section find LCP marker, click — DevTools shows the specific element.
Why LCP is Poor: Dependency Chain
Typical chain for banner in Bitrix slider:
- Browser requests HTML → waits for TTFB (500 ms – 2 s)
- HTML parsed → finds
<script src="swiper.min.js">in<head>— blocks parsing - Swiper.js loads (200 KB), parsed, executed
- JS initializes slider, creates
<img>in DOM - Browser detects image → starts loading
- Image loads (PNG/JPEG, 500 KB – 2 MB)
- LCP registered
On poor 3G, this is 8–12 seconds. Each step can be optimized.
Fixing TTFB as LCP Base
LCP can't be less than TTFB — until server delivers HTML, browser can't work. TTFB optimization via SQL indexes, component cache, OPcache is first step. See TTFB optimization article.
Goal: TTFB < 200 ms for cached pages.
Preload LCP Image
Most effective action — tell browser about LCP image before parsing HTML body:
<!-- Add to <head> BEFORE all scripts and styles -->
<link rel="preload" as="image"
href="/upload/resize_cache/iblock/banner_main.webp"
fetchpriority="high"
imagesrcset="/upload/resize_cache/iblock/banner_main_800.webp 800w,
/upload/resize_cache/iblock/banner_main_1600.webp 1600w"
imagesizes="100vw">
In Bitrix, add via AddHeadString() at template start or directly in header.php:
// In component_epilog.php or header.php
if ($arResult['BANNER_IMAGE']) {
$GLOBALS['APPLICATION']->AddHeadString(
'<link rel="preload" as="image" href="' . $arResult['BANNER_IMAGE'] . '" fetchpriority="high">',
true // true = add to head start
);
}
fetchpriority="high" tells browser to load this resource with highest priority, ahead of other images.
Static First Slide Instead of JS Initialization
Hero banner in Bitrix often implemented as JS slider. Problem: JS initializes slider after loading and executing script — image appears with delay.
Solution: render first slide in static HTML, JS slider initialization for subsequent interaction:
// In template.php of main banner component
$firstSlide = $arResult['ITEMS'][0];
?>
<!-- Static first slide — browser sees immediately -->
<div class="banner-slider" id="main-banner">
<div class="swiper-slide swiper-slide-active">
<img src="<?= $firstSlide['IMG']['SRC'] ?>"
width="<?= $firstSlide['IMG']['WIDTH'] ?>"
height="<?= $firstSlide['IMG']['HEIGHT'] ?>"
fetchpriority="high"
alt="<?= htmlspecialchars($firstSlide['NAME']) ?>">
</div>
</div>
<!-- JS initializes after page load -->
<script defer>
document.addEventListener('DOMContentLoaded', function() {
new Swiper('#main-banner', { /* ... */ });
});
</script>
Image Optimization
Format. WebP is 25–35% smaller than JPEG at same visual quality. AVIF is 20–30% smaller but browser support slightly worse.
Bitrix can serve WebP via \Bitrix\Main\File\Image::resize() when enabled in .settings.php. AVIF support requires ImageMagick with AVIF support or external service.
Size. Image 3000×2000 px for banner on 1920px screen is triple waste. Set sizes via CIBlock::GetPreviewPicture() or \Bitrix\Main\File\Image::resize():
$resizedImage = \CFile::ResizeImageGet(
$originalFileId,
['width' => 1920, 'height' => 600],
BX_RESIZE_IMAGE_PROPORTIONAL_ALT,
false,
false,
false,
90 // quality
);
Compression. Additional optimization via mozjpeg or oxipng at server level: lossless quality, 15–20% size reduction. Configured via nginx ngx_http_image_filter_module or external optimizer on file upload via OnFileSave event handler.
Responsive Images Recommendations
Mobile user with 375px screen shouldn't download 1920px banner. Use srcset:
<img src="/upload/banners/banner_1200.webp"
srcset="/upload/banners/banner_480.webp 480w,
/upload/banners/banner_800.webp 800w,
/upload/banners/banner_1200.webp 1200w,
/upload/banners/banner_1920.webp 1920w"
sizes="100vw"
width="1920" height="600"
fetchpriority="high"
alt="Hero banner">
In Bitrix template: pre-slice multiple sizes via CFile::ResizeImageGet() and output in srcset.
LCP Optimization Timeline
| Task | Time | LCP Improvement |
|---|---|---|
| Preload main image | 0.5 day | −0.5–1 s |
| Static first slide without JS dependency | 1–2 days | −1–2 s |
| WebP conversion + resize | 1 day | −0.5–1.5 s |
| TTFB optimization | 3–10 days | −1–3 s |
| Defer/async for non-critical scripts | 1 day | −0.3–0.8 s |
| Responsive images + srcset | 1–2 days | −0.5–1 s |
With comprehensive work, realistic goal: LCP < 2.5 s for mobile, < 1.5 s for desktop on cached pages.







