Кэширование css. Cache-js

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

К счастью, мы можем воспользоваться возможностями JavaScript"a и написать функцию cache , способную кэшировать результаты работы других методов, чтобы, в случае надобности, повторно не вызывать эти самые методы:

Function cache(key, value) { if (typeof value == "undefined") { return cache; } cache = value; }

Теперь на примерах рассмотрим как будет вести себя написанная выше функция cache.

Пример 1. Кэширование querySelector

// _io_q - обертка под querySelector, сохраняющая данные в кэш _io_q = function(selector) { if (!cache(selector)) { cache(selector, document.querySelector(selector)); } return cache(selector); }

Теперь посмотрим на скорость работы _io_q и querySelector:

Console.time("regular querySelector"); for (var i = 0; i < 1000000; i++) { document.querySelector("h1"); } console.timeEnd("regular querySelector"); // regular querySelector: 100.6123046875ms console.time("cached _io_q"); for (var i = 0; i < 1000000; i++) { _io_q("h1"); } console.timeEnd("cached _io_q"); // cached _io_q: 5.77392578125ms

Пример 2. Кэширование запросов с сервера

Напишем функцию, которая отправляет очень тяжелый запрос на сервер:

Function longRequestToServer(params) { var key = params.endpoint + "_" + params.value; if (!cache(key)) { var result = 0; for (var i = 0; i < 999999999; i++) { result++; } cache(key, result); } return cache(key); }

Посмотрим как будет вести себя функция:

Console.time("first run"); longRequestToServer({ endpoint: "/loadExample", value: 10}); console.timeEnd("first run"); // first run: 1012.068115234375ms console.time("second run"); longRequestToServer({ endpoint: "/loadExample", value: 10}); console.timeEnd("second run"); // second run: 1.31884765625ms console.time("other request"); longRequestToServer({ endpoint: "/loadSomeOtherData", value: 15 }); console.timeEnd("other request"); // other request: 1033.783203125ms

TL;DR

Используя возможности JavaScript"a можно эффективно кэшировать данные, выигрывая в производительности. Но будьте аккуратны, ведь выигрывая в производительности можно потерять на ресурсах и по неосторожности добиться утечки памяти.

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

