Технологии Манифест одностраничного интерфейса

После небольшого знакомства с Single Page Application решил перевести The Single Page Interface Manifesto на русский язык, так как в сети довольно мало материалов по этой теме. Ниже представлен вольный перевод вышеупомянутого манифеста.

Манифест одностраничного интерфейса (The Single Page Interface Manifesto)

Происхождение веб-технологий

Когда Тим Бернерс-Ли изобрел веб, он искал систему для публикации научных документов, которые могли бы быть доступны удаленно. Система должна была быть визуально привлекательной, удобной для кодирования, удобной в использовании технически неподготовленными пользователями. Научные документы должны были содержать в себе ссылки на другие документы, чтоб читатель мог более глубоко разбираться в теме во время чтения.

Для этих целей была изобретена Всемирная паутина, которая была основана на страницах (документах) с гиперссылками.

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

Приход веб-приложений

Много лет предпринимались серьезные усилия по адаптации парадигмы страниц и гиперссылок для разработки программного обеспечения.

Были предприняты различные подходы для разработки программного обеспечения:

  • модель 1: прямое перенесение оригинальной модели страниц с гиперссылками, в которой страницы генерировались динамически;
  • модель 2 MVC: в данном случае ссылки не вели напрямую на конкретные страницы, вместо этого контроллер решал, какая страница должна отображаться, в зависимости от параметров;
  • MVC основанный на компонентах (Модель 3?): это усложненная версия Модели 2, которая имитирует работу настольного приложения. Она основана на компонентах и событиях, при этом любое действие пользователя подразумевает полное перестроение и перезагрузку нужных частей страницы. Страницы управляются компонентами, которые “знают” о том, какие действия необходимо выполнить при возникновении тех или иных событий, таким образом можно имитировать работу системы подобно программированию GUI для настольных приложений.

В последние годы была представлена технология Ajax, позволяющая выполнять перезагрузку частей страницы на основе данных из сервера, без перезагрузки всей страницы, с помощью языка JavaScript. Несмотря на то, что техника частичной перезагрузки страницы появилась задолго до того, как XMLHttpRequest был представлен в Internet Explorer (основа AJAX программирования), эта техника начала массово использоваться.

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

Несмотря на массовое использование AJAX, мы могли бы назвать сегодняшнюю модель развития веба, как “Модель 2 (MVC) обогащенная AJAX”.

При использовании AJAX, “Модель 3” не имеет особого смысла, так как AJAX в значительной степени снижает необходимость управления страницей на основе компонентов. Так как AJAX часто используется вместе с компонентами (что не обязательно для Модели 2), мы могли бы классифицировать данный этап веб-разработки, как Модель 3.5, где для навигации по страницам можно частично избежать с помощью AJAX и JavaScript.

Какие недостатки разработки на основе навигации по страницам?

Каждый веб-разработчик сталкивается с некоторыми проблемами при навигации по страницам веб-приложения, например:

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

К примеру, нередко можно встретить веб-приложения, в которых используется iframe, чтоб избежать проблем с кнопками вперед/назад.

Разработка на основе страниц иногда заставляет прибегать к немного странному стилю кодирования, повторениям кода (мы постоянно должны подключать одни и те же файлы), неэффективному использованию ресурсов (затраты на пропускной канал и вычислительную мощь), это все не присуще разработке настольных приложений.

Что препятствует интенсивному использованию технологии AJAX?

В области веб-разработки можно выделить два вида решений: веб-приложения и веб-сайты.

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

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

  • закладки: каждая веб-страница имеет собственный URL, этот URL может быть сохранен в закладках. AJAX позволяет изменять части содержимого страниц, но URL страницы в этом случае остается одним и тем же, в следствие чего пользователь не может сохранить конкретный вид (состояние) страницы в закладки;
  • поисковая оптимизация (SEO): любой веб-сайт должен быть полностью проиндексирован поисковыми системами, такими, к примеру, как Google Search. Сегодняшние поисковики рассматривают веб, как веб 1.0, при этом JavaScript код полностью игнорируется, тем самым, любое частичное изменение страницы с помощью AJAX не считается новым посещением;
  • сервисы, основанные на посещении страниц: для таких сервисов, как рекламный сервис Google AdSense и сервис мониторинга посещений Google Analytics, очень важным является показатель количества посещений страниц. При использованием технологии AJAX частичная перезагрузка страницы не учитывается как новое посещение;
  • часто возникает необходимость в использовании всплывающих окон.

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

