Глава 1.3: Движки рендеринга: Blink vs WebKit

Почему один и тот же сайт по-разному выглядит на Android и iOS

Глава 1.3 • Часть 1 из 8

Движки рендеринга: Blink vs WebKit

Понимание различий между движками — ключ к кроссплатформенному тестированию. Здесь мы разберём, почему «на Android работает, а на iOS — нет».

1 Что такое движок рендеринга

Движок рендеринга (rendering engine) — это программный компонент, который преобразует HTML, CSS и JavaScript в визуальное представление на экране. Это «сердце» любого браузера или WebView.

Как работает движок (упрощённо):

  1. Парсинг: Читает HTML и строит DOM-дерево, читает CSS и строит CSSOM-дерево.
  2. Построение Render Tree: Объединяет DOM и CSSOM, исключая невидимые элементы.
  3. Layout (Reflow): Вычисляет геометрию каждого элемента (размеры, позиции).
  4. Paint: Рисует пиксели (цвета, границы, тени, текст).
  5. Composite: Объединяет слои для финального отображения (особенно важно для анимаций).
VS
🍎
WebKit
iOS WKWebView
Движок Apple, используется в Safari

Почему QA должен понимать движки:

  • Различия в рендеринге: Один и тот же CSS может отображаться по-разному.
  • Поддержка фич: Новые CSS/JS-свойства появляются в движках в разное время.
  • Баги движков: Каждый движок имеет свои специфические баги.
  • Производительность: Оптимизации работают по-разному.
  • Вендорные префиксы: -webkit-, -moz- — наследие разных движков.
🎯 Исторический контекст

До 2013 года Android WebView тоже использовал WebKit. Но Google форкнула WebKit и создала Blink — более быстрый и современный движок. С тех пор пути Android и iOS разошлись, и кроссбраузерность стала головной болью для разработчиков.

2 Blink (Chromium) — Android WebView

Blink — это движок рендеринга, разработанный Google на основе форка WebKit. Используется в Google Chrome, Opera, Microsoft Edge (с 2020) и Android WebView.

Ключевые особенности Blink:

  • Мультипроцессная архитектура: Каждый таб (или WebView) работает в отдельном процессе. Это повышает стабильность (краш одного WebView не убивает всё приложение).
  • Быстрый JavaScript: Движок V8 — один из самых быстрых JS-движков в мире.
  • Современные веб-стандарты: Blink часто первым внедряет новые CSS/JS-фичи.
  • Агрессивная оптимизация: Кэширование, ленивая загрузка, предиктивный рендеринг.
  • DevTools: Chrome DevTools — золотой стандарт отладки веба.

Специфичные CSS-свойства Blink:

CSS-свойства, которые работают только в Blink (или лучше в Blink)
/* Скроллбары */
::-webkit-scrollbar {
  width: 8px;
}

::-webkit-scrollbar-track {
  background: #f1f1f1;
}

::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 4px;
}

/* Плавная прокрутка (лучше, чем в WebKit) */
html {
  scroll-behavior: smooth;
}

/* Backdrop filter (размытие фона) */
.modal {
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px); /* Для WebKit */
}

/* Container queries (современная фича) */
@container (min-width: 400px) {
  .card {
    display: grid;
  }
}

Известные баги и ограничения Blink в Android WebView:

  • Проблема с position: fixed: На некоторых устройствах фиксированные элементы «прыгают» при скролле.
  • Баг с overflow: auto: На старых версиях Android (5.0-7.0) скролл внутри контейнера может не работать.
  • Проблема с input type="date": Нативный date picker выглядит по-разному на разных версиях Android.
  • Утечки памяти: При длительной работе с тяжёлым DOM могут возникать утечки.
  • Проблема с will-change: Чрезмерное использование может привести к потреблению большого объёма памяти.
💡 Как определить версию Blink

В Android WebView версия Blink привязана к версии приложения «Android System WebView» в Google Play. Проверить можно так:

  1. Откройте настройки устройства.
  2. Перейдите в «Приложения» → «Android System WebView».
  3. Посмотрите версию (например, 120.0.6099.144).
  4. Это и есть версия Blink.

3 WebKit — iOS WKWebView

WebKit — это движок рендеринга, разработанный Apple (на основе форка KHTML от KDE). Используется в Safari и iOS WKWebView. Это единственный движок, разрешённый на iOS (Apple запрещает другие движки в App Store).

