Виртуальный DOM (англ. ) — легковесное JS-представление объектной модели документа (DOM), используемое в декларативных веб-фреймворках, таких как React, Vue.js и Elm. Поскольку создание виртуального DOM происходит относительно быстро, любой фреймворк может выполнять повторную отрисовку виртуального DOM столько раз, сколько необходимо, с относительно низкими затратами. Затем фреймворк может найти различия между предыдущим и текущим виртуальным DOM (этот процесс называется сравнением или diffing) и внести только необходимые изменения в реальный DOM (этот процесс называется согласованием или reconciliation). Хотя технически этот подход медленнее, чем использование чистого JavaScript, он значительно упрощает написание сайтов с большим количеством динамического контента, поскольку разметка напрямую связана с состоянием.

К схожим техникам относятся Glimmer во фреймворке Ember.js и инкрементальный DOM в Angular.

История Исторически API для работы с DOM в JavaScript был неконсистентным в разных браузерах, неудобным в использовании и трудномасштабируемым для крупных проектов. Хотя библиотеки, такие как jQuery, были нацелены на улучшение общей согласованности и эргономики взаимодействия с HTML, они также были подвержены повторяющемуся коду, который плохо описывал природу вносимых изменений и отделял логику от разметки.

Выпуск AngularJS в 2010 году привёл к серьёзному сдвигу парадигмы во взаимодействии между JavaScript и HTML благодаря идее «грязной» проверки (dirty checking). Вместо императивного объявления и уничтожения обработчиков событий и изменения отдельных узлов DOM, отслеживались изменения переменных, а секции DOM помечались как «грязные» и перерисовывались при изменении переменной в их области видимости. Этот «цикл digest» предоставил фреймворк для написания более декларативного кода, который связывал логику и разметку более логичным образом.

Хотя AngularJS стремился предоставить более декларативный опыт, он по-прежнему требовал явной привязки данных к DOM и их отслеживания, а также вызывал опасения по поводу производительности из-за дорогостоящего процесса «грязной» проверки сотен переменных. Для решения этих проблем React стал первой крупной библиотекой, принявшей на вооружение виртуальный DOM в 2013 году. Это устранило как узкие места в производительности (поскольку сравнение и согласование DOM стали относительно дешёвыми операциями), так и сложность привязки данных (поскольку компоненты по сути стали просто объектами). Другие преимущества виртуального DOM включали повышенную безопасность, поскольку XSS-атаки стали практически невозможными, и лучшую расширяемость, так как состояние компонента было полностью инкапсулировано. Его выпуск также совпал с появлением JSX, который ещё теснее связал HTML и JavaScript с помощью синтаксического расширения, похожего на XML.

После успеха React многие другие веб-фреймворки скопировали общую идею идеального представления DOM в памяти, например, Vue.js в 2014 году, который использовал компилятор шаблонов вместо JSX и имел встроенную гранулярную реактивность.

В последнее время виртуальный DOM подвергается критике за медлительность из-за дополнительного времени, необходимого для сравнения и согласования узлов DOM. Это привело к разработке фреймворков без виртуального DOM, таких как Svelte, и фреймворков, которые редактируют DOM «на месте», таких как Angular (начиная со второй версии).

Реализации

React React был пионером в использовании виртуального DOM для декларативного создания компонентов. Узлы виртуального DOM создаются с помощью функции createElement(), но чаще всего они транспилируются из JSX, чтобы сделать написание компонентов более эргономичным. В классовых компонентах React узлы виртуального DOM возвращаются из функции render(), в то время как в функциональных компонентах на основе хуков возвращаемое значение самой функции служит разметкой страницы.

Vue.js Vue.js использует виртуальный DOM для обработки изменений состояния, но, как правило, разработчики не взаимодействуют с ним напрямую; вместо этого компилятор преобразует HTML-шаблоны в узлы виртуального DOM, что является деталью реализации. Хотя Vue поддерживает написание JSX и пользовательских рендер-функций, более типичным является использование компилятора шаблонов, так как в этом случае не требуется этап сборки.

Svelte В Svelte нет виртуального DOM. Его создатель, Рич Харрис, назвал виртуальный DOM «чистыми накладными расходами». Вместо сравнения и согласования узлов DOM во время выполнения, Svelte использует реактивность на этапе компиляции для анализа разметки и генерации JavaScript-кода, который напрямую манипулирует DOM, что значительно повышает производительность.

См. также Shadow DOM

Примечания

Категория:Веб-разработка Категория:Объектные модели