Кроссбраузерность

Кроссбраузерность в контексте Deck.gl определяется не только различиями HTML/CSS, но прежде всего неоднородностью реализации WebGL, GPU-стека и драйверов в разных браузерах и операционных системах. Deck.gl как надстройка над WebGL через слой luma.gl вынужден учитывать множество аппаратных и программных различий, которые напрямую влияют на стабильность рендеринга, производительность и корректность визуализации.


Различия WebGL-реализаций между браузерами

Основная кроссбраузерная сложность возникает на уровне WebGL 1.0 и WebGL 2.0. Несмотря на стандартизацию, каждая реализация имеет собственные ограничения:

  • различия в поддержке расширений WebGL
  • различия в лимитах GPU (texture size, attribute count)
  • особенности управления контекстом (context loss/restoration)
  • различия в precision shader-ов
  • различия в работе с float-буферами

Deck.gl опирается на WebGL как на базовый слой, поэтому любые отклонения от спецификации напрямую влияют на слои (layers), шейдеры и геометрические вычисления.


WebGL 1 vs WebGL 2 в разных браузерах

Поддержка WebGL 2.0 существенно различается:

  • Chrome и Edge (Chromium) обеспечивают наиболее стабильную реализацию WebGL 2
  • Firefox поддерживает WebGL 2, но чаще демонстрирует строгие ограничения по памяти
  • Safari historically имеет ограничения по части extensions и поведения context loss

Deck.gl адаптируется к этому через fallback на WebGL 1, что влияет на доступность:

  • instanced rendering
  • 3D текстуры
  • integer-атрибуты
  • некоторые типы blending modes

В WebGL 1 многие операции требуют дополнительных расширений, таких как OES_element_index_uint или ANGLE_instanced_arrays, которые не всегда доступны одинаково во всех браузерах.


Контекст WebGL и проблемы инициализации

Создание контекста WebGL является одной из самых нестабильных точек кроссбраузерности.

Типовые различия:

  • Safari может возвращать null при нехватке GPU памяти даже при успешной поддержке WebGL
  • Firefox может ограничивать число одновременно активных контекстов
  • Chrome чаще допускает создание контекста, но позже может инициировать context lost

Deck.gl использует защитные механизмы через probe-слой probe.gl, позволяющий отслеживать:

  • потерю контекста (webglcontextlost)
  • восстановление контекста (webglcontextrestored)
  • деградацию производительности

Особенно важно учитывать, что восстановление контекста не гарантирует сохранение GPU-ресурсов: текстуры, буферы и шейдеры должны пересоздаваться.


Различия в GPU и драйверах

Даже при одинаковом браузере поведение WebGL может отличаться:

  • Intel integrated GPUs имеют меньшие лимиты по uniform buffers
  • мобильные GPU (Adreno, Mali) часто ограничивают точность float в шейдерах
  • Apple Silicon отличается высокой стабильностью, но строгими лимитами памяти

Deck.gl вынужден учитывать:

  • MAX_TEXTURE_SIZE
  • MAX_VERTEX_ATTRIBS
  • MAX_3D_TEXTURE_SIZE
  • precision mediump/lowp/highp

Эти параметры напрямую влияют на визуализацию больших наборов данных (например, GeoJSON или point clouds).


Особенности Safari и iOS

Safari (особенно iOS) представляет один из самых сложных случаев для WebGL-приложений:

  • агрессивное управление памятью
  • частые внезапные context loss
  • ограничения на количество WebGL canvas
  • нестабильная работа с offscreen canvas
  • частичная поддержка WebGL 2 в зависимости от версии iOS

Deck.gl на iOS часто сталкивается с необходимостью:

  • уменьшения разрешения render target
  • отключения некоторых post-processing эффектов
  • снижения числа одновременно активных layers

Дополнительно влияет поведение devicePixelRatio, которое на мобильных устройствах может достигать 3–4, резко увеличивая нагрузку на GPU.


Canvas и devicePixelRatio

Разные браузеры по-разному интерпретируют плотность пикселей:

  • Chrome и Edge корректно масштабируют canvas под DPR
  • Safari иногда требует ручной синхронизации размеров buffer и CSS canvas
  • Firefox может иметь расхождения при динамическом изменении масштаба

Deck.gl обычно опирается на автоматическое масштабирование canvas через viewport abstraction, но в кроссбраузерных сценариях важно учитывать:

  • несоответствие между CSS pixels и framebuffer pixels
  • необходимость явного пересоздания viewport при resize
  • влияние DPR на fill-rate GPU

