image22 ноября года сиего вышло обновление Riot.js — минималистичной библиотеки для создания веб-интерфейсов. Как пишут её авторы на главной странице своего сайта, Riot.js — это «Simple and elegant component-based UI library». И она действительно очень простая и элегантная.

Я большой поклонник данного изобретения. Оно не забивает мой мозг лишней логикой, правилами и принципами. Оно даёт мне очень простое API для создания вложенных друг в друга компонентов и даёт возможность в действительно короткие сроки реализовать то, что мне требуется.

Для меня программирование и API различных популярных библиотек всегда было чем-то похожим на математику. На основе чего работает вся математика? На основе чистых и минималистичных формул, доведённых до совершенства. За время существования этой науки человечество смогло довести различные сложнейшие идеи до коротких и чистых выражений. И примерно тем же самым занимаются и хорошие библиотеки и фреймворки в мире программирования. Они предоставляют инженерам ПО простой и понятный API для решения проблем. Все мы знаем jQuery с его короткими и лаконичными методами для работы в браузере и её девиз "write less, do more". Или, скажем, многие знают о такой замечательной библиотеке, как Sugar.js для добавления разумной порции сахарка вашим глобальным объектам JavaScript. И Riot.js — в точности об этом же, только на тему веб-компонентов с учётом всех последних тенденций в эволюции веб-технологий.

В совокупности с Pug-шаблонизатором, ваши веб-компоненты на основе Riot.js могут выглядеть как-нибудь вот так:

login-form

    .login-title Авторизация

    p Введите данные вашей учетной записи:

    .login-form
        form(method='POST', action='/auth/login')
            .login-field
                .login-label
                    label(for='email') E-mail
                input(type='email' name='email')

            .login-field
                .login-label
                    label(for='password') Пароль
                input(type='password' name='password' id='password')

            .login-button
                button.senddata(type='primary') Войти

            .login-links
                span.link.clickable(onclick="{ openPasswordForm }") Забыли пароль?
                span.link.clickable(onclick='{ openRegisterForm }') Регистрация

    script.
        /* JS логика вашего компонента */
        var tag = this

        tag.openRegisterForm = function() {
            RegisterForm.open()
        }

        tag.openPasswordForm = function() {
            PasswordForm.open()
        }

    style.
        /* Стили вашего компонента */

Это — практически стандартный HTML вместе со стандартным JS, при этом, он позволяет разбивать ваш код на независимые компоненты и инкапсулировать их логику и представление в отдельных и ясных сущностях, также, как это можно делать в React.js, к примеру. Есть всего несколько моментов, которые надо знать о работе Riot.js, чтобы начать на нём писать. Это вам не дока по Angular 2.0 (я даже думать не хочу о том, чтобы сидеть и читать всю эту гору документов. Сколько времени уйдёт на это?).

Версия 3.0 не принесла никаких кардинальных изменений. Практически всё осталось работать точно также, как оно работало и ранее. Библиотека просто стала ещё более вылизанной и доработанной. Была исправлена масса мелких и тонких проблем.

Пара слов о проблемах Riot.js


Всё это конечно прекрасно, но если я не расскажу о проблемах, с которыми вы, возможно, столкнётесь при работе с данной библиотекой, я не буду достаточно правдив с вами. Как ни крути, но Riot.js медленнее своих конкурентов (единственное — версия 3.0 вроде как должна быть более производительной, а в данных тестах проверяется вторая ветка библиотеки. Также следует иметь ввиду, что команда Riot.js в данный момент нацелена на увеличение скорости рендеринга компонентов и считает это своей целью на ближайшее будущее).

