Давненько я ничего тут не писал, а сегодня как раз пятница, так что можно набросить на React рассказать о своей поделке Vidom.
Краткая история
Когда только React входил в стадию хайпа (начало 2014 года), идея virtual dom, а также всего с ним связанного (диффы, патчи), показалась мне крайне интересной и я решил осознать ее и прочувствовать через свою собственную реализацию. Я посмотрел существовавшие на тот момент имплементации, сделал несколько подходов, переписывая все несколько раз с нуля, чтобы добиться максимально производительности. Потом, постепенно, появились компоненты, хуки, контексты, серверный рендеринг, es2015 и т.д. Затем я посмотрел что людям в React доставляет боль при использовании, и одними из самых популярных проблем было: производительность серверного рендеринга и отсутствие поддержки фрагментов (этому таску в трекере реакта уже почти два года!). Засучив рукава, я добавил поддержку фрагментов. А производительность ssr в Vidom изначально была в него заложена, результат бенчмарка можно увидеть ниже.
В результате получилось:
Чем Vidom похож на React
- виртуальный DOM под капотом
- jsx
- возможность создавать свои высокоуровневые компоненты, как на основе классов, так и на основе функций
- lifecycle-хуки в компонентах на основе классов
- легкая подписка на DOM-события
- context api
- изоморфизм, ssr, возможность реиспользовать разметку, пришедшую с сервера
- плагин для chrome developer tools
Чем Vidom отличается от React
- скорость, скорость и еще раз скорость
- целевая платформа только браузеры
- поддержка фрагментов, что, позволяет, например, из одного компонента возвращать несколько других (без ненужных, и, порой, мешающих DOM-оберток) или манипулировать несколькими нодами, в том числе и DOM, как одной.
- нет необходимости расставлять key в простых случаях при использовании массивов
- размер библиотеки (примерно 10Кб после gzip)
- отсутствуют propTypes
- отсутствуют, и это главный минус, тысячи сопутствующих библиотек, таких как, react-router, react-redux и т.п. :)
Бенчмарки
Repaint rate challenge
UI bench
Server-side рендеринг (node v4.4.3, NODE_ENV=production):
Проект на github: vidom
Готов ответить на ваши вопросы, а также увидеть issue и pull request на github ;)
Комментарии (45)
Scf
24.06.2016 13:52На функционал пока не смотрел, но ТС забыл одно из самых важных преимуществ своего подхода — 16 kb gzipped. Это уже позволяет задуматься о stateless rendering людям, которым небезразлично UX на мобильных устройствах.
Судя по тому, что библиотека собрана webpack, там еще есть к чему стремиться в плане размера и скорости старта.
dfilatov
24.06.2016 13:58Вообще, в тексте, есть про это, но не про 16Кб, а про 10Кб после gzip ) Собрано, кстати, не webpack, а browserify+babelify, но да, я тоже в результирующем бандле тоже вижу много «лишнего» от babel и это меня печалит, конечно, но, пока, некритично.
Scf
24.06.2016 14:05Здесь — 16: https://cdnjs.cloudflare.com/ajax/libs/vidom/0.3.3/vidom.js
Наверное, где-то есть минимизированная версия, но я ее не нашел
Laney1
24.06.2016 15:47+2есть альтернативы и покомпактнее, например preactjs.com заявляют о 3kb
dfilatov
24.06.2016 23:23+1А вы сами его использовали? Там урезано многое, если хотите как в React, то нужно подключать уже дополнительные модули, а с ними размер, соответственно, увеличится. И я помню, что у меня коллеги хотели его использовать вместо React, но у них постоянно что-то не так работало или чего-то не хватало, в итоге они вернулись на React.
Но, самое интересное, сейчас посмотрел на бенчмарки, в которых есть Preact, он проигрывает даже React в них.
Scf
24.06.2016 14:34Когда-то на хабре была замечательная статья https://habrahabr.ru/post/235121/
Атомы с самоподпиской я удачно скрещивал с реактом, что позволяет вообще обойтись без component state и всяких-разных Flux, призванных этим состоянием управлять.
Не думали в эту сторону?
dfilatov
24.06.2016 14:41Если скрещивалось с React, то, с очень большой долей вероятности, скрестится и с Vidom. Если statefull-компоненты не нужны, то можно их и не использовать.
Pinsky
24.06.2016 14:53Роутер сделайте для Вашей библиотеки.
На выходных постараюсь посмотреть-оценить.
Насколько она production-ready? Использовали ли Вы ее в реальном мире?
justboris
24.06.2016 16:07А еще ходят слухи, что и реальный DOM не такой уж и медленный. Например, в библиотеке morphdom. Смотрели в эту сторону?
dfilatov
24.06.2016 16:21Cудя по бенчмаркам с morhpdom, гораздо медленнее. Ну и плюс есть вопросы про ключи (насколько я понял, morphdom использует id), и, особенно, про ssr.
justboris
24.06.2016 16:41Morphdom на сервере и не нужен, это же только для замены текущего состояния на новое. На сервере мы же сразу отдаем готовую строку с html, а ее можно делать и другими способами. Например, с помощью full-stack framework choo, в котором все шаблоны — template strings, а morphdom отвечает лишь за наложение diff в браузере
dfilatov
24.06.2016 17:00В repaint rate challenge morhpdom намного медленее даже react, что как бы намекает про DOM vs VDOM.
tsabir
25.06.2016 10:30morphdom на странице проекта утверждает что:
On the server, rendering directly to an HTML string will always be faster than rendering virtual DOM nodes (that then get serialized to an HTML string).
Как-то не могу уложить это у себя в голове… Что думаете об этом утверждении? Разве есть какая-то принципиальная разница html vs vdom на стороне сервера?
Ashot
25.06.2016 23:26Id он использует по умолчанию, это можно изменить. Баловался с ним для перерисовки страницы полностью — работал достаточно шустро(конкретных цифр уже не вспомню).
nuit
26.06.2016 07:54А смысл менять если он опять же будет требовать уникальные ключи на всём поддереве которое диффается, а не то как это сделано во всех нормальных либах? https://github.com/patrick-steele-idem/morphdom/blob/master/lib/index.js#L235
И игнорировать ключи со значением `0` :) https://github.com/patrick-steele-idem/morphdom/blob/master/lib/index.js#L253
И куча других багов, и работает он очень тормозно. У этой либы есть свои юзкэйсы при работе с кучей легэси говнокода, но если пишется что-то новое, то нет никакого смысла использовать морфдом.
Shannon
25.06.2016 02:50+1Всё чаще прихожу к такому же мнению. Не то что быстрее vdom, а то что не такой уж и медленный
Допустим, многих устраивает скорость react, тогда если взять тот же тест http://mathieuancelin.github.io/js-repaint-perfs/
react ~30-32fps
native dom ~24-26fps
Optimized react ~35-38fps
Optimized native dom ~39-42fps
Тоесть, как минимум видно что и dom в целом может быть быстрее
Конечно это если не сравнивать с каким нибудь vidom, который выдает ~80-110fps, и если выбор именно какой vdom, то стоит однозначно попробовать Vidom
IvanPanfilov
24.06.2016 18:36-1почему нет в сравнении фреймвёрк vanilla js?
dfilatov
24.06.2016 19:58+2Он есть в Repaint rate challenge, можете сами сравнить ;)
IvanPanfilov
26.06.2016 07:12+1имхо кривое сравнение repaint — зачем перерисовывать когда можно подставлять данные и менять пбготовленные блоки (переключать видимость «экранов» или элементов) в соответствии с состоянием.
nuit
26.06.2016 08:11+1repaint rate challenge можно ругать за другое, например за то что у них там счётчик со словом repaint rate должен быть переименован во что-нибудь типа «как часто я вызывал ping() в течении кадра», кто-то накручивает этот счётчик за счёт того что обновлюяют дом только по рафу, а пингуют по таймауту, кто-то вместо setTimeout использует setInterval, кто-то запускает в воркере и замеряет скорость того как часто будет вызываться setTimeout в воркере :)
Никто не останавливает вас от реализации самого быстрого варианта на vanilla. Вперёд, кидайте пулл риквесты: https://github.com/Rich-Harris/dom-monster, в этой репе более-менее нормальные счётчики, продемонстрируйте миру как все ошибаются, и что если писать на ванилле, то можно добиться невероятной скорости :)
JiLiZART
25.06.2016 01:59А где можно глянуть на примеры с jsx?
dfilatov
25.06.2016 08:39Например, в todomvc:
https://github.com/dfilatov/vidom-todomvc/tree/master/js/components
NeXTs_od
27.06.2016 11:03+1Почему бы не применить полученный опыт и ускорить существующий, популярный и многими полюбившийся инструмент — react?
Экосистема фронтенда перенасыщена фреймворками и комьюнити сейчас неохотно переходит на что-то другое, связка react+redux многим понравилась. Скорость которую вы добились — это круто, но я правда удивлюсь если у вас получится собрать более-менее крупное комьюнити вокруг этой библиотеки.dfilatov
27.06.2016 15:59Потому что внутри Vidom устроен совершенно по-другому, несмотря на похожее апи. Нельзя взять и просто адаптировать одно под другое. К тому же, как сами создатели React пишут, DOM — это second class citizen для них, у них другой уровень абстракции. Vidom же сосредоточен только на работу с DOM.
PQR
28.06.2016 10:32+1В мире React для управления состоянием очень популярен Redux.
Но есть и другие заметные контейнеры состояний, например, MobX https://twitter.com/ReactJSNews/status/747522375038697473
В экосистеме MobX ходят обсуждения, что React достаточно толстый, многие функции при использовании MobX являются балластом. Я даже видел предложения к автору MobX написать свой тонкий и лёгкий vritual dom. Посмотрите в эту сторону! Попробуйте написать mobx-vidom и, возможно, вы найдёте успех в растущем MobX сообществе!nuit
28.06.2016 10:41>В экосистеме MobX ходят обсуждения, что React достаточно толстый, многие функции при использовании MobX являются балластом
А тем временем в экосистеме реакта ходят обсуждения, что MobX говно https://twitter.com/sebmarkbage/status/741382155746480128xGromMx
28.06.2016 11:27Этот чел не шарит что такое FRP и путает с простыми реакциями. И да, MobX мутирует состояние, что уже не дает назвать его F
NeonXP
React Native смотрит на этот пункт грустно и с недоумением.
Статья выглядит как представление Vidom, а по сути рассказ о ± React. Может я и не прав, но кмк большая часть статьи должна быть описанием Vidom, с примерами и прочим. А про React — для затравочки.
dfilatov
Я же про это честно говорю. Но у меня и задачи такой нет (сделать аналог react native). Есть задача максимально быстро делать это в браузерах и в nodejs. Зато, за счет одной целевой платформы, есть возможность отказаться от кучи абстракций и срезать кучу углов.
NeonXP
Я неправильно прочитал, прошу прощения.
xGromMx
Что по поводу https://preactjs.com/ или https://github.com/anthonyshort/deku?
dfilatov
Про preact ниже есть коммент, а с deku в плане производительности еще более все печально.
NeonXP
А не правильно прочитал. Второй пункт это про vidom, а я читал как «Что не так в React», т.е. думал что это минусы реакта. Это мне вынесло мозг :)
raveclassic
Сходу прочитал так же, может поправить?
dfilatov
Поправил, так понятнее?
raveclassic
Так гораздо лучше, спасибо!