На этот раз вместо статьи было решено сделать видеоролик, объясняющий три немаловажные аспекта API Матрешки. Это пилотный ролик, и, если последует позитивная реакция от сообщества, в планах записать несколько видео туториалов, предположительно, в формате «Х за 60 секунд».

В ролике рассказывается о:

1. Методе реализующем одно/двусторонее связывание данных (bindNode).
2. Зависимостях одних данных от других (linkProps).
3. Возможности прослушивать изменения свойства для запуска произвольного кода.



Матрешку иногда критикуют за способ, который был выбран для связывания данных и представления. Если быть точнее, у разработчиков вызывает вопросы метод bindNode и использование селектора вместо новомодных компонентов или описания логики прямо в HTML коде.

this.bindNode('key', '.selector', binder);

В видео есть ответ на этот вопрос: вьюха — это ни более чем источник данных, событий и способ вывести данные в документ. Преимущество такого подхода в том, что вы не заморачиваетесь с представлением, а работаете с данными, не задумываясь, что произойдет, когда данные изменятся.

Это касается и коллекций, в том числе (в видео о работе с коллекциями ничего не говорится). Вы задаёте несколько правил и, при изменении коллекции, вьюха реагирует сама, а логика приложения содержится в обработчиках событий, которые реагируют на изменения.

this.on('modify', function() {
  // когда коллекция изменится, сделать что-то
}); 

this.push(obj);

Фреймворк был создан благодаря обычной лени и нежеланию хранить кучу всего в голове. Приложения создаются последовательно, шаг за шагом, так же, как и описываются ячейки в табличных процессорах: A зависит от B; B зависит от C; A не знает, от чего зависит B; C не знает, что зависит от B. Вместо A, B, C можно подставить и вьюху, и данные.

Кроме этого, с Матрешкой можно сначала описать всё, что отвечает за данные, не задумываясь, откуда они возьмутся (из кода, из вьюхи, из консоли) и куда потом попадут (во вьюху, в обработчик и пр.), а, затем, описать байндинги. Это чертовски удобно.

Репозиторий
Документация на русском

Спасибо за просмотр.