Но сегодня разница между понятиями “веб-приложение” и “веб-сайт” становится все менее заметной, так как почти любой веб-сайт является своего рода веб-приложением.

Должны ли мы отказаться от активного использования AJAX в своих приложениях?

Нет.

Существуют технические решения, которые позволяют решить все вышеперечисленные проблемы.

Разработка веб-сайта на основе одной страницы (SPI), это возможно?

Да!

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

Для того, чтоб разработать успешное приложение с использованием этого “нового” подхода в веб-разработке, мы должны реализовать все вышеперечисленные функции.

Прощаемся со страницами, встречаем состояния

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

  • основное состояние;
  • второстепенное состояние.

Различия между этими двумя видами очень важны, так как основные состояния могут превращаться в самостоятельные веб-страницы, при необходимости. Перечень основных и второстепенных состояний зависит от специфики сайта.

Для лучшего понимания обоих типов состояний давайте рассмотрим пример: процесс валидации данных при входе на сайт.

В классическом приложении, основанном на страницах, у нас было бы две страницы:

  • страница с формой для ввода логина и пароля;
  • страница профиля пользователя, которая должна отображаться при успешном входе.

При неправильном вводе логина или пароля и возникновении ошибок, страница с формой входа должна перезагрузиться и отобразить сообщение об ошибках вместе с формой входа.

В SPI-приложении форма входа и страница профиля пользователя - это основные состояния, а сообщения об ошибках вместе с формой входа - это второстепенное состояние.

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

Одностраничный интерфейс и закладки

Обычно разные веб-страницы имеют разные URL, но следуя парадигме SPI мы должны изменять состояние лишь одной страницы, без ее перезагрузки, но вместе с этим мы должны изменять и URL, чтоб дать возможность пользователям добавить страницу в неком состоянии в закладки. Как мы можем это сделать?

Существует трюк, с помощью которого можно реализовать данную функцию, используя “ссылочную” часть URL (“хэш-фрагмент”), это последняя часть ссылки, которая идет после символа “#”. Обычно эта часть используется для прокрутки страницы в конкретную позицию, которая определена меткой. При изменении ссылочной части страница не перезагружается, а значит, если URL будет изменен с помощью window.location вместе с основным состоянием страницы, тогда страница перезагружена не будет. Так как URL и основное состояние будут изменены, пользователи смогут сохранить этот URL в закладки. Ссылочная часть URL будет содержать информацию о состоянии страницы, на основе этой информации могут быть запрошены данные из сервера, если пользователь захочет открыть страницу, которую он сохранил в нужном состоянии в закладках. К сожалению, ссылочная часть URL не может быть отправлена на сервер, так как ссылочная часть никак не взаимодействует с удаленным ресурсом по протоколу HTTP, следовательно, нам нужно запрашивать данные у сервера о состоянии страницы уже после загрузки самой страницы. После того, как будет загружена страница, мы можем проверить с помощью JavaScript, содержит ли объект window.location ссылочную часть, в которой должна храниться информация о состоянии. Если содержит, тогда мы можем запросить нужное состояние у сервера на основе ссылочной части URL. После выполнения дополнительного запроса к серверу мы получим страницу в нужном нам состоянии.

Другое решение, лучше чем "хэш-фрагмент", появилось с приходом HTML5, этим решением вляется HTML 5 History API.

Одностраничный интерфейс и поисковая оптимизация (SEO)

Самый простой способ сделать так, чтоб наш веб-сайт был обработан поисковыми системами - сделать две разных модели навигации: SPI - для пользователей; страницы - для поисковых ботов. Следующий пример демонстрирует ссылку, которая соответствует данной идее: <a href="http://link" onclick="return false">…</a>. Эта ссылка ничего не делает в браузерах с поддержкой JavaScript, так как навигация отключена с помощью команды "return false" атрибута onclick, но когда поисковый бот будет индексировать страницы, он проигнорирует атрибут onclick, так как JavaScript код им не выполнится, в результате чего робот сможет пройти по ссылке, занести ее в индекс и проиндексировать следующую страницу. В SPI-приложениях URL, используемый для навигации между состояниями, должен содержать идентификатор состояния, либо в ссылочной части URL, либо URL может быть задан в виде обычной ссылки с параметрами. Второй вариант предпочтительней, так как позволяет избежать лишнего запроса к серверу, также можно использовать и “красивые” URL.

