Pull to refresh

Исследование AJAX Client Storage — от хирургии Dojo к собственной реализации Fullajax Storage

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

При этом, не следует воспринимать это как «прихоть» разработчиков каких-то особых и экзотических веб-сервисов – по последним данным даже такой гранд среди массовых западных социальных сервисов, как сеть MySpace будет применять решение от Google – Google Gears (подробнее — gearsblog.blogspot.com/2008/05/myspace-message-center-is-now-searching.html). В сети имеется ряд публикаций на тему использования локальных хранилищ, например, можно отметить следующие публикации, которые мы изучали при подготовке материала:

browserpersistence.ru
abrdev.com/?tag=storage
pablotron.org/software/persist-js

Если у вас нет понятия что такое локальное хранилище, или вы слабо знакомы с этим, по выше указанным ссылкам вы найдете исчерпывающую информацию относительно storages и областей его применения.
Исследовав все возможные варианты реализации локальных хранилищ данных, наиболее привлекательным на данный момент времени является хранилище на основе Flash. Заметьте, что мы ведем речь о постоянных хранилищах данных, то есть, сохраняя туда какие-либо данные, мы ожидаем возможности получить к ним доступ на клиентском компьютере и после закрытия страницы в браузере, и обновлении и даже после перезагрузки компьютера. В данной статье будет проведен анализ реализации хранилища на основе Flash.
Давайте посмотрим на явные преимущества Flash Storage:
  • Максимальная кросс-браузерность (по понятным причинам мы не рассматриваем экзотические варианты браузеров, не поддерживающих обычные для веба технологии).
  • Максимальная распространенность: Flash установлен на более чем ~95% браузеров.
  • Возможность хранить практически неограниченный объем данных (хотя с некоторыми оговорками, например то, что пользователь должен явно разрешить хранение указанного обьема или установить разрешение на хранение неограниченного количества информации).

Одни разработчики склонны приписывать этому методу недостаток в том, что якобы пользователи блокируют Flash из-за баннеров, однако я считаю эту проблему больше надуманной. Если так, то они и графику отключат, и скрипты – а значит, как говорится в одном изречении, «сами себе буратино» — Flash сейчас часто неотъемлемая часть многих сайтов и единственная приемлемая технология для реализации мультимедии в веб-среде.
Следует отметить, что из всех проанализированных нами Flash стораджей, наиболее привлекательным по функциональности оказался сторадж, который входит в состав библиотеки Dojo (dojotoolkit.org). Более того, по большому счету, это первая промышленная реализация этой технологии.
Отличительные достоинства:
  • Возможность хранения JS-объектов, автоматическая сериализация и десериализация (конечно, в формате JSON).
  • Учтены некоторые баги работы Flash ExternalInterface.
  • Мощный и универсальный API для работы с хранилищем данных.
  • Встроенная поддержка пространства имён для хранимых данных, работа с несколькими хранилищами одновременно.
  • Наличие статуса PENDING.
  • При превышении текущего предельного размера хранилища — автоматический вывод диалога-запроса на разрешение увеличить размер.

диалога-запроса на разрешение увеличить размер

Конечно, это решение при всех его достоинствах, не лишено и недостатков:
  • Большой объем дистрибутива (имеется ввиду, что если вы применяете Dojo только ради системы Storage).
  • При инициализации хранилища, загрузка лишнего кода, который может и не понадобится при работе приложения.
  • Неработоспособность при работе скрипта с локальной файловой системы file://

Тестовый пример download.dojotoolkit.org/release-1.1.0/dojo-release-1.1.0/dojox/storage/tests/test_storage.html?forceStorageProvider=dojox.storage.FlashStorageProvider грузит 13(!) скриптов. Загрузка всех их осуществляется с использованием AJAX, причем даже при явном указании использовать Flash Storage, все равно грузится куча дополнительных файлов, которые не нужны для работы данного хранилища.

Простейший пример helloworld — download.dojotoolkit.org/release-1.1.0/dojo-release-1.1.0/dojox/storage/demos/helloworld.html грузит не меньшее количество JS-скриптов. Поэтому можно сделать вывод – в случае, если ваше приложение не использует какой-либо функционал Dojo Toolkit, привлекать его для реализации только лишь Storage достаточно ресурсоемко и не эффективно.

Так как «корень недостатков» один и тот же, мы решили избавиться от этих недостатков, или хотя бы максимально уменьшить их влияние. Скачав дистрибутив Dojo 1.1, пришлось засесть за анализ его архитектуры с целью отдельно выделить только Flash Storage. Вот здесь то и оказалась первая сложность. Субъективно, внутренняя архитектура Dojo очень нетривиальная и сложная (ну конечно, ведь это самый мощный фреймворк из всех, вероятно, реализованных на JS, использующий несколько парадигм программирования, например, недавно пополнился модулем для реализации аспектно-ориентированного программирования). Поэтому просто и быстро выделить отдельно Flash Storage не получалось. Но желание устранить указанные недостатки оказалось больше встретившихся трудностей.

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

