Главная > AJAX, Flash, ActionScript, Open Source, веб-обзоры, Разное > Исследование AJAX Client Storage — от хирургии Dojo к собственной реализации Fullajax Storage

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

4 июня 2008

С интенсивным развитием веб-приложений все более востребованным становится хранение больших объёмов данных  на стороне клиента. Это не просто упрощает приложение – часто именно применяя клиентскую систему хранения данных можно существенно расширить функциональность создаваемого приложения, позволив ему делать то, что в другом случае было бы невозможно. При этом, не следует воспринимать это как «прихоть» разработчиков каких-то особых и экзотических веб-сервисов – по последним данным даже такой гранд среди массовых западных социальных сервисов, как сеть MySpace будет применять решение от Google – Google Gears (подробнее). В сети имеется ряд публикаций на тему использования локальных хранилищ, например, можно отметить следующие публикации, которые мы изучали при подготовке материала:

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

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

Давайте посмотрим на явные преимущества Flash Storage:

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

Одни разработчики склонны приписывать этому методу недостаток в том, что якобы пользователи блокируют Flash из-за баннеров, однако я считаю эту проблему больше надуманной, чем реальной. Если так, то они и графику отключат, и скрипты – а значит, как говорится в одном изречении, «сами себе буратино» - Flash сейчас часто неотъемлемая часть многих сайтов и единственная приемлемая технология для реализации мультимедии в веб-среде.

Следует отметить, что из всех проанализированных нами Flash стораджей, наиболее привлекательным по функциональности оказался сторадж, который входит в состав библиотеки Dojo (dojotoolkit.org). Более того, по большому счету, это первая промышленная реализация этой технологии.
Отличительные достоинства:

  • Возможность хранения JS-объектов, автоматическая сериализация и десериализация (конечно, в формате JSON).
  • Учтены некоторые баги работы Flash ExternalInterface
  • Мощный и универсальный API для работы с хранилищем данных.
  • Встроенная поддержка пространства имён для хранимых данных, работа с несколькими хранилищами одновременно.
  • Наличие статуса PENDING (для случаев переполнения хранилища и ожидания ручного увеличения лимита)
  • При превышении текущего предельного размера хранилища - автоматический вывод диалога-запроса на разрешение увеличить размер

Конечно, это решение при всех его достоинствах, не лишено и недостатков:

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

Тестовый пример грузит 13(!) скриптов. Загрузка всех их осуществляется с  использованием AJAX, причем даже при явном указании использовать Flash Storage, все равно грузится куча дополнительных файлов, которые не нужны для работы данного хранилища. Простейший пример helloworld -  грузит не меньшее количество 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, необходимо проектировать с учётом данной особенности.

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

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

Алгоритм работы данного метода похож на принцип реализации SVN. Сайт имеет номер глобальной версии. Любые изменения отдельного контента или групповое изменение контента, увеличивает номер версии. При начальной загрузке сайта на сервер отсылается номер версии на клиентской стороне. Сервер сверяет присланную версию на клиенте с текущей версией на сервере  и, если имеются отличия, в ответ формируется список изменённых идентификаторов-ключей контента в соответствии с разницей клиентской и серверной версий сайта. Другими словами при изменении контента на сервере, на клиент отсылается список ключей, которые необходимо удалить в хранилище. Этот список соответствует разности изменений между версией сайта клиента и текущей версией на сервере. В это же время сам контент на клиент не отправляется - только при запросе клиентской стороной конкретных данных  и при удачной загрузке попадает в хранилище.


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

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

Алгоритм основан на идентификации уникальности конкретно каждой отдельной единицы контента. Суть заключается в том, что при начальной загрузки сайта с сервера приходит список пар значений {ключ: идентификатор новизны}. Клиентский скрипт проверяет совпадение идентификаторов новизны в хранилище. Если имеются отличия, из хранилища удаляются  старые значения идентификаторов новизны и данные соответствующие обновлённому ключу контента. Тут же в хранилище записываются  новые  значения идентификаторов новизны. Так же, как и в ранее рассмотренном методе, контент на клиент отправляется только при запросе клиентской стороной конкретных данных и при удачной загрузке попадает в хранилище.


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

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

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

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

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

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

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

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

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

P.S. Автор материала: Руслан Синицкий ( sirus , http://fullajax.ru), соавтор: Александр Лозовюк (aleks_raiden, http://abrdev.com)

  • Статья конечно интересная, только немного трудна для понимания:) может просто это все только для профи.

  • да, материал не простой… вы задавайте вопросы что непонятно 🙂

  • сергей

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

  • Сергей, а чем JS код библиотеки отличается от текста? Ничем 🙂 а что делает Eval, знаете? Значит можно, хотя это вряд ли самый оптимальный путь, но в некоторых случаях вполне допустим и оправдан.

  • можно не только eval, можно обьект script создать и впихнуть его в head, так будет даже более правильно

    хранение js библиотек представляется не только возможным но и эффективным! и я бы сказал не в некоторых случаях, а во многих

Developers.org.ua