render(element, vnodes)
Описание
Выполняет рендеринг виртуального DOM в указанный DOM-элемент.
m.render(document.body, 'hello');
// <body>hello</body>
Сигнатура
m.render(element, vnodes, redraw)
Аргумент | Тип | Обязательный | Описание |
---|---|---|---|
element | Element | Да | DOM-элемент, который будет являться родительским узлом для отрисованного поддерева. |
vnodes | Array<Vnode>|Vnode | Да | Виртуальные узлы, которые необходимо отобразить. |
redraw | () -> any | Нет | Функция обратного вызова, вызываемая при каждом срабатывании обработчика событий в поддереве. |
возвращает | Возвращает undefined |
Как это работает
Метод m.render(element, vnodes)
принимает дерево виртуального DOM (обычно создаваемое с помощью функции m()
hyperscript), генерирует соответствующее DOM-дерево и монтирует его в element
. Если element
уже содержит DOM-дерево, смонтированное предыдущим вызовом m.render()
, vnodes
сравнивается с предыдущим деревом vnodes
, и существующее DOM-дерево обновляется только в тех местах, где это необходимо для отражения изменений. Неизмененные DOM-узлы остаются без изменений.
Если передать необязательный аргумент redraw
, он будет вызываться каждый раз, когда срабатывает обработчик событий в любом месте поддерева. Это используется в m.mount
и m.redraw
для реализации функциональности autoredraw, но также может быть полезно в более сложных сценариях, например, при интеграции со сторонними фреймворками.
m.render
выполняется синхронно.
Почему Virtual DOM
Может показаться, что генерация дерева виртуальных узлов при каждой перерисовке является избыточной, но создание и сравнение структур данных JavaScript оказывается на удивление дешевым по сравнению с чтением и изменением DOM.
Работа с DOM может быть ресурсоемкой по нескольким причинам. Чередование операций чтения и записи может негативно влиять на производительность, вызывая несколько последовательных перерисовок браузера, в то время как сравнение деревьев виртуального DOM позволяет объединять операции записи в одну перерисовку. Кроме того, производительность различных операций DOM может отличаться в разных реализациях, и ее может быть трудно изучить и оптимизировать для всех браузеров. Например, в некоторых реализациях чтение childNodes.length
имеет сложность O(n); в некоторых чтение parentNode
вызывает перерисовку и т. д.
В отличие от этого, обход структуры данных JavaScript имеет гораздо более предсказуемый и стабильный профиль производительности, и, кроме того, дерево vnode устроено таким образом, что позволяет современным движкам JavaScript применять агрессивные оптимизации, такие как скрытые классы, для еще большей производительности.
Отличия от других методов API
Метод m.render()
внутренне вызывается m.mount()
, m.route()
, m.redraw()
и m.request()
. Он не вызывается после обновлений stream.
В отличие от m.mount()
и m.route()
, дерево vnode, отображаемое с помощью m.render()
, не перерисовывается автоматически в ответ на события view, вызовы m.redraw()
или вызовы m.request()
. Это низкоуровневый механизм, предназначенный для разработчиков библиотек, которые хотят вручную управлять рендерингом, а не полагаться на встроенную систему автоматического обновления Mithril.js.
Другое отличие состоит в том, что метод m.render
ожидает vnode (или массив vnodes) в качестве второго параметра, в то время как m.mount()
и m.route()
ожидают компоненты.
Автономное использование
var render = require("mithril/render")
Модуль m.render
сопоставим по функциональности с библиотеками view, такими как Knockout, React и Vue. Он реализует механизм сравнения виртуального DOM с современным алгоритмом сокращения пространства поиска и переиспользованием DOM, что обеспечивает высокую производительность как при начальной загрузке страницы, так и при повторном рендеринге. Он не зависит от других частей Mithril.js, кроме нормализации, предоставляемой через require("mithril/render/vnode")
, и может использоваться как автономная библиотека.
Модуль render
является полностью функциональным и самодостаточным. Он поддерживает все, что можно ожидать: SVG, пользовательские элементы и все допустимые атрибуты и события - без каких-либо необычных чувствительных к регистру случаев или исключений. Конечно, он также полностью поддерживает компоненты и методы жизненного цикла.
При использовании m.render
в качестве автономного модуля может быть полезно также импортировать hyperscript function
для создания виртуальных узлов, которые будут отображаться.