Phoenix LiveView: когда вам больше не нужен JavaScript*

* для создания динамической страницы

Не так давно 12.12.2018 был анонсирован выход новой библиотеки для фанатов phoenix framework под названием Phoenix LiveView. Я бы хотел поделиться с вами впечатлениями от ее использования и phoenix в целом, а в следующей статье попробовать написать простую браузерную игру. Часть статьи с личным мнением не является исключительно правдивой, я попробую объяснить преимущества веб-разработки на примере phoenix против php



Теоретическая часть


Phoenix — это фрэймворк на функциональном языке elixir. Прошу не путать с Phalcon для php.


Phoenix LiveView — это потрясающая новая библиотека, которая позволяет создавать динамические веб-страницы без написания javascript кода посредством двунаправленной связи по вебсокетам и server side rendering. Как мы прекрасно знаем, вебсокеты у phoenix достаточно хорошо реализованы, поэтому производительности хватит для большинства идей, которые вы планируете реализовать.


Существует несколько вариантов использования LiveView:

  • Проверка ввода данных в формы (валидация), нажатие кнопок, скрытие и отображение блоков, автозаполнения.
  • События от сервера, такие как уведомления, информационные панели, счетчики.

В данный момент с ограничениями доступны и приоритетны в будущем:

  • Навигация по страницам и пагинация. Они могут быть построены с помощью LiveView, но в настоящее время вы потеряете функционал перехода «назад / вперед». Поддержка `pushState` включена в план.
  • Отображение постоянно растущих данных — чаты, онлайн логи и т.п. можно создавать с помощью LiveView, но в настоящее время вы должны хранить все данные в состоянии приложения на сервере. Поддержка частичного обновления данных состояния находится в разработке.
  • Работа с задержками при изменении состояния. LiveView хранит состояние приложения на стороне сервера и это гарантирует правильную работу интерфейса при серьезных задержках.
  • Полный набор функций для моделирования этих ситуаций появится в будущих версиях.

В чем плох LiveView:

  • Анимации. К примеру отображение меню по клику можно реализовать через LiveView, но плавное появление лучше отдать в css или js.
  • Optimistic UI. Приложение рассчитано на постоянную работу с стейтом сервера и этого стейта нет на клиенте. Весь html код на любое событие подготавливается на сервере с новым состоянием и летит по вебсокетам к клиенту, все видимые изменения происходят посредством подмены html кода.

Как работает LiveView?


image
Изображение взято с elixirschool

LiveView начинается с обычного HTTP-запроса и HTML-ответа, а затем приступает к отслеживанию состояния приложения на сервере через вебсокеты, при этом гарантируя отображение обычной HTML-страницы, даже если JavaScript отключен. Каждый раз, когда состояние приложения меняется, оно автоматически перерисовывает отображение и обновления передаются клиенту. На клиенте при помощи библиотеки morphdom происходит обновление контента. По сути, логика достаточно близкая к современным js фрэймворкам, только без использования virtual DOM.
Чтобы сеанс связи не терялся при повторном подключении, из контроллера инициируется «сессия» пользователя с необходимыми данными и передается клиенту. Только подписанная сессия с первичными данными хранится на клиенте, она отправляется на сервер при подключении, или повторном подключении в случае сбоя, к состоянию приложения.


Впечатление и личное мнение о самом Phoenix


Из личного опыта скажу, что редко встречал понятно написанные приложения в командах от 3х и более человек. Часто встречается мешанина из сервисов на php(сервер) nodejs (websocker) react/vue (фронт) туда еще и go засунут для вещей, которые «медленно» работают на php. Очереди мы в redis засунем, потом подключим rabbitmq, а один из разработчиков не умеет ими пользоваться и реализовал в sql. Кто-то умеет правильно пользоваться кроном через flock и не городит логику защиты повторного запуска в коде, а другие запускают демоны на php, что иногда вставляет палки в колеса при обновлении кода и структуры бд. Состояние приложения начинает хранится везде и всюду, в статике класса, в синглтоне, порой даже в статической переменной метода, начинают множится правила написания кода чтобы бороться с незнанием языка и правильным построением архитектуры, но что если проект начинал программист уровня middle или junior на коленке, не задумываясь что это все вырастет до настоящего бизнеса? Поддерживать такое в одиночку не так просто, часть логики дублируется как на клиенте, так и на сервере (валидация к примеру). В SPA, когда фронт начинает использовать публичное api, мы начинаем задумываться о версионировании. Поддержка усложняется т.к. приходится удовлетворять не только нужды внешних сервисов и клиентов, но и свой часто изменяемый фронт, а дублировать код не хочется. Прикручивам graphql. Со временем зоопарк библиотек разрастается и фирмы начинают нанимать больше разработчиков.


