Архитектура интерактивных сайтов

(Из ленты )

В анонсе серии статей «Интерактивные сайты» я постарался максимально доходчиво изложить свою мотивацию к ей созданию, да и актуальность самой темы, так что сразу к делу!

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

Сразу хочу предупредить, что далеко не всем сайтам такая
глобальная интерактивность пойдет на пользу. Если пользователи сайта
редко что-либо делают и большую часть времени читают длинные тексты, то,
вероятно, этот проект как раз из этой категории: быстрота реакции на
клик не так радует, когда большую часть времени приходится работать
скроллом. Если Ваш интернет-проект является сайтом с длинным контентом в
формате блога, новостей или вики — подумайте лишний раз, прежде чем
переделывать весь сайт, вероятно будет достаточно интерактивных
комментариев и голосований на AJAX. Для социальных сетей,
сайтов знакомств, интернет-магазинов, поисковых систем, корпоративных
сайтов и многих других визуально заметная интерактивность определенно
станет одним из ключевых конкурентных преимуществ.

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

Архитектура интерактивного сайта

Общие замечания

  • Здесь и далее я буду описывать «среднестатистический» интернет-проект, в
    зависимости от специфики могут появляться дополнительные компоненты или
    убираться за ненадобностью упомянутые. Например, если известно, что
    пользоваться сайтом будут только сотрудники какой-то компании, то помимо
    замены Интернета на Интранет, можно запросто избавиться и от
    HTML-интерфейса и всего, что с ним связано — никаким роботам доступ
    к нему не нужен.
  • Наверное стоит прямым текстом сказать, что:

    • Голубые элементы — компоненты проекта, а серые — внешние.
    • Связи в виде прямых линий означают двусторонний обмен данными,
      транспорт и формат пока особо не важны.
    • Схема логическая, так что вопросы балансировки нагрузки,
      отказоустойчивости, репликации и т.п. остались в стороне; за каждым
      блоком может стоять произвольное количество серверов.
  • Я решил не загромождать схему мониторингом, резервным копированием,
    почтой, сервисом доменов и прочими хоть и важными, но не связанными
    напрямую с темой компонентами системы.

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

Клиентская часть

  • Начнем наше путешествие. Пользователь вводит в адресной строке браузера
    адрес нашего сайта и жмет Enter, инициируя тем самым сначала определение
    IP-адреса через DNS, а затем и HTTP-запрос к нашему HTML-интерфейсу.
  • Получив в ответ страницу в формате HTML браузер
    начинает загружать указанные в нем внешние ресурсы, в том числе и
    Javascript-клиент, которому и передается слово. Сама страница
    параллельно отрисовывается как и в статичном сайте.
  • Как уже упоминалось выше, некоторые проекты решают не тратить силы на
    поддержку двух интерфейсов к сайту, жертвуя тем самым доступом
    большинства роботов и браузеров без поддержки
    JavaScript. Стартовый HTML-документ в этом случае
    превращается просто в практически пустой статичный файл, который служит
    лишь для загрузки клиента.
  • Так как наша цель стоит в интерактивном взаимодействии пользователем,
    повторять эти действия при каждом переходе на другую страницу —
    непозволительная роскошь. Кстати, можно начинать думать и общаться не
    в терминах страниц, а в терминах экранов, которые видит
    пользователь.
  • Для обеспечения этого JavaScript-клиент должен переопределить
    стандартные обработчики событий перехода по внутренним ссылкам сайта и
    отправки форм. Ему нужно отменить стандартный механизм перехода на
    другую страницу и вместо него отправить запрос через интерфейс
    сериализованных данных
    . На основе полученного в ответ сообщения он
    меняет какую-то часть загруженного ранее HTML-документа, чтобы он
    соответствовал тому экрану, который ожидал увидеть пользователь. В
    итоге пользователь видит в браузере ровно ту же картинку, как если бы он
    ввел тот адрес, на который вела нажатая ссылка, или просто нажал на нее
    с отключенным JavaScript.
  • Важно не сломать при этом поведение браузера: кнопка «назад» должна
    работать как обычно, а в адресной строке должны меняться ссылки (это
    актуально, например, когда пользователь отправляет содержимое адресной
    строки кому-то по почте или через мессенджер).
  • При ожидании ответа от сервера стоит эмулировать курсор и иконку
    загрузки страницы, чтобы пользователь не паниковал в случае (пускай и
    редком) визуально заметных задержек.
  • На резонный вопрос «Почему, собственно, этот трюк обеспечит
    интерактивность?»
    , ответ хоть и не всегда однозначен, но он все же
    есть:

    • Сериализованные изменения страницы занимают меньший объем, чем
      полный HTML со всеми связанными ресурсами, заголовками, версткой
      и прочим — значительно меньше данных нужно передавать по сети.
    • Как правило, есть возможность держать постоянное соединение
      между браузером и интерфейсом сериализованных данных, что позволяет
      не делать лишние HTTP-запросы. Обратная сторона медали — это самое
      соединение постоянно же использует часть серверных ресурсов, но есть
      способы минимизировать эти издержки.
    • Для некоторых действий изменения HTML не требуют ответа сервера и
      могут быть сделаны параллельно с отправкой запроса (например
       различные вариации на тему +1 или написание комментария, текст
      которого можно взять из формы).
    • Как правило, можно предсказать наиболее вероятные переходы по
      экранам и загрузить необходимые изменения заранее. Хотя этот
      вопрос скорее из области оптимизации.
    • Таким образом, в большинстве случаев есть техническая возможность
      снизить время отклика  на действие пользователя с 500-2000 мс в
      случае неплохо сделанного статического сайта до 20-200 мс., что
      вполне сопоставимо с откликом десктопного приложения.
  • Как все это сделать на практике — тема следующей статьи из серии.

