В целом кэширование может повысить производительность за счет хранения данных, чтобы будущие запросы на те же данные обслуживались быстрее. Например, кэшированный ресурс из сети может избежать кругового пути к серверу. Кэшированный вычислительный результат может исключить время для выполнения того же вычисления.
В Chrome механизм кэширования используется различными способами, и HTTP-кеширование является одним из примеров.
Как в настоящее время работает HTTP-кэш Chrome
Начиная с версии 85, Chrome кэширует ресурсы, полученные из сети, используя соответствующие URL-адреса ресурсов в качестве ключа кэша. (Ключ кэша используется для идентификации кэшированного ресурса.)
Следующий пример иллюстрирует, как одно изображение кэшируется и обрабатывается в трех различных контекстах:

https://x.example/doge.png
} Пользователь посещает страницу ( https://a.example
), которая запрашивает изображение ( https://x.example/doge.png
). Изображение запрашивается из сети и кэшируется с использованием https://x.example/doge.png
в качестве ключа.

https://x.example/doge.png
} Тот же пользователь посещает другую страницу ( https://b.example
), которая запрашивает то же изображение ( https://x.example/doge.png
). Браузер проверяет свой HTTP-кэш, чтобы узнать, есть ли у него уже кэшированный ресурс, используя URL-адрес изображения в качестве ключа. Браузер находит совпадение в своем кэше, поэтому он использует кэшированную версию ресурса.

https://x.example/doge.png
} Неважно, загружено ли изображение из iframe. Если пользователь посещает другой веб-сайт ( https://c.example
) с iframe ( https://d.example
) и iframe запрашивает то же изображение ( https://x.example/doge.png
), браузер все равно может загрузить изображение из своего кэша, поскольку ключ кэша одинаков для всех страниц.
Этот механизм хорошо работает с точки зрения производительности уже долгое время. Однако время, которое требуется веб-сайту для ответа на HTTP-запросы, может показать, что браузер обращался к тому же ресурсу в прошлом, что делает браузер уязвимым для атак на безопасность и конфиденциальность, например:
- Определите, посещал ли пользователь определенный сайт : злоумышленник может определить историю просмотров пользователя, проверив, есть ли в кэше ресурс, который может быть специфичен для определенного сайта или группы сайтов.
- Атака с использованием межсайтового поиска : злоумышленник может определить, содержится ли произвольная строка в результатах поиска пользователя, проверив, находится ли в кэше браузера изображение «Нет результатов поиска», используемое определенным веб-сайтом.
- Межсайтовое отслеживание : кэш может использоваться для хранения идентификаторов, подобных файлам cookie, в качестве механизма межсайтового отслеживания.
Чтобы снизить эти риски, Chrome, начиная с версии Chrome 86, разделяет свой HTTP-кэш.
Как разбиение кэша повлияет на HTTP-кеш Chrome?
При разделении кэша кэшированные ресурсы будут зашифрованы с использованием нового «ключа сетевой изоляции» в дополнение к URL-адресу ресурса. Ключ сетевой изоляции состоит из сайта верхнего уровня и сайта текущего кадра.
Еще раз взгляните на предыдущий пример, чтобы увидеть, как работает разбиение кэша в различных контекстах:

https://a.example
, https://a.example
, https://x.example/doge.png
} Пользователь посещает страницу ( https://a.example
), которая запрашивает изображение ( https://x.example/doge.png
). В этом случае изображение запрашивается из сети и кэшируется с использованием кортежа, состоящего из https://a.example
(сайт верхнего уровня), https://a.example
(сайт текущего кадра) и https://x.example/doge.png
(URL ресурса) в качестве ключа. (Обратите внимание, что когда запрос ресурса поступает из фрейма верхнего уровня, сайт верхнего уровня и сайт текущего кадра в ключе сетевой изоляции совпадают.)

https://b.example
, https://b.example
, https://x.example/doge.png
} Тот же пользователь посещает другую страницу ( https://b.example
), которая запрашивает то же изображение ( https://x.example/doge.png
). Хотя то же изображение было загружено в предыдущем примере, поскольку ключ не совпадает, это не будет кэш-попаданием.
Изображение запрашивается из сети и кэшируется с использованием кортежа, состоящего из https://b.example
, https://b.example
и https://x.example/doge.png
в качестве ключа.