Тут я и вижу превосходство phoenix. Из коробки у нас замена php (elixir + Phoenix), nodejs (вебсокеты на Phoenix.Socket), react/vue (Phoenix.LiveView), redis(ets), rabbitmq (ets), cron (возможно через GenServer), демоны (GenServer), урезанная бд (mnesia). У нас кеширование в самом языке через mnesia или ets, крон или демоны вообще без проблем т.к. многозадачность и работа в фоне годами у «эликсира в крови». Хранение состояния чаще всего в генсервере. Публичное api исключительно для нужд внешних сервисов, spa в скором времени будут писаться на LiveView. Поддержка api станет куда проще. Масштабируемость в любое направление средствами языка, скорость работы ограничена только источником хранения данных, все остальное работает весьма быстро. Достаточно понятная схема работы если один раз узнать как работает plug и что такое conn. Генерация кода, «микросервисная архитектура» — посмотрите в сторону umbrella application. Это все пытаются решить докерами с оркестрацией и т.п. создавая рабочие места для большого количества devops инженеров.


Итог


Попробуйте установить elixir и запустить phoenix. В этой статье я постарался изложить «воду», личное мнение и теоретическую часть, чтобы в следующей ограничится исключительно кодом и логикой. Мы будем писать простую игру на LiveView формата dogeminer но без функциональности кликера. Это моя первая статья, прошу строго не судить и не воспринимать чрезмерно серьезно, я намеренно однобоко показал достоинства Phoenix и упустил его недостатки. Их лучше ощущать на практике чем вот так на мнении чужого человека.


Присоединяйтесь к русскоязычному сообществу elixir разработчиков proelixir или находите в telegram @proelixir. Свежие новости языка собирает бот на канале @proelixir_news.
Поделиться публикацией

