Лучшие практики для развертывания проектов vue

Vue.js

предисловие

использоватьvue,react,angularВ процессе развития технологии мы столкнемся со следующими проблемами:

  1. Медленная загрузка на сгиб
  2. Каждое обновление должно очищать кеш браузера, чтобы увидеть эффект (часто жалуются тесты)

Эти две проблемы можно оптимизировать разными способами, и сегодня я оптимизирую эти две проблемы на этапе развертывания страницы интерфейса. PS: все нижеследующее основано наvue-cli3+.

Схема кэширования файла внешней страницы

отvue-cli3начать собираться

Маршрутизация использует загрузку по запросуПосле упаковки сгенерированных файлов каждая страница маршрутизации соответствуетjsа такжеcssфайл, записьmain.jsи его зависимости упакованы какapp.jsа такжеapp.css, размещаются публичные зависимостиchunk-vendors.js.

vue-cli3упакованныйdist/jsпапка:

Как видите, пакет сгенерированjs/css/imgи так далее, имена файлов имеютhashЗначение, при изменении содержимого исходного файла соответствующий файл после переупаковкиhashЗначение также изменится. Например, мы модифицировалиabout.vueсерединаjs, при переупаковкеabout.jsизhashзначение будет меняться и зависит отabout.vueдокументapp.jsизhashТакже изменится значение и других немодифицированных файлов, запакованныхhashНи одно значение не изменится.

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

vue-cli3Полоса имени файла, сгенерированная упаковкойhashРоль стоимости

Для лучшего опыта с кэшированием

Кратко рассмотримhttpкешированные знания (Обратитесь к MDN):

  1. HTTP1.0черезExpires(время истечения срока действия файла) иLast-Modified(Время последнего изменения), чтобы сообщить браузеру о кэшировании, эти два поляUTCвремя (абсолютное время).ExpiresКонтроль срока действия нестабилен, потому что браузер может по своему желанию изменять локальное время, что приводит к неточному использованию кеша. а такжеLast-ModifiedВремя истечения может быть с точностью до секунды.
  2. HTTP1.1пройти черезCache-Contorlа такжеEtag(номер версии) для управления кешем. Сначала проверьте браузерCache-Control, если есть, тоCache-Controlпреобладать, игнорироватьExpires. если нетCache-Control, затем сExpiresпреобладать.

Cache-Controlкроме того, что вы можете установитьmax-age(относительное время истечения в секундах), вы также можете установить следующие общие значения:

  • public, ресурсы могут кэшироваться промежуточными серверами. Когда браузер запрашивает сервер, если время кэширования не истекло, промежуточный сервер напрямую возвращает содержимое браузеру, не запрашивая исходный сервер.
  • private, ресурс не может кэшироваться промежуточными прокси-серверами. Когда браузер запрашивает сервер, промежуточный сервер должен прозрачно передать запрос браузера на сервер.
  • no-cache, независимо от того, истек ли срок действия локальной копии, каждый раз при доступе к ресурсу браузер должен спрашивать сервер.Если файл не изменился, сервер просто говорит браузеру продолжать использовать кеш (304).
  • no-store, ни браузеры, ни промежуточные прокси-серверы не могут кэшировать ресурсы. При каждом доступе к ресурсу браузер должен запрашивать сервер, и сервер не проверяет, изменился ли файл, а напрямую возвращает полный ресурс.
  • must-revalidate, до истечения срока действия локальной копии вы можете использовать локальную копию; после истечения срока действия локальной копии вы должны перейти на исходный сервер для проверки достоверности.
  • proxy-revalidate, который требует от прокси-сервера подтверждения с исходным сервером для кэшированного ресурса.
  • s-maxage: максимальное количество времени, в течение которого сервер кэширования будет кэшировать ресурс.

99% браузеров теперьHTTP1.1и выше, мы настраиваем кеш для использованияCache-Contorlа такжеEtagПросто сотрудничайте.

Затем возникает проблема, проверьте, актуален ли файл или нет.etag, почему имя файла по-прежнему должно иметьhashстоимость?

(1) Если имя файла не содержитhashзначение, требуется версия файлаetagЧтобы отметить, браузер должен сначала проверить, не истек ли срок его действия, а сервер должен проверить, является ли файл актуальным.