https://a.example
, https://a.example
, https://x.example/doge.png
} Теперь пользователь возвращается на https://a.example
, но на этот раз изображение ( https://x.example/doge.png
) встроено в iframe. В этом случае ключом является кортеж, содержащий https://a.example
, https://a.example
и https://x.example/doge.png
, и происходит попадание в кэш. (Обратите внимание, что когда сайт верхнего уровня и iframe являются одним и тем же сайтом, можно использовать ресурс, кэшированный с фреймом верхнего уровня.

https://a.example
, https://c.example
, https://x.example/doge.png
} Пользователь вернулся на https://a.example
, но на этот раз изображение размещено в iframe с https://c.example
.
В этом случае изображение загружается из сети, поскольку в кэше нет ресурса, соответствующего ключу, состоящему из https://a.example
, https://c.example
и https://x.example/doge.png
.

https://a.example
, https://c.example
, https://x.example/doge.png
} Что делать, если домен содержит поддомен или номер порта? Пользователь посещает https://subdomain.a.example
, который встраивает iframe ( https://c.example:8080
), который запрашивает изображение.
Поскольку ключ создан на основе "scheme://eTLD+1", поддомены и номера портов игнорируются. Следовательно, происходит попадание в кэш.

https://a.example
, https://c.example
, https://x.example/doge.png
} Что делать, если iframe вложен несколько раз? Пользователь посещает https://a.example
, который встраивает iframe ( https://b.example
), который встраивает еще один iframe ( https://c.example
), который в конечном итоге запрашивает изображение.
Поскольку ключ берется из верхнего фрейма ( https://a.example
) и непосредственного фрейма, который загружает ресурс ( https://c.example
), происходит попадание в кэш.
Часто задаваемые вопросы
Включено ли это уже в моем Chrome? Как я могу проверить?
Функция будет развернута до конца 2020 года. Чтобы проверить, поддерживает ли ее ваш экземпляр Chrome:
- Откройте
chrome://net-export/
и нажмите «Начать запись на диск» . - Укажите, где на вашем компьютере сохранить файл журнала.
- Полистайте веб-страницы в Chrome в течение минуты.
- Вернитесь на
chrome://net-export/
и нажмите «Остановить ведение журнала» . - Перейдите по ссылке
https://netlog-viewer.appspot.com/#import
. - Нажмите «Выбрать файл» и передайте сохраненный вами файл журнала.
Вы увидите вывод файла журнала.
На той же странице найдите SplitCacheByNetworkIsolationKey
. Если за ним следует Experiment_[****]
, то HTTP-разделение кэша включено в вашем Chrome. Если за ним следует Control_[****]
или Default_[****]
, то оно не включено.
Как протестировать разбиение HTTP-кэша на Chrome?
Чтобы протестировать разделение HTTP-кэша на Chrome, вам нужно запустить Chrome с флагом командной строки: --enable-features=SplitCacheByNetworkIsolationKey
. Следуйте инструкциям в разделе Запуск Chromium с флагами , чтобы узнать, как запустить Chrome с флагом командной строки на вашей платформе.
Должен ли я как веб-разработчик предпринять какие-либо действия в ответ на это изменение?
Это не критическое изменение, но оно может повлиять на производительность некоторых веб-сервисов.
Например, те, кто обслуживает большие объемы высококэшируемых ресурсов на многих сайтах (таких как шрифты и популярные скрипты), могут заметить рост своего трафика. Кроме того, те, кто потребляет такие услуги, могут иметь повышенную зависимость от них.
(Существует предложение о включении общих библиотек с сохранением конфиденциальности, называемое Web Shared Libraries ( видеопрезентация ), но оно все еще находится на рассмотрении.)
Каковы последствия этого изменения поведения?
Общий показатель промахов кэша увеличивается примерно на 3,6%, изменения FCP (First Contentful Paint) незначительны (~0,3%), а общая доля байтов, загружаемых из сети, увеличивается примерно на 4%. Подробнее о влиянии на производительность можно узнать в пояснении кеширования HTTP .
Это стандартизировано? Другие браузеры ведут себя по-другому?
«Разделы кэша HTTP» стандартизированы в спецификации fetch, хотя браузеры ведут себя по-разному:
- Chrome : использует схему верхнего уровня://eTLD+1 и схему фрейма://eTLD+1
- Safari : использует верхний уровень eTLD+1
- Firefox : Планируется реализовать схему верхнего уровня:://eTLD+1 и рассмотреть возможность включения второго ключа, как в Chrome.
Как обрабатывается прием от рабочих?
Выделенные рабочие используют тот же ключ, что и их текущий фрейм. Работники служб и общие рабочие сложнее, поскольку они могут быть общими для нескольких сайтов верхнего уровня. Решение для них в настоящее время обсуждается.