Серверная часть

  • С серверной точки зрения основным отличием является четкое разделение
    двух входных точек:

    • HTML-интерфейс отдает готовые документы в ответ на HTTP-запросы.
    • Интерфейс сериализованных данных использует какое-то постоянное
      соединение, хотя в некоторых случаях целесообразно ограничиться
      просто асинхронными HTTP-запросами.
  • Если для статичных сайтов полное выделение бизнес-логики в отдельные
    сервисы
    — просто хорошее архитектурное решение, то для интерактивных
    сайтов — это практически необхохимо. Иначе придется реализовывать и
    поддерживать две копии кода для каждого интерфейса и надеяться, что они
    постоянно будут оставаться совместимыми и выдавать одинаковый результат.
  • Хорошей практикой является использование какого-то одного протокола
    общения между компонентами системы, в частности пользовательских
    интерфейсов с сервисами бизнес-логики и последних друг с другом.
    Желательно использовать что-то бинарное и с поддержкой разных языков
    программирования, хотя если весь проект на одной платформе и не
    планирует это менять — можно использовать и стандартный для этой
    платформы протокол.
  • Чтобы не включать элементы верстки при передаче через интерфейс
    сериализованных данных, рекомендую использовать кроссплатформенный
    формат HTML-шаблонов. Об этом будет отдельная статья.
  • Интерфейс сериализованных данных при необходимости легко может быть
    адаптирован для использования в роли API для сторонних сервисов или
    собственных приложений
    для мобильных платформ или настольных
    компьютеров.
  • В целом внутренние сервисы общаются с остальными располагающимися на
    серверной части компонентами системы вполне обычным образом.
  • В статье про серверную часть подробно будет рассматриваться
    использование брокера сообщений для уведомлений пользователей в реальном
    времени.

Подводим итоги

  • Глобальная интерактивность сайта требует использования достаточно
    сложного и комплексного JavaScript-клиента и создания
    дополнительного более легковесного внешнего инетрфейса на серверной
    части.
  • По-настоящему мгновенной реакцией сайта смогут насладиться лишь
    пользователи с современным браузером и относительно широким
    интернет-каналом
    . Из-за возможных сетевых задержек или
    особенностей устаревших браузеров эффект мгновенного перехода все же
    может теряться, но при должном тестировании реально добиться
    нормального поведения сайта и в таких ситуациях. Хотя зачастую
    «проваливание» до обычного режима статичных страниц в подобных
    ситуациях — вполне резонное решение.
  • Архитектура серверной части проекта в большинстве случаев не требует
    существенных изменений. Хотя если в ней все было хаотично и не
    продумано, то создание интерактивного клиента может послужить
    неплохим поводом пересмотреть и привести в порядок и её.
  • Кроме очевидной потребности в использовании JavaScript для клиента,
    особых ограничений на используемые технологии и языки
    программирования, обсуждаемая схема не накладывает.

Эта статья — первая в серии про Интерактивные сайты, автор — Иван Блинков, основано на личном опыте.
До встречи на страницах Insight IT!

Источник: Архитектура интерактивных сайтов