Веб-стандарты

индекс
156,37

HTML5: кэширование приложений для работы в оффлайне

HTML5 представляет несколько новых возможностей для веба, в частности: многопоточный javascript (multi-threaded Javascript), кросс-документный обмен сообщениями (cross-document messaging), хранение документов в браузере (механизм localStorage). [...]

Кэширование приложений для работы в оффлайне


У всех браузеров есть своя разновидность механизма кэширования, но, по-честному, эти механизмы не всегда работают. Скажем, Вы просматриваете какой-либо сайт на своем ноутбуке и затем закрываете его. Немного спустя, Вы открываете ноутбук и нажимаете на кнопку «Назад» в браузере, надеясь увидеть предыдущую страницу, которая была открыта. Однако, если Вы уже не подключены к интернету или браузер не закэшировал страницу должным образом, Вы не сможете ее просмотреть. Вы, конечно же, кликаете на кнопку «Вперед», в надежде что загрузится хотя бы она, но и этого не происходит. И пока Вы снова не подключитесь в Интернет, Вы не сможете просмотреть эти страницы.

До HTML4, единственным выходом было сохранять каждую страничку вручную. HTML5 предусматривает более изящное решение. Во время создания сайта, разработчик может определить файлы, которые браузер должен закэшировать. Фактически, на каждой странице, Вы можете указать какие документы должны быть закэшированы. Таким образом, если Вы обновите страницу когда Вы уже в оффлайне, страница все равно загрузится должным образом. Этот вид кэширования имеет несколько преимуществ.

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

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

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

Как это работает


Механизм, позволяющий веб-сайту быть доступным пользователю, даже если они и не соединены, очень прост. Вам необходимо прописать атрибут manifest в тэге html. Значением атрибута должна быть гиперссылка на файл manifest.cache, в котором содержаться правило для кэширования:

<!DOCTYPE HTML>
<html manifest="manifest.cache">
...

А вот как обычно выглядит файл manifest.cache:

# v1
# this is how you add a comment to the manifest.

CACHE MANIFEST
index.html
stylesheet.css
images/masthead.png
scripts/misc.js

NETWORK:
search.php
login.php
/api

FALLBACK:
images/dynamic.php static_image.png

В файле manifest.cache три заголовка:

* CACHE
* NETWORK
* FALLBACK

Обратите внимание, что MIME type файла manifest.cache — text/cache-manifest. Вам может понадобиться добавить нестандартный тип расширения файла привязки к Apache (или к любому другому веб-серверу, который Вы используете) или выставить mime-type, например, используя директиву PHP header.

Файлы, перечисленные после CACHE будут закэшированы сразу после того, как они загрузятся; а файлы, перечисленные после NETWORK считаются белым списком. Это означает, что им необходимо непосредственное соединение с сервером. Если пользователь не соединен с сервером, браузер не должен отображать вместо них закэшированную версию.

Раздел FALLBACK (досл. «нейтрализация неисправности») содержит записи, которые предусматривают стратегию создания резервной копии. Если браузер не в состоянии восстановить исходный контент, будет задействован резервный ресурс. В примере выше, мы отображаем статическое изображение в случае если динамическое будет недоступно.

Последняя строка в разделе NETWORK содержит путь к папке для обеспечения выполнения запросов загрузки ресурсов, содержащихся в /api, которые будут избегать кэширования и всегда получать данные с сервера.

В манифесте, любая строка, начинающая с # обрабатывается как комментарий. Помимо увеличения читабельности кода, комментарии имеют еще одну возможность использования. Представьте, что Вы указали, что файл masthead.png должен быть закэширован; но Вы обновили изображение. Теперь, поскольку кэш будет обновлен только когда изменится манифест, пользователь будет продолжать видеть старое закэшированное изображение. Вы же можете решить проблему путем изменения части манифеста; например, хорошим способом будет увеличение номера версии каждый раз, когда Вы обновляете свой сайт.

Примечания:


A/ Если Вы заметили ошибку или неточность, пожалуйста, укажите на них в комментариях — обязательно исправлю.