Ошибки в этой области приводят к размытым текстурам или неправильному позиционированию геометрии.


Поддержка расширений WebGL

Критическим фактором кроссбраузерности являются WebGL-расширения:

  • OES_texture_float
  • OES_texture_float_linear
  • WEBGL_depth_texture
  • EXT_color_buffer_float
  • ANGLE_instanced_arrays

Deck.gl активно проверяет доступность расширений через абстракции luma.gl. Если расширение отсутствует:

  • используется альтернативный shader path
  • снижается precision вычислений
  • отключаются части визуализации (например, bloom или heatmap blending)

Разные браузеры реализуют эти расширения с различной степенью полноты, особенно в WebGL 2, где часть расширений становится частью core API, но ведёт себя по-разному.


Шейдеры и различия GLSL-компиляции

GLSL-шейдеры могут компилироваться по-разному:

  • Firefox строже относится к неиспользуемым uniform variables
  • Safari может оптимизировать код агрессивнее, удаляя потенциально используемые переменные
  • Chrome более tolerant к нестрогому GLSL

Типовые проблемы:

  • precision mismatch (highp/mediump)
  • различия в implicit type conversion
  • различия в поддержке loop unrolling
  • лимиты на длину шейдера

Deck.gl вынужден генерировать шейдеры динамически, учитывая эти ограничения, и часто применяет паттерны:

  • conditional compilation через #ifdef
  • разделение шейдеров на modular chunks
  • fallback для старых GPU

Web Workers и кроссбраузерные ограничения

Использование Web Workers в Deck.gl (например, для подготовки геометрии) также подвержено различиям:

  • Safari ограничивает передачу transferables в некоторых режимах
  • Firefox может медленнее сериализовать большие массивы
  • Chrome наиболее стабилен в structured cloning

При этом передача данных между worker и main thread критична для performance больших dataset-ов (миллионы точек, сетки, полигоны).


Производительность рендеринга и requestAnimationFrame

Хотя requestAnimationFrame стандартизирован, его поведение имеет различия:

  • Safari может снижать FPS в фоне более агрессивно
  • Firefox иногда синхронизирует RAF с system refresh rate иначе, чем Chrome
  • mobile browsers часто throttle RAF при низком battery mode

Deck.gl, работающий в связке с Mapbox или standalone WebGL canvas, вынужден учитывать:

  • падение FPS при tab inactive
  • нестабильную частоту обновления на мобильных устройствах
  • jitter при смешанных источниках событий (scroll + render loop)

Ограничения памяти и большие данные

Работа с большими геоданными в Deck.gl часто упирается в кроссбраузерные ограничения памяти GPU:

  • Chrome допускает более высокие лимиты buffer allocation
  • Safari быстрее освобождает ресурсы, но может преждевременно убивать контекст
  • Firefox ограничивает размер текстур и buffer objects более строго

Это влияет на:

  • количество одновременно отрисовываемых объектов
  • размер tile-based данных
  • использование GPU instancing

Стратегии адаптации Deck.gl к различиям браузеров

Для обеспечения стабильного поведения применяется многоуровневая стратегия:

  • feature detection вместо browser detection
  • runtime проверка WebGL capabilities
  • адаптивное снижение качества рендеринга
  • динамическое переключение precision shader-ов
  • fallback на менее сложные layers

Также используется принцип деградации функциональности:

  • отключение post-processing эффектов при слабом GPU
  • уменьшение resolution scale
  • упрощение геометрии (simplification)
  • ограничение числа атрибутов

Различия в обработке событий мыши и touch

Интерактивность Deck.gl слоёв зависит от событий браузера:

  • Safari имеет особенности обработки touch events и pointer events
  • Chrome более предсказуем в pointer capture
  • Firefox иногда имеет задержки в dispatching mousemove при высокой нагрузке

Это влияет на:

  • picking (выбор объектов)
  • hover-интерактивность
  • drag interactions

В сложных сценах может наблюдаться рассинхронизация между визуальным состоянием и event state.


Системные ограничения и их влияние на архитектуру

Кроссбраузерность Deck.gl в конечном итоге определяется не только WebGL API, но и системными факторами:

  • GPU scheduling операционной системы
  • ограничения sandbox браузера
  • особенности энергосбережения ноутбуков
  • управление памятью mobile OS

В результате архитектура Deck.gl строится вокруг принципа:

  • минимизация зависимостей от конкретного браузера
  • максимальная изоляция WebGL-слоя
  • предсказуемая деградация вместо аварийного падения