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

Не так давно 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. AxisPod
    19.05.2019 12:15

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


    1. Slavenin999
      19.05.2019 12:43

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


      1. AxisPod
        19.05.2019 17:23
        +1

        Просто все стараются переносить часть обработки на сторону клиента, но никак не на сервер.


        1. dsnipe
          20.05.2019 09:56

          При этом необходимо создавать копию состояния и налаживать синхронизацию. К тому же необходим JS программист.
          Для стартапа быстрый выход на рынок — это наивысший приоритет. К тому же бюджет не всегда позволяет иметь полноценную команду. Вот тут Phoenix + LiveView будут идеальным вариантом.
          В дальнейшем, если база пользователей будет уже серьёзной, то и деньги должны быть и команду можно побольше нанять. Тогда уже вопрос оптимизаций и т.п. будет актуален.
          Так что рынок для этого решения огромный.
          Но сейчас я столкнулся с тем, что молодые backend программисты не готовы (да и не умеют) верстать HTML и стили :) Вот это уже другая проблема.


    1. JustDont
      19.05.2019 12:44

      Нет, это что-то типа «php пытается выглядеть более живым и полезным, чем он есть».
      Полный server-side rendering в ряде задач будет вполне уместен. А в ряде других задач — да, будет тормозным и убогим поделием, требующим непрерывной связи с сервером, и желательно, чтоб сервер стоял в соседней комнате (чтоб latency поменьше).


      1. Virviil
        19.05.2019 13:11

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


        1. JustDont
          19.05.2019 13:26

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


          1. Virviil
            19.05.2019 13:30

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


          1. vril
            19.05.2019 20:18
            +1

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


    1. Virviil
      19.05.2019 12:50

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


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


    1. Ru6aKa
      20.05.2019 10:00

      Вообще по сути это третья реализация подходов которые были использованы в 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. SbWereWolf
    19.05.2019 12:52

    хранить состояние на сервере это дорогое удовольствие, это постоянная запись нового состояния. Постоянное чтение — это нормально, это быстро, а постоянная запись это просто долго. Состояние клиентского интерфейса надо хранить на клиенте, пусть он у себя перезаписывает и рендерит своё состояние, серверу зачем этим заниматься? Что бы обойтись толко PHP и не искать JS программиста?


    1. Virviil
      19.05.2019 13:11

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


      1. ZurgInq
        19.05.2019 15:35
        +1

        В статье автор запутался и запутал читателей. Во многих местах упоминается php. Вплоть до:

        Тут я и вижу превосходство phoenix. Из коробки у нас php (Phoenix), ...

        При это у php есть несколько созвучный Phalcon.


        1. yaBliznyk Автор
          20.05.2019 10:01

          Прошу прощения за это(


      1. avidcrawler
        19.05.2019 15:39
        +1

        > Из коробки у нас php (Phoenix)
        Видимо, читатели не знакомые близко с предметом статьи, интерпретировали эту фразу буквально :)


        1. Virviil
          19.05.2019 15:44

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


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

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


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


          1. barkalov
            20.05.2019 03:17

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


  1. Nexon
    20.05.2019 01:32
    -1

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


    1. prostofilya
      20.05.2019 03:56

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


      1. Nexon
        20.05.2019 11:10

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