[Из песочницы] Динамическое обновление веб-страницы

imageВведениеНикого уже не удивишь концепцией динамического HTML, почти все сайты давно в той или иной мере используют javascript для того, чтобы сделать страницы интерактивными. А с появлением технологии AJAX стало возможным асинхронно генерировать запросы к серверу, чтобы изменять старые данные на сервере или получать новые. Но как именно обновлять структуру страницы? Кто должен генерировать новый html — сервер или javascript? А может, все вместе? Посмотрим, как можно ответить на эти вопросы.Для начала, я опишу жизненный цикл страницы. Сразу скажу, что я не собираюсь описывать этот процесс досконально, здесь требуется только понимание основной логики процесса.

Любое веб-приложение можно логически поделить на две составляющие — на клиентскую часть и серверную часть. К клиентской части относятся сам браузер и скрипты, которые он выполняет, к серверной — набор скриптов, которые генерируют ответ на любой запрос пользователя.

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

После получения страницы с сервера, браузер отображает её и запускает на выполнение приложенные к ней скрипты.Клиентская часть реагирует на различные события — например, на клик по некоторому элементу, перемещение мыши или на истечение таймера. Для того, чтобы получить какие-то данные с сервера (или отправить что-то на него), используются дополнительные, обычно асинхронные, запросы.

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

Ближе к сути Для удобства объяснения рассмотрим вариант обновления простой страницы с лентой новостей и, скажем, счетчиком подписчиков. Мы хотим, чтобы браузер регулярно проверял обновления ленты, добавляя новости по мере их появления. А еще мы хотим, чтобы каждый посетитель видел динамику роста популярности нашего сайта — пусть счетчик подписчиков тоже регулярно обновляется.Тело нашей страницы может выглядеть, например, так:

Подписчиков: 42

Вариант 1 — дублирование Основная идея — логику отображения знает и клиентская, и серверная часть. В таком случае, ответы на регулярные запросы со стороны клиента могут содержать исключительно данные — изменения в модели, и выглядеть, например, так: { subscr_cnt: 44, news:[ { href:»/wiskey», name: «Названы лучшие в мире сорта виски 2015 года» }, { href:»/kindergarden», name: «В Нью-Йорке появился детский сад для взрослых» } ] } При получении такого ответа клиентская часть «оборачивает» данные в html-теги, добавляет необходимые тексты и обновляет структуру страницы.Серверу же знания об отображении нужны только для того, чтобы сгенерировать изначальную версию страницы.

Плюсы подхода:

Малый объем трафика — передаются только необходимые данные; Минусы подхода:

Требуется продублировать код — он будет и в клиентской части, и в серверной; Клиентская часть должна знать, как именно поступать с каждой порцией данных от сервера — иногда нужно заменить html элемента, иногда добавить новые данные к уже существующему коду; Вариант 2 — всемогущий сервер и «толстые» ответы Основная идея — логику отображения знает только сервер, клиентская часть получает уже готовый html-код элементов. Здесь ответ сервера выглядит так: { subscr_cnt: «Подписчиков: 44», news:»

  • Крупнейшие на Земле метеоритные кратеры случайно нашли в Австралии
  • \n
  • Чудо-женщина ответила на критику о своей груди
  • «Ромео и Джульетту» экранизируют в духе »300 спартанцев»
  • Названы лучшие в мире сорта виски 2015 года
  • В Нью-Йорке появился детский сад для взрослых
  • » } Замечу, что пересылается здесь весь html каждого компонента на странице. Реализуется же такой способ просто — сервер генерирует страницу по кускам, клиент при получении ответа заменяет тела отдельных элементов.Плюсы подхода:

    Простота реализации; Отсутствие дублирования кода; Минусы подхода:

    Многократная генерация одного и того же кода, особенно неэффективно при небольших изменениях; Огромный объем трафика, особенно на больших страницах; Вариант 2а — всемогущий сервер и «тонкие» ответы Можно попытаться исправить главный недостаток предыдущего варианта. Сервер может не отправлять весь html компонента, а присылать только «дельту» — изменения, которые необходимо внести. Наш ответ тогда может стать таким: { subscr_cnt: { html: «Подписчиков: 44», mode: «replace» }, news: { html:»

  • Названы лучшие в мире сорта виски 2015 года
  • В Нью-Йорке появился детский сад для взрослых
  • », mode: «append» } } Теперь клиент определяет элемент, который будет изменять, и то, как он его будет изменять, непосредственно из ответа сервера.Плюсы подхода:

    Отсутствие дублирования кода; Минусы подхода:

    Все еще достаточно большой объем сетевого трафика; Клиент должен отправить серверу текущее состояние каждой компоненты, закодированное некоторым образом, чтобы сервер понял, относительно чего считать дельту; Сложность вычисления и записи дельты в случае нетривиальных изменений; Общее усложнение и клиентской, и серверной части; Вариант 3 — всемогущий javascript Можно переложить всю ответственность за генерацию html на клиента. В таком случае сервер будет только предоставлять данные, необходимые для отображения. Ответы, как и в первом варианте, будут содержать только данные: { subscr_cnt: 44, news:[ { href:»/wiskey», name: «Названы лучшие в мире сорта виски 2015 года» }, { href:»/kindergarden», name: «В Нью-Йорке появился детский сад для взрослых» } ] } Так в чем же существенное отличие от первого варианта? А заключается оно в том, что сервер не выполняет первоначальную генерацию страницы, её сборка осуществляется уже браузером клиента. Вариант этот только выглядит странным, он может пригодиться, если необходимо уменьшить нагрузку на сервер.Плюсы подхода:

    Малый объем трафика — передаются только необходимые данные; Уменьшение нагрузки на сервер; Минусы подхода:

    Высокая нагрузка на компьютер пользователя; Возможна избыточность — часть знаний клиентской части об отображении может так и остаться невостребованной, если какие-то события не наступят; Заключение Каждый из рассмотренных методов имеет право на жизнь, и может быть использован в проектах разной сложности. Лично я во встреченных мною проектах чаще всего видел первый вариант, несмотря на нарушение им моего любимого принципа DRY — Don`t repeat yourself.А какие принципы вы используете при разработке динамических страниц?

    © Habrahabr.ru