Уже более детальные тесты Flash Storage показали еще одно преимущество: хранилище одно для всех браузеров на компьютере, т.е. данные сохраненные при использовании Firefox, спокойно достаются из Internet Explorer и наоборот.

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

Но возможность просто хранить некоторые данные на клиенте и получать их для работы приложения – это не единственный функционал. Очень хотелось бы иметь возможность контролировать данные в таком кеше и автоматически со стороны сервера их обновлять.

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

Метод глобальной версионализации сайта

Алгоритм работы данного метода похож на принцип реализации SVN. Сайт имеет номер глобальной версии. Любые изменения отдельного контента или групповое изменение контента, увеличивает номер версии. При начальной загрузке сайта на сервер отсылается номер версии на клиентской стороне. Сервер сверяет присланную версию на клиенте с текущей версией на сервере и, если имеются отличия, в ответ формируется список измененных идентификаторов-ключей контента в соответствии с разницей клиентской и серверной версий сайта. Другими словами при изменении контента на сервере, на клиент отсылается список ключей контента, который необходимо удалить в хранилище. Этот список соответствует разности изменений между версией сайта клиента и текущей версией на сервере. В это же время сам контент на клиент не отправляется. Контент отправляется только при запросе клиентской стороной конкретных данных и при удачной загрузке попадает в хранилище.
Метод глобальной версионализации сайта
Оригинальное изображение алгоритма fullajax.ru/doc/storage/Storage-Algorithm-1.jpg

Рассмотренный алгоритм уменьшает количество коннектов к серверу и общий объем передаваемой информации. Данный метод удобно применять при большом количестве единиц контента.

Метод версионализации отдельных единиц контента

Алгоритм основан на идентификации уникальности конкретно каждой отдельной единицы контента. Суть заключается в том, что при начальной загрузки сайта, с сервера приходит список пар значений {ключ: идентификатор новизны}. Клиентский скрипт проверяет совпадение идентификаторов новизны в хранилище. Если имеются отличия, из хранилища удаляются старые значения идентификаторов новизны и данные соответствующие обновленному ключу контента. Тут же в хранилище записываются новые значения идентификаторов новизны. Так же, как и в ранее рассмотренном методе, контент на клиент отправляется только при запросе клиентской стороной конкретных данных и при удачной загрузке попадает в хранилище.
Метод версионализации отдельных единиц контента
Оригинальное изображение алгоритма fullajax.ru/doc/storage/Storage-Algorithm-2.png

Рассмотренный алгоритм уменьшает количество коннектов к серверу и общий объем передаваемой информации. Данный алгоритм прост в реализации и его использование эффективно при малом количестве единиц контента. При большом количестве единиц контента список пар значений {ключ: идентификатор новизны} может быть слишком большой, что снижает эффективность применения данного алгоритма.

Стандартный метод использования Etag

Метод основан на отправке серверу Etag идентификатора контента. При совпадении присланного идентификатора на клиенте с текучим серверным идентификатором, в ответ сервер отвечает 304 Not modified и клиент берет данные из хранилища. При отличии идентификаторов сервер отвечает новым контентом. Клиент успешно загрузивши новый контент, заменяет в хранилище старые данные новыми и записывает его Etag идентификатор новизны.

Рассмотренный алгоритм уменьшает только общий объем передаваемой информации. Метод прост в реализации, но по количеству подключений к серверу менее эффективен по сравнению с ранее рассмотренными алгоритмами.

Выбор использования того или иного подхода зависит от конкретной ситуации.

Примеры применения

Использовать Flash Storage удобно не только для хранения конфигурационных данных и обьектов веб-приложения, а также для хранения скриптов, стилей, картинок и даже непосредственно самого контента. Пример применения хранилища реализован на уже известном вам сайте fullajax.ru. На данном сайте для обновлении данных на стороне клиента применен выше рассмотренный «Метод версионализации отдельного контента». В хранилище сохраняются скрипты и контент, т.е. однажды загрузив страницу данного сайта последующие разы она достается из хранилища, до тех пор пока на сервере не появится более новая версия страницы.

Особенно эффективно использовать связку AJAX + Storage. В состав Fullajax библиотеки включен модуль для реализации Flash Storage. Тем пользователям, которые уже используют библиотеку Fullajax достаточно подключить дополнительный скрипт и при запросе данных с помощью AJAX (dax или hax методы) данные автоматически будут попадать в хранилище. Остается только позаботится об механизме обновления данных на стороне клиента.

Конечно, данная реализация не является единственной. Да и во многих случаях ей будет очень нехватать отдельных функциональностей. Не буду скрывать – действительно лучшим вариантом сейчас будет встроенная СУБД из Google Gears, однако это решение достаточно эксклюзивное и может быть эффективно использовано только в особых случаях веб-приложений. Ну а для массового применения, в том числе и на обычных веб-сайтах действительно лучше всего применять либо описанное выше решение, либо одно из универсальных, например, Browserpersistense или PersistJS.

Автор материала: Руслан Синицкий ( sirus, fullajax.ru), соавтор – Александр Лозовюк (aleks_raiden, abrdev.com).
Tags:
Hubs:
Total votes 17: ↑16 and ↓1 +15
Views 1.5K
Comments Comments 30