Комментарии 21

    –1
    Т.е. новый виток в создании более тормозных сервисов?
      0

      На чем основано утверждение? Вы пробовали live view?

        0
        Просто все стараются переносить часть обработки на сторону клиента, но никак не на сервер.
          0
          При этом необходимо создавать копию состояния и налаживать синхронизацию. К тому же необходим JS программист.
          Для стартапа быстрый выход на рынок — это наивысший приоритет. К тому же бюджет не всегда позволяет иметь полноценную команду. Вот тут Phoenix + LiveView будут идеальным вариантом.
          В дальнейшем, если база пользователей будет уже серьёзной, то и деньги должны быть и команду можно побольше нанять. Тогда уже вопрос оптимизаций и т.п. будет актуален.
          Так что рынок для этого решения огромный.
          Но сейчас я столкнулся с тем, что молодые backend программисты не готовы (да и не умеют) верстать HTML и стили :) Вот это уже другая проблема.
        –3
        Нет, это что-то типа «php пытается выглядеть более живым и полезным, чем он есть».
        Полный server-side rendering в ряде задач будет вполне уместен. А в ряде других задач — да, будет тормозным и убогим поделием, требующим непрерывной связи с сервером, и желательно, чтоб сервер стоял в соседней комнате (чтоб latency поменьше).
          +1

          При чем тут вообще PHP?

            –3
            Вы на этот Phoenix смотрели, нет? Если смотрели, откуда вопросы?
              +1

              Не только смотрел, но даже писал на нем. И точно уверен, что Phoenix к PHP не имеет никакого отношения. Вы бы что-ли на теги к статье посмотрели, на ссылки пощёлкали...

                +1

                Вы часом не с Фалконом путаете?

            +3

            Сперва происходит рост уровня взаимодействия за счёт раздувания инфраструктуры — потом схлопывание инфраструктуры без потери уровня взаимодействия.


            Так что да, мы вроде как на новом витке)

              0
              Вообще по сути это третья реализация подходов которые были использованы в nitrogen, старогом erlang фреймворке.

              Первая реализация была в виде CMS zotonic, в которой под капотом такой же подход как и в nitrogen.
              Вторая реализация в виде n2o erlang фреймворка, по сути это переписанный с нуля nitrogen, с вебсокетами и разными вариантами кодирования сообщений.
              Третья реализация и скорее всего не последняя от команды разработчиков Phoenix.

              Подход очень простой:
              1. Сервер отдает сгенерированный html клиенту. В котором все элементы с которыми взаимодействует пользователь (кнопки, выпадающие списки, поля ввода и т.д.) кроме уникальных id (сгенерированных на стороне сервера), содержат js код для отправки payload(нагрузка с данным или просто событием) на сервер…
              2. При получении события на стороне сервера происходит декодирование нагрузки, подготавливается ответ, и отправляется клиенту.
              3. При получении клиентом сообщения от сервера происходит выполнение кода, как правило это prepend/append, addClass/removeClass, так же может поменять значение элемента или заменить весь блок.

              Плюсы такого подхода:
              1. Состояние коннекта храниться на сервере, и поэтому не теряется при перезагрузке, так же отпадает надобность в хранилище состояние для фронтенд фрейморка.
              2. Для данных которые постоянно дописываются в конец, нету лишнего преобразования данных, с сервера прилетает уже готовый html (в случае фронтенд фрейморков, сервер отдает данные в json, а фреймворк эти данные добавляет в дерево).
              3. Для долгих задач на стороне сервера, не надо писать особую логику. Если пользователь закрыл вкладку, то пришедшие данные просто ничего не поменяют.
              4. Для клиентов с выключенных js, отдается уже готовый контент, пускай и с урезанной интерактивностью.

              Да есть и минусы:
              1. Основной минус, что шаблоны и данные идут в перемешку, можно забыть про MVC и прочие патерны.
              2. На каждое действие пользователя летит событие на сервер и ответ обратно, при плохой сети это может вызывать проблемы с интерактивностью приложения.
              –1
              хранить состояние на сервере это дорогое удовольствие, это постоянная запись нового состояния. Постоянное чтение — это нормально, это быстро, а постоянная запись это просто долго. Состояние клиентского интерфейса надо хранить на клиенте, пусть он у себя перезаписывает и рендерит своё состояние, серверу зачем этим заниматься? Что бы обойтись толко PHP и не искать JS программиста?
                0

                При чем тут вообще PHP?

                  +1
                  В статье автор запутался и запутал читателей. Во многих местах упоминается php. Вплоть до:
                  Тут я и вижу превосходство phoenix. Из коробки у нас php (Phoenix), ...

                  При это у php есть несколько созвучный Phalcon.
                    0
                    Прошу прощения за это(
                    +1
                    > Из коробки у нас php (Phoenix)
                    Видимо, читатели не знакомые близко с предметом статьи, интерпретировали эту фразу буквально :)
                      0

                      Возможно, автор написал запутано, но вроде как нигде он не запутался.


                      Из коробки у нас php (Phoenix), nodejs (вебсокеты на Phoenix.Socket), react/vue (Phoenix.LiveView), redis(ets)

                      Почему php(Phoenix) может запутать, если перечисление продолжается, и из него видно противопоставление? Так можно подумать что разговор идет и про nodejs фреймворк. Или даже одновременно про PHP и Nodejs фреймворк (как бы это парадоксально не звучало)...


                      Но в принципе, можно было и попонятнее сформулировать, в этом я с вами согласен

                        0
                        так можно подумать что разговор идет и про nodejs фреймворк
                        Phoenix LiveView: когда вам больше не нужен JavaScript*
                  –2

                  Спасибо за статью. Как раз хотел освоить что-нибудь новое в отпуске.
                  Я правильно понимаю, что данная технология применима в Tor/I2P, т.к. способна работать без JS?

                    0

                    Нет, ,js там просто скрыт под капотом.

                      0
                      Да, тоже увидел JS, который собственно и поднимает websockets.

                  Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                  Самое читаемое