Около полутора лет назад мы написали внутренний инструмент для корпоративных анонсов. Изначально в нём использовался Phoenix для бэкенда и React для фронтенда. Тем самым мы получали преимущества Redux и каналов Phoenix при доставки обновлений в браузер в реальном времени.


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


Почему мы решили заменить React


Обновление в реальном времени позволяет лучше погрузиться в работу с приложением, но при этом имеет дополнительные издержки.


Стоимость разработки


Вместо того, чтобы добавлять новую возможность в одном месте, нам нужно было заниматься ей и в части API, и в части UI. Это также означало, что каждый разработчик, желающий добавить свой вклад в проект должен знать и React, и Phoenix, что отбивало у них охоту попробовать включиться в работу.


Тестирование


Другим больным местом при работе с кодом React было тестирование. Так как приложение и клиент были разделены, нужно было быть уверенными, что ответы нашей тестовой имитации сервера всегда актуальны. На практике это не было серьёзной проблемой, но несколько раз всё же вставило палки в колёса, уменьшив наше доверие тестам.


Внесение вклада в проект


Наконец, мы хотели, чтобы больше людей могло принимать участие в работе над проектом. Мы обнаружили, что реализация функционала в двух местах намного трудозатратнее по сравнению с работой в единственном месте. А пытаться координировать бэкенд- и фронтенд-разработчиков довольно утомительно. Это особенно важно, поскольку работа над этим приложением происходит в наше «время для развития».


Процесс замены


Благодаря тому, что у нас уже был готовый к использованию API, мы смогли переписать страницы на Phoenix и развернуться на продакшене, не затрагивая существующий на React фронтенд. Так как приложение по большей части представляет собой CRUD, большинство страниц были просто перекопированы один-в-один, лишь заменяя className на class и блоки {} на <%= %>.


В местах, где нам был нужен JavaScript, мы пошли проторенной дорожкой «вкрапления» кусочков на нём. Лучший пример такого подхода — живое обновление комментариев. Всякий раз, когда комментарий создаётся на бэкенде, мы транслируем его всем пользователям. Вместо того, чтобы отправлять JSON, мы создаём live-html канал, через который передаём обновления пользователями в виде HTML. Вот JavaScript код прямиком из приложения:


import socket from './socket'

const channel = socket.channel('live-html', {})

channel.join()
  .receive('ok', function(resp) { console.log('Joined successfully', resp) })
  .receive('error', function(resp) { console.log('Unable to join', resp) })

channel.on('new-comment', payload => {
  $(`[data-announcement-id='${payload.announcement_id}'] .comments-list`)
    .append(payload.comment_html)
})

Это удивительно небольшое количество кода на JavaScript, обеспечивает огромный кусок функциональности нашего приложения. Подобная стратегия генерации HTML на сервере и транслирования его клиентам гораздо проще, чем написание полноценного фронтенд-приложения с такими же возможностями.


Мы также добавили сюда Turbolinks, что сделало обновление страницы очень плавным и позволило нам получать ощущение SPA.


Результаты


Полная миграция была относительно безболезненной. Мы пришли к тому, что за несколько месяцев к проекту присоединилось больше людей, чем за весь год использования фронтенда на React. Тесты стало писать гораздо легче, в то же время они стали гораздо надёжнее. Ведь теперь не нужно боятсья, что тестовые ответы сервера отличаются от настоящих.


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


Усвоенные уроки


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


А вы отказывались от каких-либо фронтенд-фреймворков в последнее время?


Заключение от Вуншей


Друзья! Следующая статья про создание блога на Фениксе через неделю. Сегодня же мы решили обсудить другую интересную тему, связанную с этим фреймворком.


Напоминаю, что мы проводим конкурс с классным призом для победы в котором вам нужно опубликовать классную статью об Эликсире на Хабре. А также призываю вас активнее подписываться на рассылку. Дважды в неделю мы отправляем новые статьи на почту, которых ещё нет в открытом доступе на сайте! Спасибо всем, кто остаётся с нами!