Где это может создать проблемы? Ну, скажем, у нас на том проекте, разработкой которого мы тут занимаемся, возникли проблемы с серверным рендером одного модуля, в котором у нас имеется 5-6 уровней вложенности компонентов. Так надо, по-другому невозможно написать этот модуль. Наш сервер на Digital Ocean рендерил этот модуль около 20-30 секунд на один запрос. Это очень уж много. Но покупать какой-нибудь выделенный сервер на Хетзнере только для того, чтобы решить эту проблему, как-то не хотелось. В итоге мы переписали конкретно данный компонент на React.js, после чего серверный рендеринг этого компонента начал отрабатывать за 5-10 секунд, что уже является вполне приемлемым для нас вариантом на данный момент (мы используем серверный рендеринг только для поисковых ботов, так что обычные пользователи не ждут 5-10 секунд до начала открытия страницы, для них контент просто рендерится в их браузерах).

В то же время, если рассуждать о производительности дальше, то я уже давно смотрю в сторону Inferno: посмотрите ещё раз на таблицу производительности библиотек. Эта библиотека практически идёт один в один с тестами на основе ванильного JS. Если честно, это действительно впечатляет. Быть может, попробовать писать сложные интерфейсы на ней? Кроме всего прочего, её явным плюсом является практически полная совместимость её API с React.js. То есть, чтобы начать работать с Inferno, вам не придётся ничего учить, если вы уже знаете React.

Также хочется отметить, что React, возможно, будет более предпочтителен для выбора, если вы собрались писать изоморфное приложение, которое будет рендерить клиентам контент со стороны сервера, так как он позволяет рендерить контент на сервере методом renderToString, благодаря которому ваш React-компонент на стороне браузера лишь навесит на созданный сервером DOM свои прослушиватели событий, избавив браузер пользователя от дополнительной нагрузки, чего в данный момент не поддерживает Riot.js: вы сможете отрендерить со стороны сервера свой контент, но он всё равно потом будет рендериться библиотекой повторно ещё и на стороне браузера.

Как мы выяснили, Riot.js более медлителен на сложных компонентах с большим количеством уровней вложенности. Но согласитесь, мы не так уж часто пишем веб-интерфейсы такой сложности?

