Розробка PWA-програми на базі 1С-Бітрікс

Наша компанія займається розробкою, підтримкою та обслуговуванням рішень на Бітрікс та Бітрікс24 будь-якої складності. Від простих односторінкових сайтів до складних інтернет-магазинів, CRM систем з інтеграцією 1С та телефонії. Досвід розробників підтверджено сертифікатами від вендора.
Пропоновані послуги
Показано 1 з 1 послугУсі 1626 послуг
Розробка PWA-програми на базі 1С-Бітрікс
Середня
~1-2 тижні
Часті питання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_website-b2b-advance_0.png
    Розробка сайту компанії B2B ADVANCE
    1262
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Розробка веб-сайту для компанії ФІКСПЕР
    851
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Розробка на базі Бітрікс, Бітрікс24, 1С для компанії Development of an Online
    585
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Розробка на базі 1С Підприємство для компанії МИРСАНБЕЛ
    751
  • image_crm_dolbimby_434_0.webp
    Розробка сайту на CRM Бітрікс24 для компанії DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Розробка на базі Бітрікс24 для компанії ТЕХНОТОРГКОМПЛЕКС
    989

Розробка PWA-додатку на базі 1С-Бітрікс

Починаючи з версії 21.0, у Бітріксі є штатний модуль pwa — генерація manifest.json, реєстрація Service Worker, базовий offline-режим. На демонстрації виглядає переконливо: сайт додається на робочий стіл, працює без мережі, надсилає push-повідомлення. На реальному проєкті модуль закриває приблизно 40% потреб. Решта — стратегії кешування, сумісність із модулем composite, обхід обмежень iOS, доведення Lighthouse-метрик до зеленої зони — потребує ручної роботи.

Штатний модуль pwa: що він робить

Активація: Адміністрування → Налаштування → Налаштування модулів → PWA. Після ввімкнення Бітрікс виконує три дії:

  1. Генерує /manifest.json з параметрів модуля — name, short_name, start_url, display, theme_color, background_color, масив icons[]
  2. Реєструє Service Worker /sw.js через navigator.serviceWorker.register('/sw.js') у шаблоні сайту
  3. Додає <link rel="manifest" href="/manifest.json"> у <head>

Параметр display за замовчуванням standalone — додаток відкривається без адресного рядка. Якщо користувачам потрібна навігація назад через історію браузера — ставимо minimal-ui.

Іконки — модуль очікує повний набір: 72x72, 96x96, 128x128, 144x144, 152x152, 192x192, 384x384, 512x512 у PNG. Без іконки 512x512 Lighthouse знижує бали за installability. Генеруємо набір з одного вихідника через CFile::ResizeImageGet(), але перевіряємо якість вручну — автоматичне стиснення іноді дає артефакти на дрібних розмірах.

Service Worker та стратегії кешування

Штатний /sw.js використовує Cache First для статики і Network First для HTML. Цього досить для базового offline, але не для повноцінного PWA.

Cache First — Service Worker шукає відповідь у CacheStorage, якщо знаходить — повертає, не звертаючись до сервера. Працює для /bitrix/js/, /bitrix/css/, /upload/. Проблема: після деплою нового JS-бандла користувач продовжує отримувати стару версію. На сайті з частими релізами це означає застарілий JavaScript протягом годин.

Рішення — версіонування кешу. Service Worker зберігає константу версії. При activate видаляє всі кеші, крім поточної версії:

const CACHE_VERSION = 'v1.4';
self.addEventListener('activate', event => {
  event.waitUntil(
    caches.keys().then(keys =>
      Promise.all(keys.filter(k => k !== CACHE_VERSION).map(k => caches.delete(k)))
    )
  );
});

Network First — спочатку запит до сервера, якщо сервер недоступний — fallback із кешу. Правильна стратегія для HTML, але є нюанс із модулем composite. Композитний сайт віддає статичний HTML із /bitrix/html_pages/ через Nginx — без ініціалізації PHP. Коли Service Worker із Cache First для HTML перехоплює відповідь, Nginx навіть не отримує запит. Якщо composite оновив сторінку (товар закінчився, ціна змінилася) — користувач бачить застарілі дані.

Stale While Revalidate — стратегія, яку штатний модуль не використовує, але ми додаємо для API та каталожних даних. Миттєво віддає з кешу, паралельно оновлює кеш запитом до сервера. Ідеально для списків товарів, що змінюються раз на годину.

Кастомну логіку пишемо у /local/templates/main/sw-custom.js і підключаємо через importScripts(). Не редагуємо /sw.js напряму — модуль його перегенерує.

Глибше про взаємодію з composite

Це найскладніший аспект PWA на Бітріксі, тому розберемо детально.

Модуль composite зберігає готовий HTML у файловій системі. Nginx віддає файл напряму — час відповіді 5-15ms. Динамічні зони (<div id="bx-composite-...">) підвантажуються окремим AJAX-запитом до bitrix/services/main/ajax.php після завантаження сторінки.

Конфлікт №1: подвійне кешування. composite кешує HTML на сервері. Service Worker кешує HTML на клієнті. Коли серверний кеш інвалідується (контент змінився), клієнтський кеш залишається старим. Користувач бачить застарілу сторінку навіть після F5 — бо Service Worker перехоплює запит до того, як він дійде до сервера.