* Заголовок для активации бурных обсуждений, наполненных радостью и добром, в комментариях.
Поделиться с друзьями
-->

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


  1. vintage
    21.11.2016 09:54
    +4

    Как быть с не-хтмл клиентами и медленным каналом связи?


    1. jarosluv
      21.11.2016 10:49
      -1

      1. Оставить JSON API дня сторонних клиентов.
      2. В этом случае нужно решать задачу, исходя из технических ограничений. Например, не использовать описанный в статье метод. :)


      1. vintage
        21.11.2016 11:41
        +5

        1. И поддерживать 2 версии АПИ?
        2. Получается его нельзя использовать никогда, так как на любой сайт я могу зайти через ГПРС.


        1. khim
          21.11.2016 13:51
          -4

          Получается его нельзя использовать никогда, так как на любой сайт я могу зайти через ГПРС.
          Мы очень рады за вас, но это не значит что есть много пользователей, кому этот факт интересен.

          Я на свой сайт тоже могу зайти по ГПРC, но утверждать вот прямо так сходу, что эта потребность нужна прям всем-всем-всем я не возьмусь. Очень может быть что и нет. Особенно если это корпоративный сайт и заходить на него откуда-нибудь из лесной глуши не нужно.


          1. vintage
            21.11.2016 18:12

            1. В пределах МКАД полно такой "глуши".
            2. Находяcь в командировке на корпоративный сайт заходить всё-таки нужно. Да ещё и через VPN.


  1. Anarions
    21.11.2016 10:52

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


    1. jarosluv
      21.11.2016 10:55

      Наверное, в этом случае и React не сильно поможет? А количество дааных в HTML и JSON представлениях, предположу, что не сильно различается.


      1. Anarions
        21.11.2016 10:59

        React может поможет тем что ответ на действие пользователя будет мгновенным (Откроется нужная страничка, на ней нарисуется loading, по ощущениям такое поведение страницы воспринимается пользователем менее болезненно ). Или все данные могут храниться в каком-нибудь store — и тогда будет только один запрос который получит все нужные данные.


        1. jarosluv
          21.11.2016 11:18
          +1

          Если нужно полноценное SPA с определёнными техническими требованиями, то да, без фронтенд-фреймворка не обойтись. Если нужно добавить «живости» сайту, то можно сделать проще. Как именно? Об этом и рассказано в статье.


          1. Anarions
            21.11.2016 11:20

            Да я не критиковал подход — я просто спросил как оно выглядит, насколько юзабельно. Секунда, пожалуй, многовато — но 500ms не слишком редкий пинг на мобильном.


            1. svboobnov
              21.11.2016 22:41

              Секунда тоже может случиться, когда ближайшая сота вырубилась, а вокруг туман густой (через туман радиосигнал плохо проходит, много пакетов теряется).
              Пользуюсь 3G — модемом, и иногда такое наблюдал.


        1. justboris
          21.11.2016 11:59
          +4

          Ничто не мешает показывать loading и в случае server-rendering.


          Например, так работает Github (при навигации по папкам репозитория сверху показывается синий прогрессбар).


        1. akaluth
          21.11.2016 14:27
          +1

          Такого же эффекта помогает добиться turbolinks


  1. markfrost
    21.11.2016 11:15
    +2

    «Другим больным местом при работе с кодом React было тестирование. Так как приложение и клиент были разделены, нужно было быть уверенными, что ответы нашей тестовой имитации сервера всегда актуальны.» Лолшто.
    Это проблема всегда есть при разработке SPA приложения.


    1. jarosluv
      21.11.2016 11:16
      +1

      И они достаточно изящно избавились от этой проблемы. Так можно делать не всегда, но если ситуация позволяет. то почему бы и нет?


    1. Veikedo
      21.11.2016 11:32

      + Есть подозрение, что такое должно решаться ui тестами.


      1. Anarions
        21.11.2016 11:38
        +1

        Ну, оно и решается, думаю в ситуации описанной автором не нравилось то что при изменении в API все изменения надо было дублировать в моках, и эту проблему решили просто избавившись от всей логики в UI


  1. saggid
    21.11.2016 12:51
    +1

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


    Суть примерно такая: 90% сайта — это обычные статичные страницы, которые генерируются сервером на основе обычных шаблонов. Но некоторые части проекта используют JS компоненты: в основном это Riot.js. По большей части, наша стратегия — это использовать сложную логику на основе js только в конкретных ключевых точках приложения, которые подразумевают большое количество динамических изменений, интерактивное поведение, и так далее.


  1. tot0ro
    21.11.2016 13:51
    +3

    Как по мне так название статьи «Как Phoenix убивает React» вводит в заблуждение.

    У меня к вам пара вопросов:
    — чем именно вам мешает React ???
    — как Phenix будет его убивать на Node, Ruby и etc???
    — вам не кажется что изначально был неверно выбран инструмент или подобрана команда???

    После прочтения статьи сложилось впечатление что у вас мало хороших front-end разработчиков и функционал приложения довольно таки посредственный и не предполагает высокой степени активности.

    Попробуйте на серверном рендеринге с минимальным js сделать торговую панель для трейдера с 3-5 индикаторами. Я думаю в этом случае React сможет более полно раскрыть свой потенциал.


    1. jarosluv
      21.11.2016 14:56

      На картинки для привлечения внимания более точный заголовок. :)

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


  1. Ckomop0x
    21.11.2016 13:52
    +1

    Тезис: Авторы описали как переехали с фронта на бэк и стало проще всё тестировать и писать в одном месте, но зачем тогда такое громкое название про React и Phoenix? Возможно, если у них нет мобильных клиентов и приложений, PWA и ограничения по трафику это удобно… но в нынешнее время куда лучше закешировать всё на клиенте и оптимизированно подтягивать данные в готовый интерфейс, а не генерить тонны трафика повторяющегося html.
    Вывод: сложилось впечатление, что им просто было лень и они решили всё упростить.


    1. justboris
      21.11.2016 13:58

      Громкое название придумали переводчики.
      Оригинально статья называлась "How We Replaced React with Phoenix", убивать никто никого не собирался


    1. jarosluv
      21.11.2016 14:53
      -5

      Прошу простить меня за столь громкий заголовок. Примечание по этому поводу в самом конце страницы. :)


    1. yul
      27.11.2016 19:22
      +2

      Вывод: сложилось впечатление, что им просто было лень и они решили всё упростить
      Что в этом плохого-то?


  1. nwalker
    21.11.2016 14:10
    +1

    внутренний инструмент для корпоративных анонсов.

    React для фронтенда

    Дальше пост можно не читать, все и так понятно.


    1. jarosluv
      21.11.2016 14:52

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


      1. nwalker
        21.11.2016 15:43
        +3

        На мой взгляд, здравомыслящемум человеку это и так понятно, и конкретные тулзы тут вообще ни при чем.


        Вообще, я этот пост читал сразу после написания и мне хотелось разбить себе лицо руками — это просто эталон хипстерства. "Давайте мы сначала сделаем фронтенд на ненужном нам new and shiny реакте, потом удивимся, что так трудно, перепишем на new and shiny фениксе и напишем пост, какой замечательный феникс и как трудно с реактом".


  1. Fen1kz
    21.11.2016 15:21
    +5

    Не верю. Окей, молодцы вкрапляете js маленькими кусочками.
    Дальше таких кусочков будет все больше и больше, а давайте ещё комменты можно будет прокручивать, а давайте будет оповещалка о новом комменте, а что-то js не тянет, давайте jquery, а давайте нам галерею, давай, jquery плагином, а ещё это и вот то, и тут классный плагин, а что это сайт превратился в jquery монстра, который парсит куски html с сервера, а давайте перепишем все на ангуляр.
    А тот будет тормозить, да и двусторонний биндинг нафиг нужен, давайте обратно на реакт.


  1. baka_cirno
    21.11.2016 15:29
    +1

    Если кто-то и убивает React (чего на самом деле и близко не происходит), так это набирающий популярность Vue.


    1. serf
      21.11.2016 18:08
      -1

      Vue (v2) содержит virtual dom как элемент оптимизации, а React только этим элементом и является (по сути просто продвинутый шаблонизатор), так что React не нужен от слова совсем.


  1. orcy
    21.11.2016 15:35
    +6

    Подождите убивать React, я на нем еще не ничего не сделал! Вот же ж JavaScript, полгода и библиотека в хайпе, а потом уже сразу considered harmful


    1. yul
      27.11.2016 19:24
      +1

      Можете уже на vue перебираться ) И да, я тоже не успел…


      1. taujavarob
        28.11.2016 16:30
        -1

        Можете уже на vue перебираться ) И да, я тоже не успел…


        Там нет драйва. Весь драйв сейчас только на React.

        Остальные просто скучноваты монстры. Вымирающие динозавры, пытающиеся хоть как-то противостоять React тем, чтобы дать всё из коробки, тем кто устал и не хочет «париться».

        Имхо.

        ;-)


  1. betsuni
    21.11.2016 18:22
    +6

    Вот такие они js фреймворки: я еще ничего даже написать на реакте не успел, а он уже умирать начал.


  1. Bimawa
    22.11.2016 09:31
    +1

    Капец заголовок… один в один новости на канале Россия 1
    Я прочитав статью не понял как Ваша навороченная версия PHP может убить Front-end фреймворк? Если Вы такие страшные убийцы фреймворков, что ж не убить и ваш новороченый PhoenHP? Один фиг его изучать тоже надо вашей команде.
    ЛАЙК ЗА GITHUB PAGES! — Убьем фреймворки!!! CLEAN HTML!
    В общем за статью спасибо, но посыл статьи в чем-то не понятен. Я не понял, толи в вашей компании работают люди которые ни чему не хотят учиться… толи… Слушайте статья не понятная вообще короче. Больше вопросов чем ответов. Почему бы вам не убить Google Chrome таким же способом?


  1. taujavarob
    24.11.2016 20:55
    -1

    Убили ну и ладно.

    Теперь сами убейтесь аб стену. (С)


  1. Bimawa
    25.11.2016 08:12
    +1

    О статья прям в тему: https://blog.daftcode.pl/hype-driven-development-3469fc2e9b22#.88ntkt501 Hype Driven Development