B/ Если у Вас есть на примете какая-либо интересная, еще не переведенная, статья по HTML/CSS/PHP и т. п. на англ. языке — напишите в личку (в случае опубликования, благодарность в начале статьи за помощь в поиске с указанием Вашего ника — гарантирована :).
+31
9 октября 2009, 11:00
51

комментарии (39)

+1
WilliamKidd #
Как сейчас дела с поддержкой атрибута manifest в браузерах?
НЛО прилетело и опубликовало эту надпись здесь
0
Solopov #
Да, не так давно намучился я с этой «малостью» — основная ее суть в том, что если FF воспринимает файлы, которые не указаны в манифесте, как подлежащие обычному кешированию стандартными механизмами браузера, то Safari перестает грузить ВСЕ файлы, которые не указаны в манифесте даже в режиме онлайн! А если проект большой, то это очень не удобно.
0
devolonter #
А как решили данную проблему если не секрет?
+2
Solopov #
Ну чтобы руками не прописывать сделал небольшой скриптик-анализатор логов апача, он вытягивает список файлов, которые просмотрел и запихнул в манифест + прописал директории в раздел нетфорк. Кстати по документации у нетворка есть интересный параметр "*", но в сафари у меня с ним проблемы были.

А вообще — хороший повод на стороне сервера в СSS использовать data.uri.
0
egorinsk #
Блин, вот идиотизм, был же заголовок Expires, он то чем не подошел? Зачем плодить еще кучу стандартов.
+1
Solopov #
Это разные вещи — стандартный механизм кеширования браузера никто не отменял, но это вытесняемый кеш, а манифест постоянный. Кстати, и сдесь реализация FF более правильная (ИМХО), он спрашивает сохранять данные или игнорировать манифест.
0
el777 #
А чем плох Cache-control?
Там же все это есть: кешировать ли (no-cache|public|private) и на сколько кешировать (max-age), и на сколько допускается устаревание документа (max-stale) — будет посильнее этого манифеста. Там нет пожалуй только fallback-а.
Начало статьи такое как будто написано Микрософтом — с таким упоением рассказывается о новой ни с чем не совместимой ерунде, аналоги которой уже давно существуют.
НЛО прилетело и опубликовало эту надпись здесь
+1
el777 #
>Cache control не дает гарантии, что страница покажется в офлайне.
Это говорит только о том, что технология не используется на все 100%. Если уж разрешено кешировать на год вперед, то почему бы не закешировать и сделать доступным для оффлайного просмотра.
0
tenshi #
а манифест даст гарантию, что ваш винч будет засран половиной интернета >:-E

мой сайт нормально открывается в автономном режиме.
0
akral #
Гарантии никакой. Как браузер не закешировал из-за Cache-control, так не закеширует из-за manifestа. Всё-таки место на диске не бесконечно.
–3
crwin #
что-то тоже не понял зачем это, если есть необходимые заголовки в пхп. + настроить можно абсолютно как угодно и не только хтмл-файлы
+5
akral #
В HTTP, вообще-то, а не в PHP. Из-за таких заявлений PHP-кодеров и считают ниже плинтуса. :(
+2
ipod #
А по-моему, интересная вещь. Можно сделать оффлайн приложение, например, на JS. Калькулятор, редактор, да много интересных вещей. Пользователь всегда может что-то сделать даже при отсутсвии интернета.
0
Solopov #
Для этого и использовал — еще если использовать локальные хранилища данных, вообще удобно получается.
0
majesty #
А как кешировать картинки, если они отдаются с другого хоста? Нипанятнаааа… :(
+1
majesty #
Паняяяятна :)

CACHE MANIFEST
static.host/image.png
НЛО прилетело и опубликовало эту надпись здесь
+1
el777 #
Скорее просто стирается граница между веб-приложениями и локальными. Веб-приложения начинают работать локально — AIR, Gears и пр., а локальные очень активно используют данные из веба — Google Earth и тп.
В мире постоянного широкополосного доступа это не проблема, но если доступ периодический, то работать будет через раз.
+3
force #
Из этого манифеста, мне не нравится то, что он не XML. Т.е. придумали ещё один очередной формат описания, которого как всегда не хватит, добавят ещё поля, которые будут обрабатываться старыми браузерами не пойми как, потом придёт гугл и сделает manifest.cache2 и опять всё будет непойми как.

ЗЫ: А можно в манифесте прописать кеширование манифеста? ;)
0
lol2Fast4U #
HTML5… А можно его прописать в XHTML?
+1
akral #
Забудьте про XHTML.
Если так нравятся строгие правила, используйте XHTML сериализацию HTML5.
+1
lol2Fast4U #
А если мне нужно его расширять? X на то и eXtensible.
Покажите мне, как проходит валидацию HTML5 с xmlns?
XFBML как мне валидно встроить в HTML5?
+1
akral #
Вопрос расширения XHTML сериализации HTML ещё не решён. Спецификация не закончена.