На сегодняшний день Google уже “умеет” сканировать “AJAX-ссылки”, с помощью ссылочной части, которая следует за символами “#!”, что позволяет делать AJAX-приложения индексируемыми. В данном случае веб-сайт должен вернуть ожидаемую страницу, которая запрашивается в соответствии с _escaped_fragment_ параметром.

В то же время SPI веб-фреймворк может добавлять специальный код обработчика onclick перед тем, как вызвать “return false”, или может назначить ссылке event listener с помощью addEventListener или attachEvent, в зависимости от браузера, для навигации между состояниями. Этот event listener будет выполнять некие действия и отдавать команды серверу, обычно с помощью AJAX, для изменения состояния страницы. Когда пользователь кликнет по ссылке, состояние изменится, но переход на новую страницу не будет осуществлен, так как атрибут onclick="... return false" предотвратит выполнение поведения по умолчанию.

Описанная выше техника - это простейший способ сделать ссылки SPI-приложения совместимыми с поисковыми ботами. Вы также можете разделить эти функции. Например, вы можете скрыть с помощью JavaScript некоторые ссылки для пользователей, которые будут видны только для ботов, и отдельно сделать кликабельные элементы, которые будут использовать пользователи для навигации между состояниями страницы.

Наиболее важной особенностью SPI-совместимого фреймворка является возможность генерирования целых HTML-страниц в нужном состоянии, и в то же время, должна быть возможность навигации между состояниями с помощью JavaScript с перезагрузкой лишь отдельных частей страницы.

Одностраничный интерфейс и кнопки вперед/назад

Кнопки вперед/назад часто являются источником проблем для традиционных страничных веб-сайов, которые по возможности должны быть устранены. Следует избегать использования этих кнопок после отправки формы на сервер (так как это, к примеру, может привести к риску дважды купить один и тот же авиабилет или книгу на сайте). Тем не менее, следует учитывать, что использование кнопок вперед/назад широко распространено и привычно для пользователей.

Очевидно, что парадигма SPI ломает традиционный путь навигации по веб-сайту, и кнопки вперед/назад не имеют никакого смысла в SPI-приложениях (так как нет страниц), да и веб-браузеры не предоставляют должного контроля над этими кнопками.

Но это не совсем так. Работу кнопок вперед/назад можно эмулировать. Вместо навигации по страницам (по истории посещений страниц) может использоваться навигация между состояниями. В таком случае, с помощью JavaScript кода, можно определить изменения ссылочной части URL и запросить соответствующие изменения состояний приложения. Так как браузер теперь не посещает разные страницы, ваше приложение полностью отвечает за поведение кнопок вперед/назад, и можно решить типичные проблемы с некорректным использованием этих кнопок при отправке форм, так как теперь нет неконтролируемых посещений различных страниц веб-сайта.

Одностраничный интерфейс и сервисы, основанные на посещениях страниц

Рекламные сервисы и счетчики посещений работают на основе подсчета количества загруженных страниц. В таких случаях вы можете использовать скрытые iframe, которые будут содержать пустые веб-страницы со скриптами, необходимыми для работы данных сервисов. В случае с рекламными сервисами, такими как Google AdSense, использование iframe позволяет выполнять загрузку новой рекламы при каждом изменении состояния, с помощью перезагрузки iframe. Google AdSense реагирует на выполнение скрипта внутри iframe и отображает нужные данные внутри контейнера. Возможно вам понадобится передать в iframe некоторые параметры, которые будут идентифицировать текущее состояние приложения.

В случае со счетчиками посещений, мы можем использовать их для отслеживания посещений основных состояний нашего SPI-приложения. В этом случае нам нужен iframe, который будет содержать скрипт мониторинга. С помощью простого параметра мы можем идентифицировать текущее состояние приложения. Наш iframe будет глобальным (всегда один и тот же на странице). Когда страница загружена в первый раз, должно быть загружено основное состояние (которое определено в URL) и информация об этом состоянии должна быть передана параметром в iframe. Каждое последующее изменение основного состояния должно оповещать iframe, изменяя его URL при помощи JavaScript, что приведет к его перезагрузке (таким образом мы сможем идентифицировать новое посещение).