(2) в то время как имя файлаhashзначение, вы можете напрямую установить время истечения файла на 1 год, и браузер будет использовать его напрямую, не проверяя, истек ли срок его действия.

Причина в том, что если исходный файл страницы изменен, сгенерированныйjs/cssизhashЗначение будет изменено, соответствующий запросjs/cssАдрес тоже изменитсяhtppЕсли адрес изменен, нет необходимости проверять, не истек ли срок его действия. неизмененный файлhashостается неизменным, и можно использовать файл кэша.

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

Достижение неосознанного освобождения

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

При условии, что обновляется только начальная страница, имя файла содержитhashзначение также может быть достигнутоРаспространение без ведома пользователя: При обновлении системы нужно только удалить упакованные файлыindex.htmlфайлы кроме (js/css/img), все загружаемые в каталог веб-сайта сервера, неизмененные файлы (то есть файлы с одинаковыми именами) пропускаются напрямую.hashЕсли значение отличается, оно будет загружено.После загрузки мы загрузимindex.htmlПросто перезапишите старую версию. За это время пользователь запросил более старую версиюindex.htmlНикакого эффекта (файл 404 не появится, потому что старая и новая версииjs/cssоба существуют), в то время как новый посещающий пользователь запрашивает новую версиюindex.html, пользователи, которые посещают старое обновление страницы, также будут запрашивать новую версию файла, и это не влияет на кеш, то есть 0 влияет на пользователя. Через некоторое время нам нужно только сравнить и удалить старые файлы в соответствии со временем создания файла. PS: Замена файлов интерфейса не требует перезагрузки сервера.

Суммировать:Любое имя файла сhashзначение файла может быть установлено на «постоянный кеш» (один год), другое безhashиспользование файлаetagустановить кеш,NginxОпределите, не истек ли срок его действия.

Оптимизация результатов упаковки

При развертывании страницы возникает проблема, как отличить, имеет ли имя файлаhashстоимость? Обычное сопоставление, очевидно, не является хорошим способом. На самом деле метод очень прост, все файлы, созданные при упаковке, содержатhashзначение, в то время какpublicФайлы в каталоге не будут упакованы. Так что просто поставьpublicВ дополнение к файлам в каталогеindex.htmlсложить все в одинstaticКаталог (обратите внимание на путь импорта)

Тогда каталог упакованных файлов станет таким:

staticфайлы в каталоге иindex.htmlИмя файла безhashзначение, другие файлы сhashстоило того

Дополнение: После упаковки обнаружилось, что некоторые файлы подкачки очень маленькие, всего несколько К

Как показано на рисунке ниже, несмотря на то, что он загружается по запросу, это похоже на пустую трату запросов к серверу.

На этом этапе мы можем настроитьwebpackспециальные аннотации (требуетсяWebpack> 2.4), упакуйте некоторые маршруты по требованию в один и тот жеjsдокумент

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')

Здесь следует отметить, что хотя каждый файл упакован отдельно, он1k,но1k+1kне равно2k, то есть упакованный объем будет больше исходного, 4 шт.1kФайлы упакованы вместе, а объем примерно10k, громкость достигает10k, просто триггерыgzipсжатый, объем после сжатия4kвокруг, так что это не имеет значения.

Кэш конфигурации сервера

Теперь, когда у нас есть теоретические знания, давайте сделаем это на практике: имя файла сhashиз (т.е.css,js,fontа такжеimgДля всех файлов в каталоге) установлен месячный кеш, браузер может использовать кеш напрямую, не запрашивая сервер. другие документы (index.htmlа такжеstaticкаталог) установлен наno-cache, то есть каждый раз, когда вы заходите на сервер, чтобы проверить, актуален ли он.

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

без глупостей,NginxВозьмем для примера сервер, конфигурация такая (файл конфигурацииnginx.confизhttpмодуль):

