Image optimization 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
    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

Image Optimization for 1C-Bitrix

Images are the largest contributor to page weight for most Bitrix projects. A typical situation: a manager uploads a product photo in high resolution directly from a camera (3–8 MB, 4000×3000 pixels), Bitrix saves the file to /upload/iblock/, and that exact file is served to mobile users. In 2024, this directly affects Core Web Vitals (LCP, CLS), Google search rankings, and conversion rates — slow image loading is directly linked to mobile bounce rates.

Bitrix Resize Mechanism

Bitrix provides CFile::ResizeImageGet() and \Bitrix\Main\UI\FileInput::processFiles() for on-the-fly image resizing. In component templates this looks like:

$resizedImage = CFile::ResizeImageGet(
    $arItem['PREVIEW_PICTURE'],
    ['width' => 400, 'height' => 300],
    BX_RESIZE_IMAGE_PROPORTIONAL,
    false,
    false
);

Results are cached in /upload/resize_cache/. The problem: by default the resize cache has no size limit. On a project with frequent image replacement, the /upload/resize_cache/ folder can grow to 20–50 GB over 2–3 years — with most files being stale.

Conversion to WebP

WebP delivers 25–40% smaller file sizes at equivalent quality for photographs, and 60–80% smaller for graphics with transparency compared to PNG. Modern browsers (Chrome 32+, Firefox 65+, Safari 14+) support WebP.

Ways to implement WebP for Bitrix:

1. At the nginx level via ngx_http_image_filter_module:

location ~* \.(jpg|jpeg|png)$ {
    add_header Vary Accept;
    if ($http_accept ~* "webp") {
        rewrite ^(.*)\.(jpg|jpeg|png)$ $1.webp break;
    }
}

This only works if .webp versions of files exist. Generation via a cron script using cwebp or imagemagick.

2. Via a PHP wrapper around CFile::ResizeImageGet():

function getImageSrc(int $fileId, int $width, int $height): string {
    $webpSupported = str_contains($_SERVER['HTTP_ACCEPT'] ?? '', 'image/webp');
    $format = $webpSupported ? 'webp' : 'jpg';
    // Custom converter with result caching
    return ImageConverter::resize($fileId, $width, $height, $format);
}

3. The <picture> tag with multiple sources:

<picture>
    <source srcset="/upload/resize_cache/product_400x300.webp" type="image/webp">
    <img src="/upload/resize_cache/product_400x300.jpg" width="400" height="300" loading="lazy" alt="...">
</picture>

This is the most universal approach — the browser selects the supported format automatically.

AVIF as the Next Step

AVIF (AV1 Image Format) yields a further 20–35% size reduction over WebP for photographs. Chrome supports it from version 85, Firefox from 86, Safari from 16. AVIF encoding is slower than WebP, so for large catalogs generation is performed in the background via a task queue.

Responsive Images (srcset)

Multiple image versions are needed for Retina displays and different screen sizes:

$sizes = [
    ['width' => 400, 'height' => 300],   // mobile
    ['width' => 800, 'height' => 600],   // tablet
    ['width' => 1200, 'height' => 900],  // desktop
];
$srcset = [];
foreach ($sizes as $size) {
    $img = CFile::ResizeImageGet($fileId, $size, BX_RESIZE_IMAGE_PROPORTIONAL);
    $srcset[] = $img['src'] . ' ' . $size['width'] . 'w';
}
<img srcset="<?= implode(', ', $srcset) ?>"
     sizes="(max-width: 768px) 400px, (max-width: 1024px) 800px, 1200px"
     src="/upload/fallback.jpg" alt="...">

Case Study: Furniture Catalog, 8,000 SKUs

Before optimization: all images in JPEG, average size 480 KB, no srcset, no WebP. Catalog page (24 products) — 11.5 MB of images on desktop, 11.5 MB on mobile (the same files).

What was done:

  • Batch conversion of all images in upload to WebP via cwebp (cron script, processed overnight)
  • Resizing via CFile::ResizeImageGet() in three sizes for srcset
  • <picture> tag with WebP source + JPEG fallback img in the catalog.section template
  • Lazy load for images below the fold
  • Configuration of scheduled cleanup for /upload/resize_cache/ entries older than 90 days

Result: average image weight in the catalog — 28 KB (WebP, appropriate size). Catalog page — 680 KB of images on mobile, 1.1 MB on desktop. LCP: 4.2 s → 1.6 s. PageSpeed Mobile: 31 → 74.

Work Stages

Stage Content Duration
Audit Analysis of current sizes, formats, and include methods 0.5 day
WebP/AVIF conversion Batch script + automated conversion on upload 1–2 days
Srcset and <picture> Component template updates 2–4 days
Lazy load Attributes and JS for custom scenarios 0.5–1 day
resize_cache cleanup Cleanup agent configuration 0.5 day

Total: 4 to 8 days depending on the number of custom templates and catalog size.