Для наглядности приведу пример до:
function loadData(url, fn) { ajax.get(url, function (err, result) { //тут обрабатываем ответ и возвращаем результат var data = "..."; fn(null, data); }); }
и после:
var cache = {}; function loadCacheData(url, fn) { var cacheData = cache; //проверяем кэш if (cacheData) { fn(null, cacheData); } else { ajax.get(url, function (err, result) { //тут обрабатываем ответ и возвращаем результат var data = "..."; //сохраняем в кэш cache = data; fn(null, data); }); }

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

Это положило начало к написанию простой функции обертки которая превращала бы loadData в loadCacheData.
Выглядеть это должно примерно так:
function loadData(url, fn) { ajax.get(url, function (err, result) { //тут обрабатываем ответ и возвращаем результат var data = "..."; fn(null, data); }); } var loadCacheData = cache(loadData);
Полученная таким способом функция «loadCacheData» должна сама кэшировать результат, а так же предоставлять функционал по управлению кэша.

Через некоторое время удалось реализовать более менее работающую версию функции «cache». Все исходники доступны на github .

Что позволяет делать эта функция:

1. Сброс кэша.
var loadCacheData = cache(loadData); loadCacheData.clearCache();

2. Устанавливать время жизни для кэша. По умолчанию устанавливает на 1 год.
var loadCacheData = cache({ expire: 10 * 1000 }, loadData);

3. Установка максимального размера кэша (сколько ответов хранить в кэше). По умолчанию 10.
var loadCacheData = cache({ max: 10 }, loadData);

4. Выбор способа хранения кэш. По умолчанию «app».
app - хранить кэш в памяти.
local - хранить кэш в localStorage и доступен между всеми страницами сайта.
var loadCacheData = cache({ storage: "local" }, loadData);
При установке «local» опционально можно установить «cacheKey» - имя ключа в localStorage где храниться кэш.

5. Установка собственного хранилища для кэша.
var loadCacheData = cache({ storage: new MyCacheStorage() }, loadData);
В этом случае MyCacheStorage() должен реализовывать три метода:
«get(key, fn);» - метод выбирает результаты из кэша по ключу.
«set(key, val, fn);» - метод устанавливает значение к кэш.
«clear(fn);» - метод сбрасывает кэш.
«fn» - функция обратного вызова, принимающая первым аргументом «ошибку», вторым «результат» (если он есть) выполнения функции.

Использование «cache-js» накладывает одно ограничение, функции, результат которых необходимо «закэшировать», должны подчиняться правилу: «Последний параметр должен быть функцией обратного вызова!».

  • Сейчас функция «cache» добавляется в глобальную область, планируется вынести в отдельную
  • Добавить кэш с использованием sessionStorage
  • Глобальные опции, например что бы полностью отключить кэш при разработке
  • Поддержка старых браузеров. В данный момент используются методы parse/stringify объекта JSON, getItem/setItem/removeItem объекта localStorage
  • !? Порт на nodejs (под вопросом)

Примеры с использованием доступны в

В HTML5 стало возможным создавать веб-приложения, которые будут работать даже без подключения к интернету.

Усовершенствованное кэширование страниц

Обратите внимание: IE10+, Chrome, Firefox, Opera и Safari имеют поддержку данной технологии.

HTML5 расширяет возможности браузерного кэширования. Теперь веб-страницы могут быть полностью доступны для пользователей даже без подключения к интернету.

Использование HTML5 кэширования дает следующие преимущества:

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

Пример использования HTML5 кэширования

...Содержимое документа...

Декларирование HTML5 кэширования

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

Если данный атрибут не был задан на веб-странице и ссылка на нее отсутствует в файле кэширования, страница не будет кэширована.

Файл кэширования может иметь любое расширение (например.appcache или.mf), но обязан иметь специальный MIME тип: "text/cache-manifest".

В некоторых случаях веб-серверу может потребоваться дополнительная настройка, чтобы обслуживать данный MIME тип. Например, чтобы настроить веб-сервер Apache необходимо добавить следующий код в.htaccess файл:

AddType text/cache-manifest .appcache

Содержимое файла кэширования

Файл кэширования является обычным текстовым файлом, который указывает браузеру какие файлы необходимо кэшировать.

Файл может содержать три секции:

  • CACHE MANIFEST - в данной секции указываются ссылки на файлы, которые необходимо кэшировать. Браузер будет автоматически кэшировать все перечисленные файлы сразу после первой загрузки.
  • NETWORK - в данной секции указываются файлы, которые требуют постоянного подключения к интернету. Браузер не будет кэшировать файлы перечисленные в данной секции.
  • FALLBACK - если файлы указанные в этой секции будут по какой-либо причине будут недоступны пользователи автоматически будут перенаправляться на другой указанный файл.

Секция CACHE MANIFEST обязательно должна присутствовать во всех файлах кэширования. Секции NETWORK и FALLBACK могут отсутствовать.

Пример файла кэширования:

CACHE MANIFEST #В данной секции перечислены файлы, которые будут кэшированы index.html flower.png NETWORK #Здесь перечислены файлы, которые требуют подключение к интернету login-page.php FALLBACK #Если mob.html недоступен пользователь будет перенаправлен на offline.html /mob.html /offline.html #Если какой-либо из HTML файлов недоступен пользователь будет перенаправлен на offline.html *.html /offline.html

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

Обратите внимание: некоторые браузеры могут иметь ограничение на размер кэшируемого содержимого на одном сайте.

Обновление кэшированных файлов

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

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

  • Очистить кэш в браузере пользователя
  • Обновить содержимое файла кэширования
  • Обновить кэш браузера программно (с помощью JavaScript)

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

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

Запрет кэширования страницы на HTML

Сделать это можно с помощью мета тегов. Сейчас мы разберем разные варианты запрета на кэширование.

Запрет на кэширование браузером и прокси-сервером

Запрет кэширования страницы, только браузером

Установка кэширования на определенное время, для браузера

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

Установка кэширования на определенное время, для прокси-сервера

Практически, то же самое, что и в предыдущем коде, только указание стоит конкретно для прокси-сервера.

Запретить кэширование страницы с помощью PHP

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

", date("H:i:s"), ""; ?>

Также, можно разрешать кэшировать на определенное время. Например, разрешим кэширование только на 1 час.

", date("H:i:s"), ""; ?>

Запретить кэширование страницы с помощью.htaccess

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

LoadModule expires_module modules/mod_expires.so LoadModule headers_module modules/mod_headers.so ... AddModule mod_expires.c AddModule mod_headers.c

Теперь в файле.htaccess, собственно запрещаем кэшировать выводимые данные. Как нам известно, .htaccess файл будет распространяться на директорию, в которой лежит, и на все субдиректории.

# Заголовок Cache-Control Header append Cache-Control "no-store, no-cache, must-revalidate" # Заголовок Expires ExpiresActive On ExpiresDefault "now"

Важно заметить, что полный запрет кэширования, повышает нагрузку на сервер. Поэтому, играйтесь с этим осторожно! А лучше, установите определенное время, на которое можно кэшировать документы. Например, установим кэширование на 1 час:

# Заголовок Cache-Control Header append Cache-Control "public" # Заголовок Expires ExpiresActive On ExpiresDefault "access plus 1 hours"

Заключение

  • htaccess кэширование сохраняет содержимое веб-страницы на локальном компьютере, когда пользователь посещает ее;
  • Использование кэша браузера – веб-мастер дает указания браузерам, как следует рассматривать ресурсы.

Когда браузер отображает веб-страницу, он должен загрузить логотип, CSS файл и другие ресурсы:

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

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

Как включить кэширование в браузере

  • Измените заголовки запроса ресурсов, чтобы использовать кэширование;
  • Оптимизируйте свою стратегию кэширования.

Изменение заголовков запроса

Для большинства людей единственный способ кэширования сайта htaccess заключается в том, чтобы добавить код в файл .htaccess на веб-сервере.

Файл .htaccess контролирует многие важные настройки для вашего сайта.

Кэширование браузера через файл.htaccess

Приведенный ниже код указывает браузеру, что именно кэшировать и как долго это «запоминать «. Его следует добавить в начало файла .htaccess :

## EXPIRES CACHING ## ExpiresActive On ExpiresByType image/jpg "access 1 year" ExpiresByType image/jpeg "access 1 year" ExpiresByType image/gif "access 1 year" ExpiresByType image/png "access 1 year" ExpiresByType text/css "access 1 month" ExpiresByType text/html "access 1 month" ExpiresByType application/pdf "access 1 month" ExpiresByType text/x-javascript "access 1 month" ExpiresByType application/x-shockwave-flash "access 1 month" ExpiresByType image/x-icon "access 1 year" ExpiresDefault "access 1 month" ## EXPIRES CACHING ##

Сохраните файл .htaccess , а затем обновите веб-страницу.

Как установить время кэширования для различных типов файлов

В приведенном выше коде заданы промежутки времени. Например, 1 year (1 год ) или 1 month (1 месяц ). Они связаны с типами файлов. Приведенный выше код устанавливает, что .jpg файлы (изображения ) следует кэшировать в течение года.

Если бы вы хотели изменить это, чтобы и JPG изображения кэшировались в течение месяца, то вы бы просто заменили «1 год » на «1 месяц «. Указанные выше значения кэширования через htaccess оптимальны для большинства веб-страниц.

Метод альтернативного кэширования для.htaccess

Описанный выше метод называется «Expires «, он помогает с кэшированием большинству новичков. После того, как вам станет проще работать с кэшированием, можете попробовать другой метод кэширования Cache-Control , который дает больше возможностей.

Возможно, что метод Expires не сработает на вашем сервере, в этом случае вы возможно захотите попробовать использовать Cache-Control .

Cache-Control

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

Пример использования в файле .htaccess :

# 1 Month for most static assets Header set Cache-Control "max-age=2592000, public"

Приведенный выше код устанавливает заголовок Cache-Control в зависимости от типа файла.

Как работает Cache-Control

Рассмотрим упомянутую выше строку кода кэширования в браузере htaccess :

# 1 Month for most static assets

Данная строка — просто примечание. Файл .htaccess игнорирует строки, начинающиеся с символа # . Это примечание рекомендуется, так как у вас может быть несколько различных наборов данных в качестве решения для кэширования файлов:

Упомянутая выше строка говорит, что, «если файл будет одним из этих типов, то мы сделаем что-то с ним… »

Самое важное в этой строке то, что в ней перечислены различные типы файлов (CSS , JS , JPEG , PNG и т.д. ) и что инструкции кэширования следует применять к этим типам файлов. Например, если вы не хотите, чтобы JPG файлы кэшировались в течение указанного периода времени, можете удалить «JPG «. Если вы хотите добавить HTML , то нужно в этой строке указать «HTML «:

Header set Cache-Control "max-age=2592000, public"

В упомянутой выше строке установлены фактические заголовки и значения:

  • Часть «Header set Cache-Control » — устанавливает заголовок;
  • Переменная «max-age=2592000 » – указывает, сколько времени займет процесс кэширования (в секундах ). В этом случае мы осуществляем кэширование в течение одного месяца (2592000 ) секунд;
  • Часть «public » сообщает о том, что это общедоступно.

Эта строка кэширования через htaccess закрывает оператор и заканчивает блок кода.

Общая проблема кэширования

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

Цифровой отпечаток URL

Получение нового (некэшируемого) файлового ресурса возможно при наличии уникального имени. Например, если файл CSS назван «main.css», то вместо этого мы могли бы назвать его «main_1.css». В следующий раз, когда мы поменяем его имя, мы можем назвать файл «main_2.css». Это полезно для файлов, которые периодически изменяются.



Статьи по теме