Если он так и не будет решён, используйте XHTML 1.1, который для этих целей и создан, в чём проблема?
+1
akral #
Кстати, в конкретном вашем примере, XFBML отдаётся не пользователю, а серверу, которому, в принципе, манифест к чёрту не сдался.

В других случаях всё упирается в то, что самое главное (svg и MathML) вставляются сразу, на уровне спецификации HTML5, а дальше идут размышления.
0
lol2Fast4U #
XHTML 1.1 используем. Хочется в нем чтобы были все эти манифесты и прочие рюшечки.
XFBML отдается пользователю. Как же он видит кнопочку авторизации, комментарии и прочие соц. виджеты?
0
akral #
XFBML отдается пользователю.

Я не разбираюсь в XFBML, но ведь Facebook приложения работают в IE. Когда я кодил приложения на Facebook, движок Facebook брал у меня страницу, подстовлял в шаблоны свои поля (типо fb:friendselector подменялся на огромный
<div class="friend selector"><input type="checkbox">...
) и показывал пользователю.

Иначе — как браузер отображает все рюшечки Facebook?
+1
lol2Fast4U #
Очень просто — он находит элементы в www.facebook.com/2008/fbml Рендерит Javascript'ом — но на клиенте же он работает!
0
akral #
А, Javascriptом. Тихий ужас.
0
akral #
Нет, правда. Если можно генерировать на стороне сервера, зачем это делать JSом?
НЛО прилетело и опубликовало эту надпись здесь
+1
lol2Fast4U #
Хм, а оно проходит :) Но ведь стандарт еще разрабатывается. Вдруг запретят?
НЛО прилетело и опубликовало эту надпись здесь
+2
akral #
А, кстати, вы документацию читать пытались?
HTML5 в XHTML serialization не препядствует xmlns:
In HTML documents, elements in the HTML namespace may have an xmlns attribute specified, if, and only if, it has the exact value «www.w3.org/1999/xhtml ». This does not apply to XML documents.

[..]
In XML, an xmlns attribute is part of the namespace declaration mechanism, and an element cannot actually have an xmlns attribute in no namespace specified.


Пример:
Elements from other namespaces…
<Person xmlns="http://www.w3.org/2000/10/swap/pim/contact#"
           r:about="http://hedral.example.com/#">

+2
akral #
Твою мать! Почему оно само постится?!

Далее. Чтение XML (XHTML):
When faced with displaying an XML file inline, user agents must first create a Document object, following the requirements of the XML and Namespaces in XML recommendations, RFC 3023, DOM3 Core, and other relevant specifications. [XML] [XMLNS] [RFC3023] [DOMCORE]
[..]
If the root element, as parsed according to the XML specifications cited above, is found to be an html element with an attribute manifest, then, as soon as the element is inserted into the document, the user agent must resolve the value of that attribute relative to that element, and if that is successful, must run the application cache selection algorithm with the resulting absolute URL with any component removed as the manifest URL, and passing in the newly-created Document. Otherwise, if the attribute is absent or resolving it fails, then as soon as the root element is inserted into the document, the user agent must run the application cache selection algorithm with no manifest, and passing in the Document.

+1
lol2Fast4U #
ну, я уже это читал, правда понял только сейчас.
>This does not apply to XML documents.
не считал HTML5 XML-документом…
+2
akral #
HTML5 в сериализации XHTML и есть XML.

Напоследок — имеется однозачное заявление самого Ian Hickson, что xmlns никто не отменял.
НЛО прилетело и опубликовало эту надпись здесь

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.