Хотя мы и переписали один модуль нашего проекта на React.js, я всё ещё считаю Riot.js более приоритетной библиотекой для разработки фронтенд-компонентов. Причина в том, что он предоставляет более простой и лаконичный синтаксис. Он содержит в себе очень маленький набор функций, но при этом их как раз столько, сколько нужно. Riot.js не забивает мою голову сложными абстракциями, правилами, ограничениями и прочим птичьим языком. Он просто даёт мне чистое API для решения моих проблем. А что мне должно быть нужно ещё в моей работе?
Поделиться с друзьями
-->

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


  1. k12th
    25.11.2016 00:41

    О, Pug поддерживается, отлично.


    Было бы интересно помимо react сравнить еще с vue (который сейчас активно пиарится и по производительности ± наравне с react). Не пробовали?


    1. saggid
      25.11.2016 00:45

      Vue.js тоже очень даже, ещё и по скорости работы хорош. Но он отталкивает меня банально тем, что он более усложнён чем Riot.js :) Плюс, до версии 2.0 у Vue.js отсутствовал серверный рендер, что сыграло решающую роль. Ибо серверный рендер нам нужен.


    1. faiwer
      25.11.2016 07:50
      +1

      Увидев pug сильно удивился. Как две капли воды похож на Jade. Полез на github, и правда:


      This project was formerly known as "Jade."

      Не удивительно :)


      1. vlreshet
        25.11.2016 09:24
        +1

        Это и есть Jade, просто его переименовали в Pug из-за авторских прав на название Jade. Мол есть там какая-то софтверная контора с таким же названием, и они начали кипишевать. А название Pug им вроде кто-то подарил, с авторскими правами и всем таким.


  1. nuit
    25.11.2016 06:25
    +3

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

    Если хочется чего-то похожего, то есть vue.js. Правда меня беспокоит отношение его автора к некоторым кроссбраузерным проблемам, к примеру https://github.com/vuejs/vue/issues/3722. React.js в этом плане гораздо лучше, и для неопытных девелоперов гораздо больше подойдёт, тк решает очень много подобных проблем.

    >В то же время, если рассуждать о производительности дальше, то я уже давно смотрю в сторону Inferno: посмотрите ещё раз на таблицу производительности библиотек. Эта библиотека практически идёт один в один с тестами на основе ванильного JS. Если честно, это действительно впечатляет.

    Вы просто не понимаете что значат цифры в этом бэнчмарке. Но это не ваша вина, просто некоторые любят использовать такие бэнчмарки в качестве маркетинговой платформы.


    1. saggid
      25.11.2016 07:15
      +3

      Я уважаю ваш опыт и мнение. Но не нужно быть таким категоричным. Вспомните тех многих противников PHP, долгие годы ведущих яростную миссионерскую деятельность против него. Всё это часто доходило до какого-то совсем страшного фанатизма, из-за чего сегодня репутация у PHP сильно подпортилась, думаю, все об этом знают. При этом, PHP решает проблемы и до сих пор живёт, к тому же, на нём ещё и пишут гигантские проекты..


      Node.js вышел, миссионеры тут же объявили смерть PHP по этому случаю. Вроде бы вот она — идеальная платформа для веб-разработки. Один язык на сервере и в браузере. Но опять что-то не сошлось… PHP не умер, а Node.js так и не смог кардинально переломить ситуацию.


      Относитесь попроще к JS библиотекам. Ну да, есть там проблемы во внутренностях, да, другие парни, возможно, написали свои библиотеки где-то лучше. Но говорить, что его авторы совсем не разбираются в том что они делают — тоже как-то слишком жёстко и некорректно.


      Такого чистого API нет ни у кого другого, из того, что я видел. Работает всё вполне нормально: я уже несколько лет использую Riot.js в довольно сложных компонентах. Да, там есть недоработки, за время работы я создал 4 ишью в их проекте на гитхабе. Все они были исправлены авторами библиотеки. Многие проблемы они поправили очень быстро, некоторые — с выходом релиза 3.0. Разве это не значит, что они понимают, что делают?)


      1. nuit
        25.11.2016 07:36
        +2

        >Но говорить, что его авторы совсем не разбираются в том что они делают — тоже как-то слишком жёстко и некорректно.

        Ну а как ещё говорить о тех кто впаривает библиотеку тысячам благодаря лжи в своих маркетинговых статьях? Когда научатся не терять внутреннее состояние, узнают про проблемы асинхронности и инпут евентов, перестанут пихать кучу ненужного хлама в документы, этот список можно очень долго продолжать… Тогда можно будет сказать о том что наконец-то они разобрались :)


        1. saggid
          25.11.2016 07:45
          +1

          Видимо я тоже не знаю об этих проблемах, ибо я бы уже создал ишью на эту тему им) Можете рассказать более подробно, с какими-то примерами, что конкретно вы имеете ввиду? Где оно вредит разработке?


          1. nuit
            25.11.2016 10:16
            +3

            Да там ещё год назад пара людей пыталась им всё объяснять. На тему потери внутреннего состояния были очень долгие обсуждения (вроде автор snabbdom'а или какой-то другой либы безуспешно пытался это объяснять). Бывают просто разработчики, которым бесполезно что-то объяснять. Пару месяцев назад там этот чел, который пишет большую часть кода сейчас, опять продолжил говорить что ключи в реакте — это глупость :) Общаться с ними больше ни у кого просто нет никакого желания, они отлично всё понимают и у них всё замечательно. Лично я никому не рекомендую прикасаться к этому говну.


      1. metalim
        25.11.2016 16:02

        На тему авторитетов и «правильного» стиля разработки: я бы ещё вспомнил CoffeeScript, который написан совершенно не по правилам «правильной» разработки компиляторов, имеет примерно 30% негативных отзывов, но при этом является самой часто используемой заменой JavaScript. И ещё благополучно забытый всеми CoffeeScript Redux, который кто-то решил написать «по правилам» разработки компиляторов и который нахрен никому оказался не нужен. Так что «правильность» — далеко не самый важный критерий разработки софта. Кстати сам JavaScript — абсолютно «неправильный», со всеми его костылями и невнятными историческими заимствованиями. Главный критерий любого софта: «он работает и им можно пользоваться».


    1. Lodin
      27.11.2016 13:36

      Вы просто не понимаете что значат цифры в этом бэнчмарке. Но это не ваша вина, просто некоторые любят использовать такие бэнчмарки в качестве маркетинговой платформы.

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



  1. vintage
    25.11.2016 09:39

    1. Вы показали как создать компоненту, но не показали как её использовать. Что если я хочу использовать эту форму в разных контекстах и в некоторых из них мне не нужна регистрация, в некоторых авторизация происходит по иному урлу, а в некоторых авторизация происходит не по e-mail, а по username?


    2. У вас тексты зашиты в вёрстку. Что если мне нужна поддержка нескольких языков? Во что превратится "этот простой и понятный код" и сколько будет стоить внедрение локализации?


    1. saggid
      25.11.2016 10:03

      Ну, это вообще-то просто анонс нового релиза. Я много чего не показал, так как не стремился написать руководство по Riot.js: для этого можно открыть их официальный сайт и почитать его. Всё прекрасно расписано, логика работы очень простая)


      Вы показали как создать компоненту, но не показали как её использовать

      Как её использовать, вы можете почитать в главе о монтировании компонентов.


      Что если я хочу использовать эту форму в разных контекстах и в некоторых из них мне не нужна регистрация, в некоторых авторизация происходит по иному урлу, а в некоторых авторизация происходит не по e-mail, а по username

      Берёте и пишете всё так, как вам надо. Для вас доступны условные конструкции, циклы, вложенные компоненты, выражения, получаемые при монтировании параметры, и так далее. Всё из того, что вы написали — легко реализуемо при нормально работающем котелке.


      Что если мне нужна поддержка нескольких языков?

      У нас сейчас как раз ведётся разработка мультиязычного проекта. Мы в нашем проекте передаём все строки, нужные компоненту, при его монтировании. То есть, код инициализации нашего компонента выглядит примерно так::


      riot.mount('#some-div', 'my-component', {
        str: {
          firstString: { ваша логика получения мультиязычной строки },
          secondString: { ваша логика получения мультиязычной строки },
        }
      })

      Далее, в коде вашего компонента, пишете что-нибудь вроде такого:


      my-component
          p { opts.str.firstString }
          span { opts.str.secondString }


    1. DenimTornado
      25.11.2016 15:28

      ой всё!


  1. lazant
    25.11.2016 13:53

    Ого! Они убрали обращение к тегам по атрибуту name? Переход на 3.0 версию не выглядит таким уж безболезненным :).


    1. saggid
      25.11.2016 15:34

      Очень правильно кстати сделали. А то раньше это реально было очень даже некрасиво сделано. Теперь всё как в React.js, есть отдельный объект refs, содержащий все ссылки на нужные dom объекты.


  1. kanekt
    25.11.2016 15:30

    А как там осуществляется серверный рендеринг? через node js?

    Существует ли какой то starter-kit?


    1. saggid
      25.11.2016 15:31

      Ну да. Пример из док-ции:


      var riot = require('riot')
      var timer = require('timer.tag')
      
      var html = riot.render(timer, { start: 42 })
      
      console.log(html) // <timer><p>Seconds Elapsed: 42</p></timer>


      1. kanekt
        25.11.2016 15:40

        жаль, что не asp.net core :)


    1. saggid
      25.11.2016 15:42

      Существует ли какой то starter-kit?

      Честно, я не пользовался, как-то сам всё делал всегда вручную. Сейчас нашёл какой-то более менее популярный. Но сказать ничего не могу про него)


      1. kanekt
        25.11.2016 15:53

        давно хочу порывать эту библиотеку, но как backend разработчику тяжело вникнуть в проект, без использования starter-kit или примера todo



  1. saggid
    25.11.2016 15:30

    del, промахнулся с комментом