Как стать автором
Обновить

ActionWeb. Асинхронный интернет.

Время на прочтение7 мин
Количество просмотров1.4K
С момента первого упоминания об AJAX в статье Джесси Джеймса Гарретта «Новый подход к разработке веб- приложений» 18 февраля 2005 года прошло уже 4 года. За это время наверно каждый веб- разработчик хоть раз испробовал эту технологию, и теперь обычного пользователя интернет уже не удивить динамической валидацией форм, автодополнением запросов в строке поиска, всплывающим контекстным меню и прочими ещё недавно диковинными вебдванольными интерактивными радостями, а современные JavaScript фрэймворки делают процесс разработки таких скриптов на порядок быстрей, эффективней и приятней для программиста. Но почему до сих пор подавляющее большинство разрабатываемых веб- сайтов придерживаются стандартной модели загрузки контента и не перешли полностью на AJAX платформу? Зачем каждый раз перезагружать всю страницу при нажатии на внутреннюю ссылку, когда нужно изменить только блок контента, а JavaScript файлы, CSS и большая часть HTML разметки не требует обновления?


Причин несколько:

— Каждый раз открывая в браузере AJAX ресурс, пользователь начинает работу с «отправной точки», т.к. состояние такого приложения в большинстве случаев не отображается в адресной строке браузера
— Динамически подгружаемый контент не обрабатывается поисковыми роботами
— Разработка асинхронных веб- приложений на порядок сложнее и длительнее, чем при использовании статической модели
— Отсутствие интеграции AJAX приложений со стандартными инструментами браузера. По такому ресурсу нельзя перемещаться, используя кнопки браузера back и forward, нельзя добавить страницу сайта в закладки, если она подгружается динамически, нельзя открыть ссылку на динамический контент в новой вкладке браузера
— Использование «толстого» клиента существенно увеличивает нагрузку на процессор компьютера пользователя и требуемый объём оперативной памяти
— AJAX приложение окажется не работоспособным при выключенном JavaScript в браузере пользователя

Для преодоления перечисленных выше проблем потребуется совершенно новая концепция, которую назовём ActionWeb. По своей сути ActionWeb (как и AJAX в своё время) не предлагает новых технологий, а только лишь изменяет принцип использования уже известных. Выдвинем основные тезисы концепции:

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

Рассмотрим определённые выше проблемы AJAX приложений, и механизмы их решения, реализованные при создании сайта nikitaeremin.com с учётом использования концепции ActionWeb.

Проблема: Текущее состояние AJAX ресурса не отображается в адресной строке браузера, пользователь каждый раз начинает работу с «отправной точки».
Решение: При изменении url в адресной строке браузера происходит перезагрузка страницы. Из этого правила есть только одно исключение: без перезагрузки можно менять хэш адресной строки (location.hash), проще говоря добавлять\убирать символ # и всё что стоит за ним. В адресной строке будет что-то вроде nikitaeremin.com/#projects/persik/, а ActionWeb приложение при инициализации вычленяет из неё хэш и соответствующим образом формирует своё состояние.

Проблема: динамически подгружаемый контент не обрабатывается поисковыми роботами
Решение: просматривая веб- ресурс поисковые роботы не воспринимают JavaScript. Сканируя исходный HTML код страницы, они путешествуют по внутренним ссылкам, при этом адрес nikitaeremin.com/#projects/persik/ для них будет означать переход на главную страницу. Выход- в исходном коде оставить ссылки как они есть, при этом разделить их на внутренние и внешние. Разделить можно, например, путём добавления css класса к ссылке. При инициализации ActionWeb приложения на ссылки с заданным классом прикрепляются обработчики событий, которые динамически подгружают контент и меняют хэш адресной строки браузера. Но что будет, когда пользователь перешёл с поисковика по ссылке nikitaeremin.com/projects/persik/, проиндексированной в исходном коде ActionWeb приложения? На соответствующей странице ставится редирект на nikitaeremin.com/#projects/persik/, происходит переход на главную страницу и приложение формирует своё состояние, исходя из хэша адресной строки.

Проблема: Отсутствие интеграции AJAX приложений со стандартными инструментами браузера
Решение: Если использовать описанную выше технику изменения адресной строки, проблема добавления в закладки решается сама собой. Так же решается проблема невозможности открыть внутреннюю ссылку AJAX приложения в новой вкладке браузера, т.к. в ActionWeb приложении нажимая правой кнопкой мыши на внутреннюю ссылку, пользователь нажимает на обычную ссылку, и браузер работает с ней точно так же, как он работал бы с ней на статическом сайте. Восстановить же функции браузера back и forward можно двумя путями. Первый способ- использовать плагин history для jQuery, написанный как раз для этих целей, но данный скрипт не отличается кроссбраузерностью и некорректно работает прежде всего в Internet Explorer. Второй путь- сохранять все изменения адресной строки в JavaScript массиве и с помощью несложных манипуляций реализовать кнопки back и forward прямо на странице приложения.