Рішення: для навігаційних запитів (HTML) завжди використовуємо Network First. Service Worker спочатку йде до сервера (де composite віддає свіжий HTML), і лише при відсутності мережі повертає кеш.

Конфлікт №2: динамічні зони. AJAX-запити до bitrix/services/main/ajax.php несуть персоналізовані дані — ім'я користувача, кошик, кількість товарів. Якщо Service Worker кешує ці відповіді, наступний користувач побачить чужі дані.

Рішення: у Service Worker виключаємо з кешування:

  • Усі запити до bitrix/services/main/ajax.php
  • Запити з параметром sessid
  • Запити з cookie PHPSESSID (перевіряємо через event.request.headers)

Конфлікт №3: CDN. Якщо composite налаштований із CDN, HTML може містити абсолютні URL на CDN-домен. Service Worker працює в межах свого scope (зазвичай /) і не перехоплює запити до іншого origin. Статика з CDN проходить повз Service Worker — це нормально для CSS/JS, але якщо зображення критичні для offline, потрібно кешувати їх окремо через cache.add().

Push-повідомлення через модуль pull

Модуль pull (Push and Pull) забезпечує real-time взаємодію в Бітріксі. Для PWA він використовується як транспорт push-повідомлень.

Ланцюжок: клієнт підписується через PushSubscription API → надсилає endpoint, keys.p256dh, keys.auth на сервер → сервер зберігає підписку в таблиці b_pull_push → при настанні події відправляє payload через \Bitrix\Pull\Push::send().

Налаштування:

  1. Генеруємо VAPID-ключі: openssl ecparam -genkey -name prime256v1 -out private.pem
  2. Публічний ключ прописуємо в налаштуваннях модуля pull → «Push-повідомлення» → «VAPID Public Key»
  3. У Service Worker обробляємо подію push і notificationclick для відкриття URL через clients.openWindow()

Серверна частина — подія OnAfterOrderAdd або будь-який інший обробник викликає \Bitrix\Pull\Push::send() з масивом підписок і payload. Для масових розсилок (акції, нові товари) використовуємо черги через b_agent або окремий cron-скрипт, щоб не блокувати основний потік.

Обмеження iOS — окрема історія

PWA на iOS через Safari — це інший рівень підтримки порівняно з Chrome на Android:

  • Web Push — лише з iOS 16.4, і лише для сайтів, доданих на Home Screen. У звичайній вкладці Safari PushManager.subscribe() поверне помилку
  • beforeinstallprompt — не підтримується. Програмно показати банер встановлення неможливо. Показуємо ручну інструкцію: «Натисніть Поділитися → Додати на початковий екран»
  • Background Sync — не підтримується. Форма, відправлена offline, не потрапить у чергу Sync API. Обхід: зберігаємо в IndexedDB, повторюємо при події online
  • Badge API — не підтримується. Лічильник на іконці додатку недоступний
  • Квота сховища — Safari обмежує кожен origin приблизно 50MB. Chrome виділяє до 80% вільного місця на диску
  • Час життя Service Worker — Safari агресивно вивантажує Service Worker після кількох днів неактивності. Push-повідомлення перестають працювати, доки користувач не відкриє додаток знову

Для проєктів, де значна частка аудиторії на iOS, ці обмеження обговорюємо з клієнтом на старті. PWA на iOS — це ближче до закладки з offline-підтримкою, ніж до нативного додатку.

Lighthouse: на що звертаємо увагу

  • Installable — коректний manifest.json, Service Worker із обробником fetch, іконка 512x512, start_url повертає 200 в offline
  • HTTPS — обов'язково. Налаштовуємо в Бітріксі: Налаштування → Головний модуль → «Працювати в режимі HTTPS». Nginx — один 301 без ланцюжка
  • theme-color<meta name="theme-color"> повинен збігатися з theme_color у manifest.json
  • Offline fallback — при відсутності мережі показуємо кастомну сторінку /offline.html, а не Chrome Dinosaur
  • start_url — не повинен повертати 3xx. На мультимовних сайтах із редіректом //uk/ вказуємо /uk/ у манифесті

PWA проти нативного додатку

Критерій PWA Нативний (iOS/Android)
Встановлення З браузера, без магазину App Store / Google Play
Оновлення Автоматичне через Service Worker Через магазин, потрібне підтвердження
Доступ до пристрою Камера, геолокація, повідомлення Повний доступ до API пристрою
Offline Кешований контент Повноцінна offline-логіка
Розмір 0 MB (кеш браузера) 20-100+ MB
Вартість розробки 1-2 тижні поверх сайту 2-4 місяці окремий проєкт

Етапи робіт

  1. Аудит поточного сайту (2-3 дні) — перевірка сумісності шаблону з вимогами PWA, Lighthouse-аналіз, оцінка взаємодії з composite
  2. Налаштування модуля та Service Worker (3-5 днів) — конфігурація manifest.json, стратегії кешування, offline-сторінка, потік push-підписки
  3. Тестування (2-3 дні) — Android (Chrome, Samsung Internet), iOS (Safari), десктоп (Chrome, Edge). Lighthouse audit на кожному етапі
  4. Запуск і моніторинг (1-2 дні) — деплой на прод, перевірка метрик, алерти на помилки Service Worker
Масштаб Терміни
PWA для існуючого сайту з composite 1-2 тижні
PWA + push-повідомлення + offline-каталог 2-3 тижні
PWA з кастомним App Shell і складною offline-логікою 3-5 тижнів