Рендеринг HTML/CSS через WebGL для максимального быстродействия и безграничных возможностей анимации в Web
В последнее время в среде веб разработчиков активно развернулась дискуссия на тему «DOM — это медленно». Этот тезис действительно справедлив. Любое изменение DOM создает волну событий по всему документу и если десктопные браузеры могут справиться с такой нагрузкой, то мобильные и встроенные системы зачастую буксуют. Именно сложность DOM модели не позволяет достигнуть заветных 60 FPS, создает задержки при анимациях и всячески расстраивает пользователей и разработчиков.
Самым болезненным моментом является анимирование слоев. Решение проблемы плавной анимации — одна из основных задач кросс-платформенной Web разаработки. Активные исследования в этой области идут уже давно ( получив дополнительное ускорение в 2011 году после отказа Facebook от разработки Web приложения), однако первые системные решения были получены совсем недавно. Все они в целом делятся на два направления:
- Ускорение классических DOM операций;
- Использование альтернативных способов рендеринга контента.
И если первая ветвь — ускорение DOM уже уперлась в теоретические возможности современных API, то альтернативные методы рендеринга еще обладают большим нераскрытым потенциалом. Одним из самых значительных достижений в области создания NO DOM приложений стал React-Canvas, использующий как понятно из названия Canvas API для отображения контента, при этом он позволяет по прежнему оперировать текстовым контентом и реализовывать сетки с помощью React компонентов <Surface>, <Layer>, <Group>, <Text>, <Image>, <ListView>. Этот подход показавший неплохие результаты с точки зрения быстродействия страдает врожденными пороками вероятно не совместимыми с жизнью:
- Лучшее решение будет независимо от конкретного фреймворка и будет обладать скорее свойствами полифила для проблемы быстродействия;
- Оно не будет предлагать разработчику новые концепции и компоненты, оставляя его работать в привычном HTML/CSS окружении;
- Мир игровых движков давно прошел этап соревнования 2d Canvas / WebGL. Уже несколько лет считается общепризнанным более высокое быстродействие последнего. Идеальное решение будет использовать WebGL с фоллбеком на Canvas;
- Хорошее решение не будет лишать разработчика DOM дерева, ведь дерево позволяет отслеживать состояние приложения, эффективно отлаживать и стилизовать контент через Dev Tools.
Исходя из этих тезисов мы начали работу над своим решением проблемы «медленного DOM». Результатом исследований стал HTML GL — библиотека позволяющая рендерить HTML/CSS через WebGL, не требующая от разработчиков изучения новой предметной области или привязки к конкретному фреймворку.
Как работать с HTML GL?
GitHub репозиторий
Подключите htmlgl.js к проекту. Используйте имя тега <html-gl> для элементов которые собираетесь анимировать. Эти элементы будут отображены в WebGL, а их CSS Transform свойство станет фасадом для трансформаций их WebGL представлений. Сам DOM элемент не будет отображен или анимирован. Все трансформации происходят на GPU и касаются лишь WebGL текстуры представляющей элемент, что значительно сокращает количество расходуемых ресурсов. Отличительной особенностью HTML GL является наличие пусть скрытого, но актуального DOM дерева которое часто бывает полезно при отладке приложения.
Примеры
- FX Demo WebGL — это не только скорость, но и безграничные возможности для эффектов
- Basic HTML GL демонстрация использования HTML GL на простом контенте, выполняется анимации элемента с помощью Velocity.js, а так же трансформации через CSS Transform
- Basic DOM тот же проект, однако HTML GL отключен и все операции выполняются над DOM узлами, можно заметить, что в пик анимации слой рисуется заново, что равносильно задержке на мобильном устройстве
- Advanced content HTML GL слайдер с несколькими уровнями вложенности содержимого, отображен через HTML Gl и анимирован Velocity.js
- Advanced content DOM
«Под капотом»
Основной идеей является управляемая растеризация HTML узла и отображение результата растеризации на полноэкранной WebGL поверхности.
- На странице создается элемент web-gl
- Его контент растеризуется
- Отображается на полноэкранном WebGL контексте в виде 2d спрайта, при этом сам DOM элемент скрыт
- style.transform элемента привязаны к его WebGL представлению и при изменении трансформируют WebGL представление
- При изменении контента или стилей компонента (DOM Mutation Observers / Events) он заново растеризуется и WebGL представление обновляется
Заключение
Как видите схема работы позволяет смешивать WebGL и классический DOM контент в пределах одного приложения, не ограничивает разработчика в выборе фреймворка, не навязывает изучение дополнительных API. Просто добавьте <html-gl>