Около полутора лет назад мы написали внутренний инструмент для корпоративных анонсов. Изначально в нём использовался 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-приложения на отдельном фреймворке. Мало того, что готовый продукт получился таким же классным, так мы ещё и стали быстрее добавлять новые возможности, смогли быть уверенными в тестах и легче привлекать разработчиков для участия в проекте. В общем, я думаю, это была большая победа.
А вы отказывались от каких-либо фронтенд-фреймворков в последнее время?
Заключение от Вуншей
Друзья! Следующая статья про создание блога на Фениксе через неделю. Сегодня же мы решили обсудить другую интересную тему, связанную с этим фреймворком.
Напоминаю, что мы проводим конкурс с классным призом для победы в котором вам нужно опубликовать классную статью об Эликсире на Хабре. А также призываю вас активнее подписываться на рассылку. Дважды в неделю мы отправляем новые статьи на почту, которых ещё нет в открытом доступе на сайте! Спасибо всем, кто остаётся с нами!