Одностраничный интерфейс и всплывающие окна

В идеале, если будет создана хоть одна новая страница, тогда получается, что мы разрушим всю парадигму SPI. Но если новое окно никак не влияет на родительское окно, тогда во всплывающих окнах нет ничего страшного.

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

К счастью это проблема решаема с помощью SPI. Вы можете эмулировать модальные или немодальные окна внутри одной веб-страницы, не создавая других страниц. В этом случае немодальные окна - это могут быть HTML-элементы с абсолютным позиционированием. Также вы можете создавать модальные окна, используя абсолютное позиционирование, z-index и полупрозрачные элементы поверх страницы (“модальные слои”). Такое решение является вполне приемлемым в контексте парадигмы SPI.

Если приложить немного усилий, любое состояние, которое отображает модальное окно может стать основным состоянием приложения и будет проиндексировано поисковыми системами.

Изменения для веб-разработчиков

Большинство веб-разработчиков (и веб-фреймворков) привыкли воспринимать веб, который основан на веб-страницах. Сведение парадигмы к использованию лишь одной страницы заставит существенно изменять процесс мышления и представления о разработке веб-приложений. Но данные изменения уже не столь радикальны, благодаря технологии AJAX, так как AJAX сегодня - это основное направление, которое позволяет сокращать количество страниц типичных веб-сайтов, в какой-то мере он и дал нам нечто приближенное к этой “новой” модели разработки на основе SPI.

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

Теперь в качестве “главного героя” выступает страница клиента с некой “симметричностью” на стороне сервера (страницы на сервере). По факту, так как мы избавляемся от необходимости сохранять состояния между страницами с помощью сессий, мы избавляемся и от источника проблем, которые проявляются, когда новые пользователи интернета открывают одну и ту же страницу в разных браузерах, что приводит к использованию разных сессий и нарушает корректную работу приложения.

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

Следуя парадигме эволюции веб-разработки, этот “новый” подход вполне может именоваться, как “Модель 4”.

Изменения для пользователей

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

Техническая реализация на сегодня

Этот манифест не является утверждением того, как именно нужно делать тот или иной функционал, это лишь четко выраженное желание продвигать “новый” путь в разработке веб-сайтов, который уже вполне реален.

Все вышеупомянутые исследования были проведены в рамках разработки Java веб-фреймворка ItsNat, который является технологической основой для разработки SPI-приложений. Но вышеупомянутые техники могут быть реализованы в рамках других существующих веб-фреймворков, или же сами фреймворки могут развиваться в данном направлении и поддерживать разработку SPI-приложений.

Пример использования

Сайт Innowhere.com разработан с помощью ItsNat и является хорошим примером SPI-сайта, так как в нем учтены все обязательные требования к SPI-приложению, которые описаны в этом документе.

SPI-парадигма заменяет существующую парадигму, но при этом не ограничивает пользователей в функционале, к которому они привыкли используя традиционный подход навигации по страницам.

Характеристики:

  • кнопки вперед/назад эмулируют навигацию по страницам, при этом навигация осуществляется между состояниями приложения;
  • основные состояния могут быть сохранены в закладки;
  • совместимость с SEO: основные состояния доступны при отклченом JavaScript, включая модальные окна; совместимость с поисковой оптимизацией для Google на основе “AJAX-ссылок”, в данном случае используется ссылочная часть URL, которая следует после символов “#!”, страница может быть запрошена в соответствии с _escaped_fragment_ параметром. Например, это состояние индексируется поисковой системой Google с помощью этой ссылки;
  • сайт работает с отключенным JavaScript;
  • на сайте есть рекламный баннер системы Google AdSense;
  • не смотря на то, что это SPI-приложение, навигация между основными состояниями мониторится системой Google Analytics с помощью скрытого iframe, URL которого изменяется при изменении основного состояния;
  • эмуляция модальных окон позволяет предотвратить создание новых страниц, эти модальные окна также доступны по прямой ссылке.

Манифест на других языках

Ссылки, указывающие на манифест


blog comments powered by Disqus