Как понять, что сайт был загружен из кэша

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

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

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

Репозиторий с кодом демо

Посмотреть работу демо

Варианты того, как можно узнать

Какой критерий использовать для понимания того, что сайт был загружен из кэша?

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

Что будем загружать?

Конечно jQuery, кэш между разными демо будем сбрасывать с помощью query-параметра.

Как отладить и проверить работу решения?

Можно отключать кэш с помощью галочки «Disable cache» в DevTools и смотреть на колонку «Size» чтобы понять, была загрузка или нет.

DevTools и проверка кэша

DevTools и проверка кэша

Способ первый — поставить флаг при загрузке страницы

Самый простой способ — если пользователь зашел на сайт, записать в долгосрочное хранилище браузера флаг, который можно будет извлечь при повторной загрузке и проверить, повторная это загрузка или нет. В качестве хранилища здесь и далее будет использоваться Web Storage API.


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

Способ второй — вычислить скорость загрузки скрипта

Тоже просто — сохраняем время перед стартом загрузки скрипта, затем после и вычисляем разницу, если она оказалась мала — значит, взяли из кэша.



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

Способ третий — загрузить скрипт вручную

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


Надежный способ, но смущает кастомная загрузка скриптов. Так же, Safari почему-то не берет из кэша без параметра cache: 'force-cache'.

Способ четвертый — использовать Perfomance API

Способ, который является самым надежным — использование параметра transferSize. Если ваши скрипты находятся на другом домене (так часто бывает при использовании CDN), ответ с кодом скрипта должен иметь заголовок Timing-Allow-Origin — иначе браузер будет всегда возвращать 0. Следующая проблема — Safari всегда отдает 0 при загрузке скриптов с другого домена, даже с заголовком. Для этого приходится делать фоллбэк на способ 2, если браузер не отдал значение transferSize.


Параметр transferSize создан специально для того, чтобы понимать, был ли скрипт загружен из кэша.

Заключение

Я остановился на четвертом способе — он выглядит самым надежным и относительно простым.

Какие способы знаете вы? Будет забавно, если есть решение без минусов перечисленных способов и я просто не смог до него добраться.

© Habrahabr.ru