Виртуальный DOM
Виртуальный DOM — это концепция в веб-разработке, представляющая собой облегчённую копию реальной объектной модели документа (DOM), которая используется в декларативных фреймворках, включая React, Vue.js и Elm. Основное преимущество данного подхода заключается в высокой скорости создания такого представления, что позволяет фреймворку многократно перестраивать виртуальное дерево с минимальными затратами ресурсов. После каждого изменения система сравнивает новое состояние виртуального DOM с предыдущим (процесс, известный как диффинг) и вносит в реальный DOM только те правки, которые действительно необходимы (согласование). Несмотря на то, что прямой манипуляции DOM на чистом JavaScript может быть быстрее, виртуальный DOM существенно упрощает разработку сложных динамических интерфейсов, поскольку разметка напрямую зависит от состояния приложения.
Аналогичные методики применяются в других технологиях, например, Glimmer в Ember.js и инкрементальный DOM в Angular.
- История
Изначально API для взаимодействия с DOM в JavaScript отличался несогласованностью между браузерами, неудобством использования и сложностью масштабирования в больших проектах. Библиотеки вроде jQuery улучшили эргономику работы с HTML, однако порождали шаблонный код, плохо отражающий семантику изменений и разделяющий логику и разметку.
С выходом AngularJS в 2010 году произошёл значительный сдвиг в подходах к взаимодействию JavaScript и HTML благодаря механизму «грязной» проверки. Вместо прямого управления обработчиками и узлами DOM фреймворк отслеживал изменения переменных, а связанные с ними участки интерфейса помечались как требующие обновления. Это позволило писать более декларативный код, теснее связывающий логику и представление.
Однако AngularJS сохранял необходимость явной привязки данных и мог страдать от проблем производительности из-за ресурсоёмкой проверки множества переменных. Решением этих недостатков стало появление React в 2013 году, который первым широко внедрил виртуальный DOM. Такой подход устранил узкие места производительности за счёт оптимизированного сравнения деревьев, а также упростил привязку данных, поскольку компоненты стали представлять собой автономные объекты. Дополнительными преимуществами стали повышенная безопасность (сведение к минимуму рисков XSS) и лучшая масштабируемость благодаря инкапсуляции состояния. Распространению React способствовало и появление JSX — синтаксического расширения, интегрирующего HTML-подобную разметку в JavaScript.
Успех React стимулировал adoption виртуального DOM в других фреймворках. Например, Vue.js, выпущенный в 2014 году, использовал компилятор шаблонов вместо JSX и предлагал встроенную реактивность.
В последние годы виртуальный DOM критикуют за издержки производительности, связанные с необходимостью сравнения деревьев. Это привело к развитию альтернативных подходов, таких как компиляция в момент сборки (Svelte) или прямое манипулирование DOM (Angular, начиная с версии 2).
- Реализации
- React
React стал первопроходцем в применении виртуального DOM для декларативного построения компонентов. Элементы виртуального дерева создаются с помощью функции createElement(), однако на практике чаще используется трансляция из JSX, что делает код более наглядным. В классовых компонентах разметка возвращается методом render(), а в функциональных компонентах с хуками — непосредственно функцией компонента.
- Vue.js
Vue.js задействует виртуальный DOM для отслеживания изменений состояния, но разработчики обычно работают с HTML-шаблонами, которые компилируются в виртуальные узлы. Хотя поддерживаются рендер-функции и JSX, стандартным подходом остаётся использование шаблонов, не требующих этапа сборки.
- Svelte
Svelte отказался от виртуального DOM в пользу компиляции в эффективный JavaScript-код, напрямую обновляющий DOM. По словам создателя фреймворка Рича Харриса, виртуальный DOM представляет собой «избыточные накладные расходы». Прекомпиляция позволяет генерировать оптимальный код, что положительно сказывается на производительности.
- См. также
- Веб-компоненты#Shadow DOM
- Примечания
Ссылки[править | править код]
- http://elmprogramming.com/|access-date=2020-12-11|website=Elm
- https://reactjs.org/docs/faq-internals.html|access-date=2020-12-11|website=reactjs.org|language=en}}
- https://www.codecademy.com/articles/react-virtual-dom|access-date=2020-12-11|website=Codecademy|language=en}}
- https://github.com/google/incremental-dom|access-date=2020-12-11|lang=en}}
- https://auth0.com/blog/face-off-virtual-dom-vs-incremental-dom-vs-glimmer/|access-date=2020-12-11|website=Auth0
- https://learn.jquery.com/using-jquery-core/jquery-object/|title=The
- http://teropa.info/blog/2013/11/03/make-your-own-angular-part-1-scopes-and-digest.html
- https://web.archive.org/web/20140130084907/http://teropa.info/blog/2013/11/03/make-your-own-angular-part-1-scopes-and-digest.html
- https://blog.core10.io/2019/04/10/the-death-of-angularjs
- https://www.youtube.com/watch?v=x7cQ3mrcKaY
- https://legacy.reactjs.org/blog/2013/06/05/why-react.html
- https://v2.vuejs.org/v2/guide/reactivity.html#How-Changes-Are-Tracked
- https://svelte.dev/blog/virtual-dom-is-pure-overhead
- https://react.dev/learn/writing-markup-with-jsx
- https://vuejs.org/guide/extras/rendering-mechanism.html
- https://vuejs.org/guide/extras/render-function.html
- https://svelte.dev/blog/svelte-3-rethinking-reactivity
- http://elmprogramming.com/
- https://reactjs.org/docs/faq-internals.html
- https://www.codecademy.com/articles/react-virtual-dom
- https://github.com/google/incremental-dom
- https://auth0.com/blog/face-off-virtual-dom-vs-incremental-dom-vs-glimmer/
- https://learn.jquery.com/using-jquery-core/jquery-object/