1. Кэш
Технология кэширования всегда былаWEBОн играет очень важную роль в технической системе и является средством быстрого и эффективного повышения производительности.
В процессе изучения кеширования раньше я его ни разу не практиковал, и некоторые понятия часто забываются.
Сегодня я в основном учусь на практике Node.кеш браузера, кстати для анализаKoaОбработка кэшированного исходного кода.
2. Кэш браузера
Во-первых, давайте посмотрим на процесс кэширования запросов браузера.
-
После выполнения запроса кеш сначала просматривается локально.
-
Обнаружил, что есть кеш, чтобы определить есть ли кешСвежий(независимо от того, истек ли срок).
-
Срок действия не ограничен, и он возвращается непосредственно клиенту.
-
Если срок действия кэша истекает, необходимо снова обратиться к серверу, чтобы запросить последний ресурс, вернуть его клиенту и повторно кэшировать.
3. Определение свежести
Многие студенты могут увидеть другой блог, в котором упоминаются «сильное кэширование / консультации по кэшированию» и другие фразы, я оставлю это после разговора. Рисунок вышеСвежийТермин относительно редкий и взят из The Definitive Guide to HTTP.
потому чтоHTTPРесурс кэшируется на определенный период времени, в течение которого кэш «свежий».
Итак, проверка того, истек ли срок действия кеша, называется,Обнаружение свежести.
Затем пройтиNodeДавайте попробуем и посмотрим:
- Как браузер кеширует?
- Как выполнить определение свежести?
В-четвертых, битва узлов
Вышеупомянутое кэширование в течение определенного периода времени, затем HTTP предоставляет общее поле заголовка (то есть поле, которое можно использовать как в сообщениях запроса, так и в ответных сообщениях) для управления временем кэширования.
1. Введение в Pragma/Expires
Pragma — это атрибут заголовка, определенный в стандарте HTTP/1.0 Эффект от включения Pragma в запрос такой же, как и от определения Cache-Control: no-cache в информации заголовка, но заголовок ответа HTTP четко не определяет это. атрибут, поэтому его нельзя использовать. Полностью заменяет заголовок Cache-control, определенный в HTTP/1.1. Прагмы обычно определяются для обратной совместимости с клиентами на основе HTTP/1.0.
Expiresвернет абсолютное время, если запрошенное времяExpiresДо указанного времени можно попасть в кеш. Однако, поскольку клиент может изменить локальное время, оно будет несовместимо со временем сервера, что чревато ошибками и не рекомендуется.
2. Введение в Cache-Control
Cache-ControlСейчас это распространенный метод кэширования, здесь много полей, упомянутых выше, новички могут просто посмотреть.max-age, во избежание путаницы, также является наиболее значимым атрибутом.
Cache-ControlОписывает относительное время. При попадании в кеш для оценки используется время клиента, поэтому сравнитеExpires,Cache-ControlУправление кешем стало более эффективным и безопасным.
3. Кэш-контроль реального боя
пройти черезKoaФреймворк, просто создайте егоNodeСлужить. и черезkoa-staticУправление статическими ресурсами.
Ссылка на структуру кода выглядит следующим образом:maxageнастройки кеша10Второй.
node index.js // server is starting at port 8001
koa-staticпрошел дальшеmaxage: 10 * 1000.
koa-staticВведен в исходный кодkoa-sendбиблиотека. усеченная частьkoa-sendИсходный код, до тех пор, пока входящийmaxage, он установитCache-Controlизmax-age. Чтобы соответствовать привычкам фронтенд-разработчиков, он передается в миллисекундах, что на самом деле в секундах.
NetWorkМожно заметить, что он был успешно установленCache-Control: max-age=10
Проверка доступа выглядит следующим образом:
-
Запросите снова в течение 10 секунд, вы можете видеть, что js/css исходит из кеша
memory cache. -
Через 10 секунд срок действия кеша истекает, если кеш не используется, он будет снова получен с сервера.
4. Почему HTML такой особенный?
4.1 Феномен
Из вышеприведенных экспериментов видно, чтоJs/CssКогда все уйдут в локальный кеш,HTMLвсе равно получается с сервера.
Cache-Control: max-age=0.Jsресурсов происходит то же самое. Поэтому делается вывод, что это добавлено браузером по умолчанию, это должно быть дляПоддерживайте актуальность запрашиваемых ресурсов.4.2 Причины
противrequestзапрос, если естьCache-Controlлимит, то кеш-система сначала проверитCache-Control. Если он не соответствует правилам, он напрямую запрашивает сервер. Конкретные правила заключаются в следующем:
Networkсерединаdisable-cacheТо же самое, когда делается запрос, значит нет необходимости лезть в кеш, и сервер должен быть самым последним.Сервер повторной аутентификации (обнаружение свежести)
любой из вышеперечисленныхhttp1.0еще1.1Решения хранятся в локальном кэше в течение определенного периода времени. По истечении этого срока вам нужно зайти на сервер и запросить его снова. это также называетсяСильный кеш.
но,Срок действия в кеше не означает изменения ресурсов сервера.
Поэтому запрос находит, что срок действия локального кеша истек. Вы можете обратиться к серверу. Этот ресурс еще свежий? Могу ли я все еще использовать его? Обычный подход заключается в переносе полейIf-Modified-Sinceа такжеIf-None-Match. Если убедиться, что ресурс свежий, ничего не изменилось. Для этого нужно только вернуть идентификатор, о чем мы часто говорим304, не нужно возвращать данные, ускорьте время запроса.
Этот процессОбнаружение свежести, то способ реализации этого кеша таков, как мы часто говоримСогласовать кеш.
Давайте взглянем на реальный кеш согласования Node.
6. Last-Modified и If-Modified-Since
нестиIf-Modified-SinceПредпосылка заключается в том, что кеш хранитLast-Modifiedполе.
Когда каждый запрос возвращается,responseМожет нести поля в полеLast-Modified, которая является последней датой изменения ресурса сервера.
If-Modified-Sinceнаходится в кэшеLast-Modifiedи сравните его со временем последней модификации ресурса сервера, чтобы узнать, свежий ли ресурс.
6.1 Проверка кода
Когда каждый запрос возвращается,responseможет нести поля вLast-Modified, потому что мы используемkoa-staticдобавится к нашему возвращаемому заголовку по умолчаниюLast-Modified.
If-Modified-Since.koa-conditional-get.
6.2 koa-conditional-get
koa-conditional-getЧто сделано, чтобы кеш согласования заработал.
Видно, что исходный код очень простой, и этого достаточно, чтобы судить о том, свежий ли он.
ctx.freshО том, как его рассчитать, будет сказано позже. Но явно провереноIf-Modified-Sinceа такжеLast-Modified.
6.3 Тест последней модификации
- Запрос в течение 10 секунд
- Запрос после истечения 10 секунд
Результат теста, в течение 10 сJs/CssБолее сильный кеш.HTMLТак как запрос добавлен по умолчаниюmax-ageЕсли он равен 0, перейдите в кеш согласования и верните 304, данные возвращать не нужно,SizeСнизился с 484B до 163B.
Js/CssПо истечении срока действия кеша все переходят в согласованный кеш, т.к.Last-ModifiedОн не изменился, все возвращают 304, возвращать данные не нужно,Sizeдо 163В.
После возврата 304 он будет сброшенmax-age, запрос не должен запрашивать сервер в течение 10 секунд, и это по-прежнему сильный кеш.
- Изменить содержимое JS
Jsрезультаты контент-тестирования,CssНикакая модификация по-прежнему не возвращает 304.JsМодификация приводит кLast-Modifiedбольше, чем в запросеIf-Modified-Since, ресурс недостаточно свежий, возвращает 200 и возвращает последние данные.
6.4 Резюме
Last-ModifiedРабочий процесс выглядит следующим образом:
В общем, без подгонки серверного времени и вмешательства в клиентские кэши эти дваheaderОчень надежно работать вместе для управления кешем согласования, но иногда ресурсы на сервере фактически меняются, но время последней модификации не меняется, и эту проблему нелегко обнаружить, и когда это происходит, когда это происходит, это повлияет на надежность кэша согласования. Значит есть еще параheaderДля управления кешем согласования эта пара заголовков имеет вид [ETag,If-None-Match】
7. ETag и If-None-Match
7.1 ETag
этоheaderЭто уникальный идентификатор, сгенерированный сервером в соответствии с текущим запрошенным ресурсом.Этот уникальный идентификатор представляет собой строку.Поскольку ресурс изменяется, строка отличается, поэтому ее можно хорошо дополнить.Last-ModifiedЭта проблема.
Чтобы не отвлекаться, вы можете комментироватьLast-modifiedлогика.
ETagПроверка также очень проста, просто добавьте промежуточное ПО.koa-etag, перезапустите сервисный тест.7.2 Практика ETag
обратиться с просьбой,responseимеютEtag:
If-None-Matchдля тайникаEtagстоимость:ИсправлятьJsРесурсный тест, результаты таковы:
JsПосле проверки ресурса, в результатеEtagИзменять. Сервер повторно проверяет, что ресурс не свежий.JsПовторное приобретение ресурсов, отдача 200.Cssбез модификации,EtagБез изменений возвращается 304.Etagобщий процесс иLast-Modifiedбыть последовательным.
7.3 Анализ исходного кода koa-etag
koaизetagСуществует два основных метода генерации, и вы можете непосредственно просмотреть исходный код для получения подробной информации.
(1) Генерируется в соответствии со временем модификации и размером файла.
function stattag (stat) {
var mtime = stat.mtime.getTime().toString(16)
var size = stat.size.toString(16)
return '"' + size + '-' + mtime + '"'
}
(2) использоватьcryptoгенерация библиотечного шифрования
function entitytag (entity) {
if (entity.length === 0) {
// fast-path empty
return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"'
}
// compute hash of entity
var hash = crypto
.createHash('sha1')
.update(entity, 'utf8')
.digest('base64')
.substring(0, 27)
// compute length of entity
var len = typeof entity === 'string'
? Buffer.byteLength(entity, 'utf8')
: entity.length
return '"' + len.toString(16) + '-' + hash + '"'
}
Пять, обнаружение свежести (интерпретация исходного кода Koa)
1. koa-conditional-get
видно впередиkoa-conditional-getКэш согласования может вступить в силу, поскольку возврат 304 обрабатывается для обеспечения актуальности ресурсов.
ctx.freshКак это обрабатывается?
2. koa
Вы можете увидеть Коа в запросеfreshМетоды, как показано ниже:
freshметод, чтобы определить, является ли запрошенный ресурс свежим.
3. Интерпретация исходного кода свежего метода
Сохраняйте только основной код, вы сами его видитеfreshисходный код.
var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/
function fresh (reqHeaders, resHeaders) {
// 1. 如果这2个字段,一个都没有,不需要校验
var modifiedSince = reqHeaders['if-modified-since']
var noneMatch = reqHeaders['if-none-match']
if (!modifiedSince && !noneMatch) {
console.log('not fresh')
return false
}
// 2. 给端对端测试用的,因为浏览器的Cache-Control: no-cache请求
// 是不会带if条件的 不会走到这个逻辑
var cacheControl = reqHeaders['cache-control']
if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) {
return false
}
// 3. 比较 etag和if-none-match
if (noneMatch && noneMatch !== '*') {
var etag = resHeaders['etag']
if (!etag) {
return false
}
// 部分代码
if (match === etag) {
return true;
}
}
// 4. 比较if-modified-since和last-modified
if (modifiedSince) {
var lastModified = resHeaders['last-modified']
var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince))
if (modifiedStale) {
return false
}
}
return true
}
freshЛогика оценки кода резюмируется следующим образом: выполняется одно из трех условий,freshдляtrue.
6. Резюме
Общий процесс кэша браузера выглядит следующим образом:
- После выполнения запроса кеш сначала просматривается локально.
- Нет кэша, чтобы перейти к серверу, чтобы запросить последние ресурсы, вернуться к клиенту (200) и повторно кэшировать.
- Если кеш найден, необходимо определить, не просрочен ли кеш локально (
max-ageЖдать). - Не просроченный, напрямую возвращен клиенту (200
from cache). - Если срок действия кеша истек, посмотрите, есть ли кеш согласования конфигурации (
etag/last-modified), перейдите на сервер, чтобы проверить, обновлен ли ресурс и можно ли продолжать использовать локальный кеш. - Если обнаружено, что ресурс доступен, верните 304, чтобы сообщить клиенту, что кеш можно продолжать использовать, и в соответствии с
max-ageДождитесь времени обновления кеша. Нет необходимости возвращать данные, что ускоряет время запроса. - Если повторная аутентификация на стороне сервера не удалась, он запрашивает последний ресурс, возвращает его клиенту (200) и повторно кэширует.
Сильный кеш, о котором мы часто говорим, на самом деле получается непосредственно из локального кеша, то естьCache-Control: max-ageи другая конфигурация, нет необходимости связываться с сервером.
Кэш согласования основан на надежном кеше.etag或last-modifiedи другие параметры. После того, как локальный кеш недействителен, перейдите на сервер для определения свежести. Это позволяет избежать возврата последних данных каждый раз, когда истекает срок действия локального кеша, что приводит к медленным запросам.
7. Ссылки
- Front-end оптимизация: введение в технологию кэширования браузера
- кеш браузера
- Книга "Полное руководство по HTTP"
Анализ исходного кода этой статьи вращается вокругkoa, не представляет другие сервисные платформы. Если вы не владеете этими знаниями, рекомендуется попрактиковаться. Не туда, приму критику и исправление~