server {
  location = /index.html {
     add_header Cache-Control no-cache;
  }

  location ~ /static/ {
     add_header Cache-Control no-cache;
  }

  location ~ /(js/*|css/*|img/*|font/*) {
      expires 30d;
      add_header Cache-Control public;
   }
}

Эффект следующий: когда мы модифицируемindex.htmlсодержание, оно будет повторно запрошено, и оно будет повторно запрошено без изменений304, с именем файлаhashВсе читаются непосредственно из локального кеша.

Следует отметить два момента:

  1. Не использовать в проектеservice-worker, что повлияет на наши настройки кеша, браузер будет иметь приоритетservice-workerкеш.vue-cli4изpwaШаблон, созданный плагином, поставляется сservice-worker

  1. Не забудьте разрешить кэширование при отладке

Настройки внешнего файлаgzipкомпрессия

webpackГенерация конфигурацииgzipсжатый файл

webpackСуществует плагин для сжатия файлов, который может сжимать большие файлы вgzipформат. Он также очень прост в использовании, сначала установите:npm install --save-dev compression-webpack-plugin,

затем изменитьwebpackконфигурация (vue.config.js):

const CompressionWebpackPlugin = require("compression-webpack-plugin");
// 可加入需要的其他文件类型,比如json
// 图片不要压缩,体积会比原来还大
const productionGzipExtensions = ["js", "css"];

module.exports = {
  configureWebpack: config => {
    if (process.env.NODE_ENV === "production"){
      return {
        plugins: [
          new CompressionWebpackPlugin({
            // filename: '[path].gz[query]',
            algorithm: "gzip",
            test: new RegExp("\\.(" + productionGzipExtensions.join("|") + ")$"),
            threshold: 10240, //对超过10k的数据进行压缩
            minRatio: 0.6 // 压缩比例,值为0 ~ 1
          })
        ]
      };
    }
  }
};

упакованныйjs/cssфайл, будет еще один соответствующийgzipфайл, вам нужно настроить его при развертывании, включитьgzip, который поддерживаетgzipСжатые браузеры запрашивают сжатые файлы, а неподдерживаемые браузеры запрашивают исходные файлы.gzipРазмер сжатого файла будет намного меньше.

Требуется ли файл шрифта?gzip?

Распространенные форматы изображений на веб-сайте:jpg(jpeg),png,gif,webp, изображения в этих форматах сами оптимизированы, поэтому больше неgzip. на самом деле сделать картинуgzipСжатие не только не влияет, но и может сделать изображение больше. Так что насчет файла шрифта, он такой же, как на картинке?

Иконочные шрифты, сгенерированные из векторной библиотеки AlibabacssМы видим, что общие файлы шрифтов:eot,woff,ttf,svg,Кроме тогоwoff2даbase64формат сохранен.

@font-face {font-family: "iconfont";
  src: url('iconfont.eot?t=1587624344896'), /* IE9 */
  url('iconfont.woff?t=1587624344896') format('woff'),
  url('data:application/x-font-woff2;charset=utf-8;base64,...') format('woff2'),
  url('iconfont.ttf?t=1587624344896') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
  url('iconfont.svg?t=1587624344896#iconfont') format('svg'); /* iOS 4.1- */
}

После проверки данных выяснилось, что:eotа такжеttfФормат вообще не сжимается сам по себе, а значит, его можноgzipсжатие. а такжеwoffФормат имеет встроенную компрессию и не требуетgzipсжатие.

Протестируйте и узнайтеeotа такжеttfможно сжать, эффект неплохой, иwoffотформатировано,CompressionWebpackPluginПлагин вообще не поддерживает сжатие, даже если вы его пропишете и настроитеwoffфайл, он также не генерируетgzдокумент.

И эксперимент показал, что,svgХотя это картина, это также может быть сделаноgzipСжатие, эффект сжатия неплохой:

В заключение:svg,eotа такжеttfФайлы шрифтов в этих трех форматах можно использоватьCompressionWebpackPluginсжать и сопоставитьNginxизgzip_typesнастроить,woffа такжеwoff2Форматировать файлы шрифтов не требуетсяgzip.

конфигурация сервераgzipкомпрессия

NginxЭто обычно используемый сервер для интерфейсных файлов.Nginxфайл конфигурации сервераnginx.confизhttpМодуль:

server {
  # 开启gzip on为开启,off为关闭
  gzip on;
  # 检查是否存在请求静态文件的gz结尾的文件,如果有则直接返回该gz文件内容,不存在则先压缩再返回
  gzip_static on;
  # 设置允许压缩的页面最小字节数,页面字节数从header头中的Content-Length中进行获取。
  # 默认值是0,不管页面多大都压缩。
  # 建议设置成大于10k的字节数,配合compression-webpack-plugin
  gzip_min_length 10k;
  # 对特定的MIME类型生效,其中'text/html’被系统强制启用
  gzip_types text/javascript application/javascript text/css application/json;
  # Nginx作为反向代理的时候启用,开启或者关闭后端服务器返回的结果
  # 匹配的前提是后端服务器必须要返回包含"Via"的 header头
  # off(关闭所有代理结果的数据的压缩)
  # expired(启用压缩,如果header头中包括"Expires"头信息)
  # no-cache(启用压缩,header头中包含"Cache-Control:no-cache")
  # no-store(启用压缩,header头中包含"Cache-Control:no-store")
  # private(启用压缩,header头中包含"Cache-Control:private")
  # no_last_modefied(启用压缩,header头中不包含"Last-Modified")
  # no_etag(启用压缩,如果header头中不包含"Etag"头信息)
  # auth(启用压缩,如果header头中包含"Authorization"头信息)
  # any - 无条件启用压缩
  gzip_proxied any;
  # 请求加个 vary头,给代理服务器用的,有的浏览器支持压缩,有的不支持,所以避免浪费不支持的也压缩
  gzip_vary on;
  # 同 compression-webpack-plugin 插件一样,gzip压缩比(1~9),
  # 越小压缩效果越差,但是越大处理越慢,一般取中间值
  gzip_comp_level 6;
  # 获取多少内存用于缓存压缩结果,‘16  8k’表示以8k*16 为单位获得。
  # PS: 如果没有.gz文件,是需要Nginx实时压缩的
  gzip_buffers 16 8k;
  # 注:99.99%的浏览器基本上都支持gzip解压了,所以可以不用设这个值,保持系统默认即可。
  gzip_http_version 1.1; 
}

экзаменgzipВступает ли это в силу

Заголовок запроса файла браузера содержит поляAccept-Encoding: gzipозначает поддержку браузераgzipСжатый файл

Заголовок ответа файла содержит поляContent-Encoding: gzipПредставляет возвращенный сжатый файл

в то же времяNetWorkСтолбец также может отображать фактический размер файла и фактический запрос (gzip)Размер файла

экзаменNginxиспользуем ли мыgzдокумент

NginxПринести свои собственныеgzipФункция сжатия, если мы ее не предоставим, она будет сжиматься на лету (например,index.htmlфайл), что является пустой тратой ресурсов сервера. Теперь мы предоставилиjsа такжеcssизgzфайл, как судитьNginxс помощью нашегоgzфайл вместо того, чтобы сжимать его самостоятельно?

Выше есть элемент конфигурации:gzip_static on;, после открытияNginxбудет использовать нашgzфайл, но все еще не уверен,Nginxты использовалgzдокумент.

ПроверитьnetworkЗапросить обнаружение, каждый файл имеетetagзаголовок ответа, еслиNginxиспользовал существующийgzфайл, затем запрошенныйetagзначение безW/, и наоборот, если файлNginxсжатый,etagзначение будет иметьW/.

Напримерindex.html:

братьchunk-vendors.jsДля эксперимента сам файл сgzдокумент, запрашиваемыйetagследующим образом (безW/):

В это время мы удаляем серверchunk-vendors.jsсоответствующийgzфайл, обновите страницу, запрос такой:

Таким образом, мы можем убедиться, что пока мы настраиваемgzip_static on;,Nginxбудет отдавать приоритет использованию нашегоgzдокумент.

Приложение -windowsУстановитьNginxсервер

  1. скачатьwindowsВнизNginxустановочный пакет:nginx.org/ru/download…

  1. Разархивируйте сжатый пакет

  1. существуетNginxкаталог с помощьюcmdКомандная строка, команда запуска:start nginx, команда закрытия:nginx -s stop

Примечание. Для изменения файла конфигурации требуется перезагрузка конфигурации:nginx -s reload. После запуска откройтеhttp://localhost:80видимый эффект

Суммировать

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

service workerОн используется для реализации офлайн-приложений и подробно в статье не описан.vue-cli4изpwaШаблон, созданный плагином, поставляется сservice worker, может этоvueЛучшая практика для кэширования элементов?

наконец,NginxЯ не очень знаком с этим, если есть какие-либо проблемы и ошибки, пожалуйста, укажите!