Комментарии (20)


  1. UncleAndy
    09.11.2015 13:53
    +1

    Очень быстрое видео. Вы не оставляете время зрителю на то, что-бы посмотреть и оценить что именно происходит. Даже паузу поставить сложно в нужный момент.


    1. Finom
      09.11.2015 13:58

      Да, вы правы.


  1. lega
    09.11.2015 14:29

    Вы не сравнивали defineProperty с Proxy по скорости?
    Сколько суммарно ушло времени на создание этого ролика?


    1. Finom
      09.11.2015 14:38

      Нет, не сравнивал. Но, теоретически, defineProperty быстрее, так как в нем указывается какие свойства нужно «слушать». Proxy «слушает» все изменения (как и Object.observe, который выпиливают из спецификации).

      Суммарно — могу сказать лишь примерно. Половина времени была затрачена на то, чтоб разобраться с Audacity и Kdenlive. Если брать только монтаж, то на половину ролика ушло 2 часа (т. е. примерно 4 часа на монтаж 6 минутного ролика). Сценарий, примеры, запись голоса, думаю, около 3 часов.


    1. Finom
      09.11.2015 15:38
      +3

      Кстати, вы как-то просили добавить Матрешку в «местный бенчмарк». Вот он.


      1. lega
        10.11.2015 00:58

        Спасибо.

        Начал причесывать эти тесты и наткнулся на аномалию — в хроме рендеринг проседает до 80% на пустом месте, анализировал профайлеры и таймлайны, гуглил — ничего. Оказалось, это проседание зависит от первых двух выводимых символов: «mk»/«ng»/«vj» (кто бы мог подумать), и это воспроизводится систематический, я уже подобрал «оптимальные» символы. В FF это не воспроизводится — работает нормально. Сделаю всем тестам одинаковый текст, что-бы было по честному.


        1. Finom
          10.11.2015 15:16

          Я немного сомневаюсь в этом тесте. Рендеринг (или серверный пререндеринг) большого количества элементов вызывает тормоза страницы, которые решаются костылями, типа этого. Может, сделаете многократную перерисовку меньшего числа элементов?

          Просто мысли в слух: в идеале хотелось бы получить альтернативу jsperf, который объективно замеряет скорость операций. В jsperf я разочеровался после этого теста. Консольный тест с jsperf расходится в 450 раз!


          1. lega
            10.11.2015 16:41

            Я немного сомневаюсь в этом тесте.
            У всех тестов есть свои недостатки. Я кстати перетащил его на гитхаб.
            Вот этот тест замеряет только перерисовку, а в «хабра» тесте есть ещё и первичное построение, что тоже важно.

            Будет время — попробую сделать быструю перерисовку меньшего кол-ва, хотя у меня появилась проблема с Basis.js lahmatiy — в хроме почему-то не всегда учитывается время рендеренга, даже если несколько раз вызвать setTimeout, из-за этого он иногда выдает цифры ниже/лучше чем у vanilla js.

            В jsperf я разочеровался после этого теста.
            JSperf вообще испортился — баги, кривые замеры, да ещё и редактировать не удобно.


            1. lahmatiy
              10.11.2015 18:57

              Цифры basis.js ниже/лучше чем у vanilla, потому что vanilla решение написано не оптимально. А перепады в цифрах, скорей всего говорят об оптимизациях/деоптимизациях и каких-то подкапотных процессах браузера, которые оказывают достаточно сильное влияние.


              1. lega
                10.11.2015 20:52

                vanilla решение написано не оптимально
                Нет, оно нормальное, их 2 варианта и один из них использует DocumentFragment, попробуйте написать более быстрое решение. Тем более 80% тратится не на построение DOM, а на рендеринг.

                и каких-то подкапотных процессах браузера
                Да, я выше озвучил причину — не учитывается время рендеринга, если вы проанализируете Timeline, то видно что во всех тестах самые ресурсоемкие операции «Layout» и «Update Layer Tree» срабатывают до фиксации времени — что правильно, а в тесте «basis fill» иногда эти операции «проскакивают» за фиксацию времени, т.е. как раз самые тяжелые операции, которые создал basis, не зачитались в результате.

                Можно конечно сделать setTimeout побольше (например 10), но это неправильный костыль. Кстати надо попробовать requestAnimationFrame, возможно это решит проблему.


              1. lega
                10.11.2015 21:53

                Применил requestAnimationFrame, теперь вся* нагрузка отражается в операции «Layout», и цифры не «скачут».


                1. Finom
                  11.11.2015 00:10

                  А ссылку можно?


                  1. lega
                    11.11.2015 00:43

                    Вот, я её в комментах выше привел, правда она там не приметная.


                    1. Finom
                      11.11.2015 23:00

                      Спасибо. Только не очевидно, как это юзать. Может, в айфрейме запускать тесты?


                1. lahmatiy
                  11.11.2015 22:12

                  vanilla решение написано не оптимально

                  Беру свои слова обратно. Там действительно все ок.
                  Только во втором решении не увидел, где используется DocumentFragment. Код обоих решений идентичен, за исключением одно цифры ;)


                  1. lega
                    11.11.2015 23:23

                    где используется DocumentFragment
                    Потерял при переносе, поправил.


  1. Irrra
    09.11.2015 18:29
    +2

    Отличная статья! Просто и доступно рассказано, вам удалось меня заинтересовать!
    Спасибо!)


    1. Finom
      09.11.2015 18:36
      +1

      Спасибо, приятно слышать.


  1. HomoLuden
    10.11.2015 15:48

    Матрешку иногда критикуют за способ, который был выбран для связывания данных и представления. Если быть точнее, у разработчиков вызывает вопросы метод bindNode и использование селектора вместо новомодных компонентов или описания логики прямо в HTML коде.


    По такому же пути прошел (и «пришел» в смысле «докатился») WPF.
    На практике многим уже приходится писать свой или грызть чужой велосипед, позволяющий в биндинге декларативно описывать логику (в смысле всяких трансформаций или арифметических выражений).
    Иначе нужно будет плодить кучу конвертеров либо копипастить с незначительными изменениями куски кода в VM части (не знаю как слой «под UI» называется в терминах матрёшки, уж простите).


    1. Finom
      10.11.2015 16:01

      Не вижу смысла копипастить. Матрешка — фреймворк с наследованием. Если у вас есть несколько общих черт нескольких виджетов, создайте общий класс.

      Вьюху можно назвать «байндингами».