Проблема: Разработка AJAX приложений на порядок сложнее, чем при использовании статической модели
Решение: Разделение презентационного слоя и слоя логики клиентской части приложения. При таком подходе от проекта к проекту меняется только презентационная составляющая, все функции взаимодействия с сервером, получения и обработки информации «зашиты» внутрь движка, обеспечивая достаточный уровень абстракции, и разработчику не надо задумываться о них. Некоторые возможности, связанные с работой бизнес-модели приложения, такие как кэширование подгружаемых контентных страниц, имя класса для внутренних ссылок ресурса и т.п. можно конфигурировать в JSON объекте, передаваемом движку при инициализации.

разделение слоя логики и презентационного слоя

Проблема: Использование RIA существенно увеличивает нагрузку на процессор клиентского компьютера
Решение: При использовании JavaScript нагрузка на процессор происходит в основном из-за насыщенности презентационного слоя, в особенности когда несколько функций анимации исполняются одновременно друг с другом или с функциями слоя безнес- логики, а при чрезмерной нагрузке браузер может просто «повиснуть». Выход- реализация цепочечного вызова функций на критических участках приложения. Цепочечный вызов означал бы не допущение исполнения нескольких функций одновременно, предотвращая тем самым чрезмерную нагрузку на компьютер пользователя. Но для реализации этого механизма в JavaScript не достаточно просто расположить вызовы функций один под другим, это просто не сработает, если в таком списке последовательного вызова будет хоть одна функция анимации, т.к. JavaScript интерпретатор сталкиваясь с отсроченными во времени операциями (проще говоря с таймаутами) не останавливается в ожидании их завершения, а идёт дальше по коду. Приведём простой пример, написанный на jQuery. Допустим, есть функция анимации и функция логики, функцию логики необходимо выполнить только после завершения работы функции анимации:

function animation(){ 	
    $("#elem").animate({"width" : "300px"}, 200, "linear", function(){ 
        alert("animation first!"); 
    }) 
}  

function logic(){ 
    alert("logic first!"); 
}  

animation(); 
logic();


При исполнении приведённого выше кода первый алерт будет «logic first!», т.к. завершение функции анимации отсрочено по времени. А для достижения нашей цели код следовало бы переписать следующим образом:

function animation(){ 	
    $("#elem").animate({"width" : "300px"}, 200, "linear", function(){ 
        alert("animation first!");  
        logic();     	
    }) 
} 

function logic(){ 	
    alert("logic first!"); 
}  

animation();


Но при таком подходе не выполнялся бы 4й тезис концепции ActionWeb. Для реализации анонимного вызова функций бизнес-логики в движке Persik потребовалось написание метода chain, связывающего компоненты бизнес-модели и презентационного слоя. В слое бизнес-логики использование метода chain выглядит следующим образом:

engine.chain(func1, [vars1]).chain(func2, [vars2]).chain(func3, [vars3]).start();


При этом в каждой функции цепочки должна быть явно определена точка выхода:

function animation(){ 	
    $("#elem").animate({"width" : "300px"}, 200, "linear", function(){ 		
        alert("animation first!");         		
        animation.next();     	
    }) 
}

function logic(){ 	
    alert("logic first!"); 	
    logic.next();
} 

persik.chain(animation).chain(logic).start();


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

Проблема: AJAX приложение окажется не работоспособным при выключенном JavaScript в браузере пользователя
Решение: В сущности, что из себя представляет ActionWeb ресурс? Это интерактивное веб- приложение, использующее метод асинхронной загрузки данных, состояние которого в большинстве случаев однозначно определяется через url. Что изменится, при выключении JavaScript? Состояние приложения не будет формироваться на стороне клиента, возможность асинхронной загрузки данных станет недоступной, функции анимации не будут выполнены. В таком случае формировать состояние приложения можно на стороне сервера, из функций анимации вычленить конечные состояния объектов (открыто\закрыто), выделить их в отдельные классы и формировать состояние DOM объектов с помощью классов (простейший пример- подсветка текущего пункта меню), асинхронная загрузка контента сменится на традиционную, и в итоге получится самый обыкновенный с точки зрения архитектуры веб- ресурс. На сервере нужно будет определить, включён ли js в браузере пользователя, и исходя из этого выдавать либо ActionWeb вариант сайта, либо обычный статический. Конечно реализация такого подхода возможна не для всех AJAX приложений, и в статическом варианте будут доступны только функции загрузки и отображения контента, но в итоге разработчик будет уверен в том, что пользователь гарантированно получит минимальный объём функциональности сайта, не зависимо от настроек его браузера.

как мой сайт работает с выключенным js

В итоге созданный ресурс распознаётся поисковыми роботами, не теряет работоспособности при выключенном JavaScript в браузере пользователя, быстрее работает за счёт AJAX и отличается высокой презентационной привлекательностью за счёт применения JavaScript анимации.
Теги:
Хабы:
Всего голосов 73: ↑38 и ↓35+3
Комментарии22

Публикации

Работа

Ближайшие события