Давненько я ничего тут не писал, а сегодня как раз пятница, так что можно набросить на 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)


  1. NeonXP
    24.06.2016 13:36
    +1

    целевая платформа только браузеры

    React Native смотрит на этот пункт грустно и с недоумением.

    Статья выглядит как представление Vidom, а по сути рассказ о ± React. Может я и не прав, но кмк большая часть статьи должна быть описанием Vidom, с примерами и прочим. А про React — для затравочки.


    1. dfilatov
      24.06.2016 13:43
      +3

      Я же про это честно говорю. Но у меня и задачи такой нет (сделать аналог react native). Есть задача максимально быстро делать это в браузерах и в nodejs. Зато, за счет одной целевой платформы, есть возможность отказаться от кучи абстракций и срезать кучу углов.


      1. NeonXP
        24.06.2016 13:44

        Я неправильно прочитал, прошу прощения.


      1. xGromMx
        26.06.2016 23:05

        Что по поводу https://preactjs.com/ или https://github.com/anthonyshort/deku?


        1. dfilatov
          28.06.2016 16:29

          Про preact ниже есть коммент, а с deku в плане производительности еще более все печально.


    1. NeonXP
      24.06.2016 13:44

      А не правильно прочитал. Второй пункт это про vidom, а я читал как «Что не так в React», т.е. думал что это минусы реакта. Это мне вынесло мозг :)


      1. raveclassic
        24.06.2016 14:59

        Сходу прочитал так же, может поправить?


        1. dfilatov
          24.06.2016 14:59

          Поправил, так понятнее?


          1. raveclassic
            24.06.2016 16:19

            Так гораздо лучше, спасибо!


  1. Scf
    24.06.2016 13:52

    На функционал пока не смотрел, но ТС забыл одно из самых важных преимуществ своего подхода — 16 kb gzipped. Это уже позволяет задуматься о stateless rendering людям, которым небезразлично UX на мобильных устройствах.


    Судя по тому, что библиотека собрана webpack, там еще есть к чему стремиться в плане размера и скорости старта.


    1. dfilatov
      24.06.2016 13:58

      Вообще, в тексте, есть про это, но не про 16Кб, а про 10Кб после gzip ) Собрано, кстати, не webpack, а browserify+babelify, но да, я тоже в результирующем бандле тоже вижу много «лишнего» от babel и это меня печалит, конечно, но, пока, некритично.


      1. Scf
        24.06.2016 14:05

        Здесь — 16: https://cdnjs.cloudflare.com/ajax/libs/vidom/0.3.3/vidom.js
        Наверное, где-то есть минимизированная версия, но я ее не нашел


        1. dfilatov
          24.06.2016 14:06

          Там же: https://cdnjs.cloudflare.com/ajax/libs/vidom/0.3.3/vidom.min.js


    1. Laney1
      24.06.2016 15:47
      +2

      есть альтернативы и покомпактнее, например preactjs.com заявляют о 3kb


      1. dfilatov
        24.06.2016 23:23
        +1

        А вы сами его использовали? Там урезано многое, если хотите как в React, то нужно подключать уже дополнительные модули, а с ними размер, соответственно, увеличится. И я помню, что у меня коллеги хотели его использовать вместо React, но у них постоянно что-то не так работало или чего-то не хватало, в итоге они вернулись на React.


        Но, самое интересное, сейчас посмотрел на бенчмарки, в которых есть Preact, он проигрывает даже React в них.


  1. Scf
    24.06.2016 14:34

    Когда-то на хабре была замечательная статья https://habrahabr.ru/post/235121/
    Атомы с самоподпиской я удачно скрещивал с реактом, что позволяет вообще обойтись без component state и всяких-разных Flux, призванных этим состоянием управлять.


    Не думали в эту сторону?


    1. dfilatov
      24.06.2016 14:41

      Если скрещивалось с React, то, с очень большой долей вероятности, скрестится и с Vidom. Если statefull-компоненты не нужны, то можно их и не использовать.


  1. Pinsky
    24.06.2016 14:53

    Роутер сделайте для Вашей библиотеки.
    На выходных постараюсь посмотреть-оценить.

    Насколько она production-ready? Использовали ли Вы ее в реальном мире?


    1. dfilatov
      24.06.2016 14:56

      Production-ready. Запущено уже несколько внутренних веб-приложений.


      1. Pinsky
        24.06.2016 15:00

        Про роутер — это была просьба, надеюсь, что грубо не прозвучала.


        1. dfilatov
          24.06.2016 15:07
          +1

          Был бы рад помощи в этом месте. Я не могу чисто физически написать все сопутствующие библиотеки.


          1. Pinsky
            24.06.2016 18:05

            Хоть и больше бэкендер, но если библиотека у меня приживется в своих проектах — постараюсь заняться роутером, если никто вперед меня его не сделает.


  1. justboris
    24.06.2016 16:07

    А еще ходят слухи, что и реальный DOM не такой уж и медленный. Например, в библиотеке morphdom. Смотрели в эту сторону?


    1. nuit
      24.06.2016 16:12

      А ещё ходят слухи, что не нужно верить всему что пишут в интернетах.


    1. dfilatov
      24.06.2016 16:21

      Cудя по бенчмаркам с morhpdom, гораздо медленнее. Ну и плюс есть вопросы про ключи (насколько я понял, morphdom использует id), и, особенно, про ssr.


      1. justboris
        24.06.2016 16:41

        Morphdom на сервере и не нужен, это же только для замены текущего состояния на новое. На сервере мы же сразу отдаем готовую строку с html, а ее можно делать и другими способами. Например, с помощью full-stack framework choo, в котором все шаблоны — template strings, а morphdom отвечает лишь за наложение diff в браузере


        1. dfilatov
          24.06.2016 17:00

          В repaint rate challenge morhpdom намного медленее даже react, что как бы намекает про DOM vs VDOM.


      1. tsabir
        25.06.2016 10:30

        morphdom на странице проекта утверждает что:

        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 на стороне сервера?


      1. Ashot
        25.06.2016 23:26

        Id он использует по умолчанию, это можно изменить. Баловался с ним для перерисовки страницы полностью — работал достаточно шустро(конкретных цифр уже не вспомню).


        1. 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

          И куча других багов, и работает он очень тормозно. У этой либы есть свои юзкэйсы при работе с кучей легэси говнокода, но если пишется что-то новое, то нет никакого смысла использовать морфдом.


    1. 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


  1. IvanPanfilov
    24.06.2016 18:36
    -1

    почему нет в сравнении фреймвёрк vanilla js?


    1. Pinsky
      24.06.2016 19:06
      +1

      Трудозатраты(и читаемость кода) при написании ПО тоже стоит учитывать.


    1. dfilatov
      24.06.2016 19:58
      +2

      Он есть в Repaint rate challenge, можете сами сравнить ;)


      1. IvanPanfilov
        26.06.2016 07:12
        +1

        имхо кривое сравнение repaint — зачем перерисовывать когда можно подставлять данные и менять пбготовленные блоки (переключать видимость «экранов» или элементов) в соответствии с состоянием.


        1. nuit
          26.06.2016 08:11
          +1

          repaint rate challenge можно ругать за другое, например за то что у них там счётчик со словом repaint rate должен быть переименован во что-нибудь типа «как часто я вызывал ping() в течении кадра», кто-то накручивает этот счётчик за счёт того что обновлюяют дом только по рафу, а пингуют по таймауту, кто-то вместо setTimeout использует setInterval, кто-то запускает в воркере и замеряет скорость того как часто будет вызываться setTimeout в воркере :)

          Никто не останавливает вас от реализации самого быстрого варианта на vanilla. Вперёд, кидайте пулл риквесты: https://github.com/Rich-Harris/dom-monster, в этой репе более-менее нормальные счётчики, продемонстрируйте миру как все ошибаются, и что если писать на ванилле, то можно добиться невероятной скорости :)


  1. JiLiZART
    25.06.2016 01:59

    А где можно глянуть на примеры с jsx?



  1. NeXTs_od
    27.06.2016 11:03
    +1

    Почему бы не применить полученный опыт и ускорить существующий, популярный и многими полюбившийся инструмент — react?
    Экосистема фронтенда перенасыщена фреймворками и комьюнити сейчас неохотно переходит на что-то другое, связка react+redux многим понравилась. Скорость которую вы добились — это круто, но я правда удивлюсь если у вас получится собрать более-менее крупное комьюнити вокруг этой библиотеки.


    1. dfilatov
      27.06.2016 15:59

      Потому что внутри Vidom устроен совершенно по-другому, несмотря на похожее апи. Нельзя взять и просто адаптировать одно под другое. К тому же, как сами создатели React пишут, DOM — это second class citizen для них, у них другой уровень абстракции. Vidom же сосредоточен только на работу с DOM.


  1. unel
    27.06.2016 18:27

    Скорость и правда впечатляет)
    Интересно, какие именно отличия от реакта дают основной прирост по скорости? Неужели propTypes?..


    1. dfilatov
      28.06.2016 10:15

      propTypes в режиме production отключен у React


  1. 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 сообществе!


    1. nuit
      28.06.2016 10:41

      >В экосистеме MobX ходят обсуждения, что React достаточно толстый, многие функции при использовании MobX являются балластом

      А тем временем в экосистеме реакта ходят обсуждения, что MobX говно https://twitter.com/sebmarkbage/status/741382155746480128


      1. xGromMx
        28.06.2016 11:27

        Этот чел не шарит что такое FRP и путает с простыми реакциями. И да, MobX мутирует состояние, что уже не дает назвать его F