Ключевые особенности WebKit:

  • Однопроцессная архитектура (в WKWebView): В отличие от Blink, WKWebView работает в том же процессе, что и приложение. Это означает, что краш WebView может убить всё приложение.
  • Строгое следование стандартам: Apple консервативна в внедрении новых фич, но тщательно тестирует их.
  • Оптимизация для iOS: WebKit идеально оптимизирован под железо Apple (A-series чипы).
  • Безопасность: Строгая политика безопасности, особенно в отношении cookies и трекинга (ITP — Intelligent Tracking Prevention).
  • Safari Web Inspector: Мощный инструмент отладки, но требует Mac для подключения.

Специфичные CSS-свойства WebKit:

CSS-свойства, которые работают только в WebKit (или лучше в WebKit)
/* Плавная прокрутка с инерцией (только WebKit) */
.scrollable {
  -webkit-overflow-scrolling: touch;
  overflow-y: scroll;
}

/* Safe area (для iPhone с «чёлкой») */
body {
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}

/* Backdrop filter (размытие фона) */
.navbar {
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

/* Стилизация input полей */
input[type="search"] {
  -webkit-appearance: none;
}

/* Маска для градиентов */
.text-gradient {
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

/* Sticky position (лучше работает в WebKit) */
.sticky-header {
  position: -webkit-sticky;
  position: sticky;
  top: 0;
}

Известные баги и ограничения WebKit в iOS WKWebView:

  • Проблема с 100vh: На iOS 100vh включает адресную строку Safari, что приводит к обрезке контента. Решение: использовать 100dvh (dynamic viewport height).
  • Баг с position: fixed и клавиатурой: При открытии клавиатуры фиксированные элементы могут «уезжать».
  • Проблема с input type="file": Загрузка файлов требует дополнительной обработки через нативный код.
  • Ограничение памяти: При превышении лимита памяти (около 1 ГБ на старых устройствах) WKWebView крашится без ошибки.
  • Проблема с autoplay для видео: Автоматическое воспроизведение видео запрещено без взаимодействия пользователя.
  • Баг с overflow: scroll: На некоторых версиях iOS скролл может «застревать».
⚠️ Важно: UIWebView vs WKWebView

До iOS 8 использовался UIWebView — устаревший компонент с множеством багов. С 2020 года Apple запретила UIWebView в App Store. Если вы видите баг в UIWebView — не тратьте время, обновляйте приложение до WKWebView.

4 Ключевые различия и кроссбраузерность

Здесь мы соберём все различия между Blink и WebKit в одну таблицу. Это ваша шпаргалка для кроссплатформенного тестирования.

Фича Blink (Android) WebKit (iOS) Рекомендация
Плавная прокрутка scroll-behavior: smooth -webkit-overflow-scrolling: touch Используйте оба свойства
Высота viewport 100vh работает корректно 100vh включает адресную строку Используйте 100dvh или JS-решение
Safe Area Поддерживается с Android 9+ Поддерживается с iOS 11+ Используйте env(safe-area-inset-*)
Backdrop filter Поддерживается с Chrome 76+ Поддерживается с iOS 9+ Добавляйте -webkit-backdrop-filter
Sticky position Работает хорошо Требует -webkit-sticky Используйте оба префикса
Container queries Поддерживается с Chrome 105+ Поддерживается с iOS 16+ Проверяйте поддержку на caniuse.com
CSS Grid Полная поддержка Полная поддержка с iOS 10.3+ Безопасно использовать
Flexbox Полная поддержка Полная поддержка с iOS 9+ Безопасно использовать
Custom properties (CSS variables) Поддерживается с Chrome 49+ Поддерживается с iOS 9.3+ Безопасно использовать
WebP изображения Полная поддержка Поддерживается с iOS 14+ Добавляйте fallback на JPEG/PNG
AVIF изображения Поддерживается с Chrome 85+ Поддерживается с iOS 16+ Используйте с осторожностью
JavaScript ES6+ Полная поддержка Полная поддержка с iOS 10+ Используйте Babel для старых iOS

Практические примеры проблем:

Проблема 1: Высота viewport на iOS
/* ❌ Плохо: на iOS контент обрежется */
.fullscreen {
  height: 100vh;
}

/* ✅ Хорошо: используем dvh (dynamic viewport height) */
.fullscreen {
  height: 100dvh;
}

/* ✅ Альтернатива: JS-решение */
.fullscreen {
  height: calc(var(--vh, 1vh) * 100);
}

<script>
  // Устанавливаем CSS-переменную
  const vh = window.innerHeight * 0.01;
  document.documentElement.style.setProperty('--vh', `${vh}px`);
  
  // Обновляем при изменении размера
  window.addEventListener('resize', () => {
    const vh = window.innerHeight * 0.01;
    document.documentElement.style.setProperty('--vh', `${vh}px`);
  });
</script>
Проблема 2: Плавная прокрутка
/* ❌ Плохо: на iOS скролл будет «дёрганым» */
.scrollable {
  overflow-y: auto;
}

/* ✅ Хорошо: плавная прокрутка на обеих платформах */
.scrollable {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch; /* Для iOS */
  scroll-behavior: smooth; /* Для Android */
}
Проблема 3: Backdrop filter
/* ❌ Плохо: на iOS не будет размытия */
.modal {
  backdrop-filter: blur(10px);
}

/* ✅ Хорошо: работает на обеих платформах */
.modal {
  -webkit-backdrop-filter: blur(10px); /* Для iOS */
  backdrop-filter: blur(10px); /* Для Android */
}
💡 Правило вендорных префиксов

Если вы используете экспериментальные CSS-свойства, всегда добавляйте вендорные префиксы:

  • -webkit- — для WebKit (iOS) и Blink (Android)
  • -moz- — для Firefox (не относится к WebView, но полезно знать)
  • -ms- — для Internet Explorer (устарел, не используйте)

Используйте Autoprefixer — инструмент, который автоматически добавляет префиксы на основе данных caniuse.com.

5 Практика: Can I Use и проверка поддержки фич

Теперь, когда вы знаете различия между движками, нужно научиться проверять поддержку конкретных фич перед тем, как заводить баг.

Can I Use — ваш главный инструмент:

caniuse.com — это база данных поддержки CSS, HTML5 и JavaScript API в разных браузерах и WebView.

Как пользоваться Can I Use:

  1. Введите название фичи (например, backdrop-filter).
  2. Посмотрите таблицу поддержки.
  3. Обратите внимание на версии:
    • Chrome for Android — это версия Blink в Android WebView.
    • Safari on iOS — это версия WebKit в iOS WKWebView.
  4. Проверьте «Known issues» — там описаны известные баги.
🎯 Пример проверки

Вы хотите использовать CSS Container Queries. Заходите на caniuse.com и видите:

  • Chrome for Android: поддержка с версии 108 (декабрь 2022).
  • Safari on iOS: поддержка с версии 16.0 (сентябрь 2022).

Вывод: Если ваше приложение поддерживает Android 5.0+ и iOS 14+, то Container Queries будут работать не на всех устройствах. Нужен fallback или polyfill.

Другие полезные инструменты:

  • MDN Web Docs (developer.mozilla.org) — документация по веб-технологиям с таблицами поддержки.
  • Chrome Platform Status (chromestatus.com) — статус внедрения фич в Chromium.
  • WebKit Feature Status (webkit.org/status) — статус фич в WebKit.
  • Autoprefixer — инструмент для автоматического добавления вендорных префиксов.
  • Babel — транспайлер JavaScript для поддержки старых версий движков.

Чек-лист для QA при тестировании кроссбраузерности:

  1. ✅ Проверьте баг в обычном браузере (Chrome на Android, Safari на iOS).
  2. ✅ Если баг воспроизводится в браузере — это 100% баг веб-контента (слой 4).
  3. ✅ Если баг не воспроизводится в браузере — проверьте версию WebView/WKWebView.
  4. ✅ Зайдите на caniuse.com и проверьте поддержку используемых фич.
  5. ✅ Проверьте консоль DevTools на наличие ошибок.
  6. ✅ Проверьте нативные логи (Logcat / Console) на наличие крашей.
  7. ✅ Укажите в баг-репорте версию движка (версию Android System WebView или iOS).
⚠️ Частая ошибка QA

Не заводите баг «не работает на iOS», не проверив:

  • Версию iOS (может, это старая версия без поддержки фичи).
  • Поддержку фичи на caniuse.com.
  • Консоль Safari Web Inspector (может, там ошибка JS).

Если фича не поддерживается — это не баг, это ограничение платформы. Заводите баг на разработчиков с просьбой добавить fallback.

💡 Лайфхак: Feature Detection

Вместо проверки версии iOS/Android, используйте Feature Detection — проверку поддержки фичи в JavaScript:

Пример: Проверка поддержки CSS Container Queries
if (CSS.supports('container-type', 'inline-size')) {
  // Container Queries поддерживаются
  console.log('Container queries are supported!');
} else {
  // Fallback для старых устройств
  console.log('Container queries are NOT supported, using fallback');
  // Применяем альтернативные стили
}