предисловие
- Страница получает все необходимые статические ресурсы с максимальной скоростью, а рендеринг быстрый;
- Когда статические ресурсы на сервере не обновляются, снова получить доступ к серверу, не запрашивая сервер;
- Когда статические ресурсы на сервере обновляются, запрашиваются последние ресурсы сервера, и загрузка происходит быстро.
- Статическая скорость загрузки ресурсов
- скорость рендеринга страницы
Во-первых, используйте картинку, чтобы обобщить то, что будет рассмотрено в этой статье.
Общие типы кеша
1. Кэш браузера
Доступно на w3cофициальная документацияСм. определения всех полей заголовка HTTP-ответа в , а поля, связанные с кешем, в основном обведены кружком на рисунке выше:
- общедоступный: ответы кэшируются и распределяются между несколькими пользователями.
- private: значение по умолчанию, ответ может использоваться только как частный кеш (например, в браузере) и не может быть разделен между пользователями;
- no-cache: ответ не будет кэшироваться, а будет запрашивать ресурсы с сервера в режиме реального времени.
- max-age: значение в секундах, количество секунд между временем запроса и временем истечения срока действия. Относительный временной интервал на основе времени запроса (поле Дата), а не абсолютное время истечения срока действия;
- Прагма: Существует только одна обычая прагма: NO-кэш, который точно такой же, как Cache-Control: NO-кэш. (Cache-Control: No-Cache предоставляется HTTP 1.1, поэтому Pragma: No-Cache может применить NO-CACE на http 1.0 и http 1.1.)
- Истекает: указывает, сколько времени осталось до истечения срока действия страницы, кэшированной и сохраненной в браузере, что эквивалентно эффекту max-age в Cache-control.Если он существует в то же время, он будет перезаписан max-age Кэш-Контроля. Если его значение равно 0, это означает, что срок действия страницы истекает немедленно. И если это свойство установлено несколько раз на странице, берите минимальное значение.
- Дата: конкретное время и дата создания сообщения;
- Last-Modified/If-Modified-Since: время последней модификации локального файла на сервере. По истечении срока действия кеша на сервер отправляется время последней модификации кэшированной страницы на стороне браузера. Сервер сравнивает это время со временем последней модификации фактического файла на сервере. Если время совпадает, то вернуть 304, и клиент будет напрямую использовать локальный кеш.
- Etag/If-None-Match: (EntityTags) — это тег URL-адреса, который используется для указания того, изменился ли объект URL-адреса, как правило, хеш-значение сущности ресурса. Подобно Last-Modified, если сервер проверяет, что ETag ресурса не изменился (ресурс не был обновлен), он вернет статус 304, указывающий клиенту использовать локально кэшированный файл. Etag имеет более высокий приоритет, чем Last-Modified, и Etag в основном предназначен для решения некоторых проблем, которые не может решить Last-Modified.
- Файл может периодически меняться, но его содержимое не меняется, и клиент не хочет получать его снова;
- If-Modified-Since размер частиц, чтобы иметь возможность проверить уровень s;
- Некоторые серверы не могут получить точное время последней модификации файла.
- If-Modified-Since: значение Last-Modified в предыдущем ответе;
- If-None-Match: значением является Etag в предыдущем ответе (если он существует);
- Cache-Control
- Pragma
- Expires
<meta http-equiv="Cache-Control" content="no-cache" /> <!-- HTTP 1.1 -->
<meta http-equiv="Pragma" content="no-cache" /> <!-- 兼容HTTP1.0 -->
<meta http-equiv="Expires" content="0" /> <!-- 资源到期时间设为0 -->
Putting caching instructions into meta tags is not a good idea, because although browsers may read them, proxies won't. For that reason, they are invalid and you should send caching instructions as real HTTP headers.
2. Кэш приложения HTML5
а. Добавить файл манифеста
- Первая строка файла должна быть CACHE MANIFEST
- Строки, начинающиеся с #, используются в качестве комментариев.
- Кэш сайта не может превышать 5M
- Путь к файловому ресурсу может использовать абсолютный или относительный путь.
- Любой сбой кеша в списке файлов сделает недействительным весь кеш.
- Вы можете использовать один и тот же файл minifest для своего сайта или по одному на страницу.
- КЭШ: файл ресурсов, который необходимо кэшировать, браузер автоматически кэширует html-страницу с атрибутом манифеста;
- СЕТЬ: для файлов, которые не нужно кэшировать, можно использовать подстановочные знаки;
- FALLBACK: невозможно получить доступ к альтернативному файлу для кэшированного файла, можно использовать подстановочные знаки.
б. Конфигурация сервера
AddType text/cache-manifest .appcache
в. Ссылки в html
<html lang="zh" manifest="main.manifest">
1. События
- cached/checking/downloading/error/noupdate/obsolete/progress/updateready
2. Процесс исполнения
- Создание кэша приложений с манифестом (доступ к html-файлам с атрибутами манифеста, хранение файлов манифеста, загрузка html-файлов и других файлов ресурсов);
- Событие Application Cache Checking (проверка списка файлов, подлежащих кэшированию)
- Событие загрузки кеша приложения (начало загрузки файлов кеша)
- Событие Application Cache Progress (0 из 4) (загрузка файлов кеша последовательно)
- ...
- Application Cache Progress event (4 of 4)
- Событие Application Cache Cached (файл кэшируется)
- Документ был загружен из кэша приложения с манифестом (файлы html и другие файлы статических ресурсов были прочитаны из кэша для отображения страницы)
- Событие проверки кэша приложений (получение нового файла манифеста, проверка обновлений)
- Да: повторно загрузить кешированный файл для следующего посещения (это не повлияет на содержимое, отображаемое текущим браузером).
- Событие загрузки кеша приложения (начало загрузки файлов кеша)
- Событие Application Cache Progress (0 из 4) (загрузка файлов кеша последовательно)
- ...
- Application Cache Progress event (4 of 4)
- Cache Cheche UpdateAbready Event (обновление файла кэша завершено)
- нет
- Событие NoUpdate кэша приложений (ничего не делать)
- Документ был загружен из кэша приложения с манифестом (файлы html и другие файлы статических ресурсов были прочитаны из кэша для отображения страницы)
- Событие проверки кэша приложений (получение нового файла манифеста, проверка обновлений)
- Событие Application Cache Obsolete (удалить все файлы в локальном кеше, больше не использовать кеш)
- Кэш приложения будет кэшировать HTML-документы, ссылающиеся на файлы манифеста по умолчанию, что является ямой для динамически обновляемых HTML-страниц (вы можете использовать хитрый метод встраивания iframe, чтобы избежать этого);
- Пока один ресурс в списке кеша не загружается, все файлы не будут кэшироваться;
- Если ресурс не кэширован и не задана NETWORK, он не будет загружен, поэтому в сети необходимо использовать подстановочные знаки;
- После обновления кеша в первый раз можно загрузить только файл манифеста, а другие статические ресурсы необходимо загрузить во второй раз, чтобы увидеть последний эффект;
- Файлы в списке кэшированных файлов сами по себе не будут повторно кэшироваться при обновлении браузера, так как же сообщить браузеру, что кэш необходимо обновить?
- Обновите файл манифеста: измените номер версии или дату комментария.
- Проверяйте наличие обновлений через интерфейс, предоставляемый кэшем приложений (window.applicationCache.swapCache).
Эта функция была удалена из веб-стандартов, хотя некоторые браузеры все еще поддерживают ее в настоящее время, но могут перестать поддерживать ее в будущем, пожалуйста, постарайтесь не использовать эту функцию. В настоящее время крайне не рекомендуется использовать описанную здесь функцию кэширования приложений, поскольку она находится в процессе удаления с веб-платформы. Пожалуйста, используйте вместо этогоService Workersзаменять.
3. PWA (сервисный работник)
Service worker is a programmable network proxy, allowing you to control how network requests from your page are handled.
- Не могу получить доступ к доме
- Невозможно использовать синхронный API
- Требуется протокол HTTPS (также доступен http://localhost или http://127.0.0.1)
Простой в использовании
<script>
navigator.serviceWorker
.register('./sw.js')
.then(function (registration) {
// 注册成功
});
</script>
self.addEventListener('install', function(event) {
/* 安装后... */
// cache.addAll:把缓存文件加进来,如a.css,b.js
});
self.addEventListener('activate', function(event) {
/* 激活后... */
// caches.delete :更新缓存文件
});
self.addEventListener('fetch', function(event) {
/* 请求资源后... */
// cache.put 拦截请求直接返回缓存数据
});
Файл index.html ссылается на static/js/main.js, а service-worker.js зарегистрирован в main.js. В service-worker.js мы видим две переменные: precacheConfig (список кеша) и cacheName (номер версии). Отключив сеть, мы видим, что файлы в списке precacheConfig все еще могут загружаться локально.
механизм обновления
4. Локальное хранилище
5. Кэш CDN
механизм обновления
prebrowsing
Предварительная загрузка — это подсказка браузера к ресурсам, которые могут быть использованы в будущем, некоторые ресурсы могут использоваться на текущей странице, а некоторые — на некоторых будущих страницах. Как разработчики, мы знаем наше приложение лучше, чем браузер, поэтому мы можем использовать эту технологию для наших основных ресурсов.
- dns-prefetch: предварительное разрешение DNS, которое сообщает браузеру, что мы можем получить ресурсы с определенного URL-адреса в будущем, и когда браузер фактически использует ресурс в домене, разрешение DNS может быть завершено как можно скорее. В основном используется при использовании сторонних ресурсов.
- предварительное подключение: предварительное подключение, завершение предварительного разрешения DNS, а также выполнение установления связи TCP и установка протокола транспортного уровня.
- prerender: предварительная визуализация, предварительная загрузка всех ресурсов документа, аналогичная открытию ссылки в скрытой вкладке — загрузит все ресурсы, создаст структуру DOM, завершит макет страницы, применит стили CSS, выполнит скрипты JavaScript, и т.п.
- prefetch: Prefetch, ресурс, объявленный с помощью prefetch, является подсказкой для браузера, предполагающей, что ресурс может использоваться в «будущем», и подходит для кэширования ресурсов для других страниц маршрутизации, на которые можно перейти. Время загрузки предварительно выбранных ресурсов определяется браузером, обычно приоритет низкий, и загрузка будет выполняться, когда браузер «простаивает».
- preload: Предварительная загрузка, активное уведомление браузера о получении ключевых ресурсов этой страницы, просто предварительная загрузка и не будет выполняться после загрузки ресурсов;
prefetch & preload
совместимость
приоритет
Примечание: предварительный просмотр прост в использовании, но не используйте его без разбора, если только вы не уверены, что будете загружать файлы, которые хотите предварительно просмотреть, иначе это увеличит нагрузку на браузер и приведет к обратным результатам.
заявление
<Link prefetch href='/'><a>Home</a></Link>
<Link prefetch href='/features'> <a>Features</a></Link>
{ /* we imperatively prefetch on hover */ }
<Link href='/about'>
<a onMouseEnter={() => { Router.prefetch('/about'); console.log('prefetching /about!') }}>About</a>
</Link>
<Link href='/contact'><a>Contact (<small>NO-PREFETCHING</small>)</a> </Link>
попытка оптимизации
1. HTML-файл
2. файлы js/css/img
Управление версиями теперь обычно выполняется по имени файла. Именование упаковки Webpack может генерировать хеш-значение имени файла в соответствии с содержимым файла, и хэш-значение повторно создается только при изменении содержимого для каждой упаковки. В этом случае вы можете установить большее время кеша в HTTP-заголовках, например, max-age=2592000, чтобы избежать 304 запросов и как можно больше запрашивать подключения к серверу.
// js
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js'),
}
// css
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css'),
}),
3. веб-шрифт
- Браузер загрузит файл веб-шрифтов только тогда, когда найдет @font-face в селекторе CSS DOMNode.В это время браузер загрузил файл html/css/js;
- Если вы скажете браузеру загрузить файл шрифта до того, как браузер обнаружит, что ему нужно загрузить файл шрифта, это ускорит загрузку файла и скорость загрузки страницы.
- React + + Mobx + Webpack
- Одностраничный React-Router/динамическая загрузка пакета-загрузчика/использование больших файлов веб-шрифтов
- Выполните описанную выше настройку кэша заголовков HTTP для файлов статических ресурсов;
- Все статические файлы ресурсов кэшируются и загружаются в автономном режиме через Service Worker, и демонстрация не будет повторяться, как указано выше;
динамически загружаемый js
- index.ef15ea073fbcadd2d690.js
- static/js/0.1280b2229fe8e5582ec5.js
- static/js/1.f3077ec7560cd38684db.js
- static/js/2.39ecea8ad91ddda09dd0.js
- static/js/3.d7ecc3abc72a136e8dc1.js
webpackConfig.plugins.push(new PreloadWebpackPlugin({
rel: 'prefetch',
}));
Атрибут rel также может выбирать режим предварительной загрузки/предварительной выборки. Он упакован так:
При посещении страницы видно, что, не влияя на загрузку dom, браузер предварительно загружает несколько других js, которые будут использоваться позже, а при переходе на соответствующий маршрут он также будет напрямую загружаться из кеша, а не запрашивать ресурсы из кеша. сервер. .
css-файл
CSS в маршруте динамической загрузки разделен не отдельно, а в js маршрута, поэтому его можно оптимизировать только с помощью js.
файл веб-шрифта
2. Используйте плагины
- Установить плагин
npm install fontpreload-webpack-plugin --save-dev
- Добавьте после плагина HtmlWebpackPlugin в конфигурационный файл webpack:
const FontPreloadWebpackPlugin = require('fontpreload-webpack-plugin');
webpackConfig.plugins.push(new FontPreloadWebpackPlugin({
rel: 'prefetch',
fontNameList: ['fontawesome-webfont'],
crossorigin: true,
}));
3, упакованный эффект