Методы внешней оптимизации, которые вы знаете

внешний интерфейс
Методы внешней оптимизации, которые вы знаете

Это будет оптимизировано.Я либо не очень хорош, либо он медленный, эй~ Я просто играю~.

banner.png

предисловие

оптимизация производительностиЭто тема, которую невозможно обойти после разработки проекта в течение определенного периода времени, и она также является занозой в сердце каждого инженера.

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

Возможное влияние на производительность (Предупреждение о тревоге при продаже❗️)

Только представьте, когда вы делаете крутые спецэффекты, потому что это медленно0.1Одиночество (ㄒoㄒ), когда тебя видит на одного человека меньше за секунды,

Только представьте, когда вы гордитесь детальным взаимодействием, потому что оно медленное.0.2Гнев пользователя был снят посредственным взаимодействием конкурентов за секунды (╯>д

Представьте, когда ваши хорошо продуманные красивые страницы работают медленно0.3Беспомощный ∑(O_O;) безжалостно отстает от поисковых систем за секунды.

Поэтому настало время нанести сильный удар и переделать славу производительности.Это наш долг ( ̄▽ ̄)/.

инструменты отладки

Сетевая панель

Панель Сеть фиксирует особенности взаимодействия с сервером.

network1.jpgЗдесь мы можем увидеть количество инициированных запросов, объем передачи и распакованный объем, а также то, какие ресурсы попали в сильный кеш, а какие — в согласованный кеш.

network2.jpg

Глядя на каскад запросов, мы можем четко увидеть, сколько времени требуется ресурсу, чтобы добраться с сервера до нашего компьютера.

Как показано выше, создание очереди заняло 1,65 мс, DNS-запрос занял 21,47 мс, начальное соединение (время TCP-квитирования) заняло 56,25 мс, SSL-квитирование заняло 37,87 мс, а затем для первого слова потребовалось более 100 мс. Строфа дошла до нашего компьютера ( TTFB — запрос/сборка выше), и для получения всего документа потребовалось 17 мс.

В настоящее время мы можем примерно получить его на основе приведенной выше информации.Если мы можем получить адрес DNS (предварительный запрос) до запроса ресурсов, мы можем сэкономить 21 мс, и мы можем сэкономить 100 мс (предварительное подключение), если мы сделали рукопожатие.Не запрашивая можно сэкономить 200мс (кэш) и потом делать соответствующие политики для этих точек.

Панель «Сеть» позволяет нам предварительно оценить производительность веб-сайта, дать общее представление об общем объеме веб-сайта и влиянии сети, а также предоставить некоторые вспомогательные функции, такие как отключение кеша и блокировка определенных ресурсов.

маяк панель

lighthouse1.jpg

Lighthouse — это общая оценка веб-сайта, оценивающая веб-сайт по нескольким различным показателям.

First Contentful PaintДля времени рендеринга первого экрана Chrome будет использовать первый отображаемый элемент в качестве эталона времени.

Time to InteractiveВремя взаимодействия, с того момента, когда вы можете увидеть и потрогать.

Speed IndexИндекс скорости, насколько быстро заполняется страница.

Total Blocking TimeИз суммы задач, которые можно увидеть и потрогать более 50мс.

Largest Contentful PaintМомент времени, когда была отображена самая большая часть страницы.

Cumulative Layout ShiftНакопленный момент времени движения элемента, например, когда абсолютный элемент внезапно переместился слева направо.

В то же время, для информации веб-сайта маяк также даст некоторые предложения по улучшению:

lighthouse2.jpg

Эти предложения могут помочь нам задать общее направление для следующей оптимизации.

панель производительности

performance1.jpg

Панель производительности предоставит нам конкретный процесс выполнения, от загрузки HTML-документов, разбора HTML, разбора CSS, вычисления стилей и выполнения JS.

график пламени

performance2.jpg

На графике пламени мы можем найти длинные задачи, проанализировать длинные задачи или найти какие-то неважные задачи, чтобы разделить их, отложить их и оптимизировать до идеального состояния.

панель монитора производительности

pm1.jpg

Монитор производительности позволяет нам отслеживать использование памяти и ЦП.Он предоставляет общие данные об использовании, которые можно использовать для наблюдения за тем, повлияет ли определенный специальный эффект определенного фрагмента кода на производительность.

webpack-bundle-analyze

wba.gif

Если вы используете упаковку веб-пакета, вы можете использовать ее для анализа упакованных файлов и разработки конкретных стратегий.

Начните с ввода URL

Вот URL-адрес, чтобы увидеть, как вы проходите через бесчисленные маршрутизаторы для трогательной истории.

DNS-запрос

Для взаимодействия с сервером необходимо сначала выполнить DNS-запрос для получения IP-адреса сервера. Браузер сначала запросит собственный кеш, а затем запросит локальные HOSTS. Если он все еще не находит его, он инициирует запрос на DNS-сервер.

Здесь не так много оптимизаций, которые мы можем сделать, DNS — это относительно неконтролируемое состояние, но одна стратегия оптимизации, которую мы все же можем использовать, — это предварительный запрос.

Сделать предварительный запрос DNS

В верхней части документа мы можем предварительно запросить DNS для адреса, который мы собираемся запросить, вставивlinkЭтикетка

<link rel="dns-prefetch" href="https://fonts.googleapis.com/">

Чтобы сообщить браузеру, что мы собираемся тянуть данные с этого адреса (обычно это адрес CDN, на котором хранятся статические ресурсы), вы можете сначала запросить его, и вы можете напрямую получить соответствующий IP при его использовании.

dns-prefetch

Установить HTTP (TCP) соединение

После получения IP-адреса сервера выполняется первое трехэтапное рукопожатие, а затем выполняется рукопожатие SSL (HTTPS), во время рукопожатия SSL серверу подтверждается версия HTTP.

Для оптимизации в этом плане есть не так много вещей, которые может делать фронтенд, в основном вещи на стороне сервера, но все же необходимо понимать стратегии, которые может видеть фронтенд.

keep-alive

Из-за надежности TCP каждое независимое TCP-соединение будет выполнять трехстороннее рукопожатие.Из приведенного выше анализа сети видно, что рукопожатие часто занимает большую часть времени, а реальная передача данных будет меньше (конечно , в зависимости от содержания). HTTP1.0 и HTTP1.1 добавили заголовки для решения этой проблемы.Connection: Keep-Alive,keep-aliveСоединение будет оставаться открытым в течение определенного периода времени, и последующие запросы будут повторно использовать этот TCP, но это также будет происходить по причинам конвейера.блокировка в начале очередиПроблема.

HTTP1.1 включает Keep-Alive по умолчанию. HTTP1.0 сейчас может быть редкостью. Если вы все еще используете его, вы можете обновить версию или принести этот заголовок.

connection keep-alive

HTTP2

Основным усовершенствованием HTTP2 по сравнению с HTTP1.1 является мультиплексирование.Мультиплексирование формирует несколько потоков данных через меньшие двоичные кадры.Чередующиеся запросы и ответы могут бытьПараллельная передачаБез блокировки это решает проблему мультиплексирования при использовании HTTP1.1.блокировка в начале очередиВ то же время в HTTP2 есть функция сжатия заголовков, если два заголовка запроса (headers) совпадают, то эта часть будет опущена, и будут передаваться только разные поля заголовка, что еще больше уменьшит объем запроса.

Для Nginx очень легко открыть HTTP2, просто добавьте одно предложениеhttp2Либо включить:

server {
	listen 443 ssl http2; # 加一句 http2.
	server_name domain.com;
}

Низкая стоимость и отличный эффект.

HTTP2

тайник

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

Существует два основных типа кэширования HTTP: сильное кэширование и согласованное кэширование, оба из которых контролируются заголовками.

Общий процесс выглядит следующим образом:

cache.png

Сильный кеш

Сильное кэширование на основе заголовков запросовExpiresиCache-ControlОпределите, попал ли сильный кеш, и ресурсы, которые попали в сильный кеш, загружаются напрямую из локального, без каких-либо сетевых запросов.

Cache-ControlЕсть много значений:

Cache-Control: max-age=<seconds>
Cache-Control: max-stale[=<seconds>]
Cache-Control: min-fresh=<seconds>
Cache-control: no-cache
Cache-control: no-store
Cache-control: no-transform
Cache-control: only-if-cached

Обычно используютсяmax-age,no-cacheиno-store.

max-ageмаксимальное время свежести ресурса с момента начала ответа, а также будет отображаться в общем ответеageУказывает текущую свежесть этого ресурса.

no-cacheПозволит браузеру кэшировать этот файл локально, но не в сетиdisable-cacheЕсли она отмечена, в запросе будет приведен хаадер, а кеш будет использоваться после прохождения очередной проверки свежести.

no-storeПолностью откажется от кэширования этого файла.

Когда сервер отвечаетCache-ControlЕсть небольшие отличия, два из которых необходимо отметить:

  1. public, public указывает, что этот запрос может кэшироваться любым объектом, прокси/CDN и другими посредниками.
  2. private, private указывает, что этот запрос может кэшироваться только терминалом, и никакие посредники, такие как прокси или CDN, не могут кэшироваться.

ExpiresЭто конкретная дата, когда эта дата наступит, кеш будет деактивирован, он имеет более низкий приоритет и существует.max-ageВ случае , оно будет проигнорировано и привязано к местному времени.Изменение местного времени можно обойти.

Кроме того, если возвращаемый контент вашего сервера не существуетExpires,Cache-Control: max-age,илиCache-Control:s-maxageно существуетLast-Modified, то браузер по умолчанию будет использовать эвристический алгоритм, то есть эвристическое кэширование. обычно берут заголовок ответаDate_value - Last-Modified_value10 % значения используется в качестве времени кэширования. После этого браузер по-прежнему будет рассматривать ресурс как надежный кэш в течение определенного периода времени. Если вы не хотите кэшировать, убедитесь, чтоno-cacheилиno-storeв заголовках ответов.

Согласовать кеш

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

Ответ сервера будет содержатьETagиLast-Modified,Last-ModifiedУказывает дату последней модификации локального файла, браузер добавит ее в заголовок запросаIf-Modified-Since(последний возвратLast-Modifiedзначение), запросить у сервера, обновлялся ли ресурс после этой даты, и если есть обновление, новый ресурс будет отправлен обратно.

Но если вы откроете файл кеша локально, это вызоветLast-Modifiedбыл модифицирован так, что в HTTP/1.1 появилосьETag.

EtagПодобно отпечатку пальца, изменения ресурсов могут вызватьETagИзменения не имеют ничего общего со временем последней модификации.ETagКаждый ресурс может быть гарантированно уникальным

If-None-MatchЗаголовок вернет последний возвращенныйETagОтправлено на сервер с запросом на ресурсETagЕсть ли обновление, новый ресурс будет отправлен обратно, если есть изменение

ETag(If-None-Match) имеет более высокий приоритет, чемLast-Modified(If-Modified-Since),Приоритетное использованиеETagПройти верификацию.

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

CDN

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

компрессия

Разумное сжатие ресурсов может эффективно уменьшить объем передачи.В результате уменьшения объема передачи пользователи могут быстрее получить ресурсы и начать анализ.

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

Браузер будет нести его в заголовках при выполнении запросаaccept-encoding: gzip, deflate, br, чтобы сообщить серверу алгоритм сжатия, приемлемый для клиента, и тогда ресурс ответа будет перенесен в заголовок ответаcontent-encoding: gzipСообщает алгоритм сжатия для этого файла.

GZIP-сжатие

GZIP — очень часто используемый алгоритм сжатия, который поддерживается современными клиентами.Вы можете загрузить сжатый файл при загрузке файла или позволитьДинамическое сжатие Nginx.

рендеринг страницы

критический путь рендеринга

workflow.jpg

Критический путь рендеринга — это последовательность шагов, которые браузер выполняет для преобразования HTML/CSS/JS в пиксельный контент, видимый на экране.

После того, как браузер получит HTML, он начнет парсить DOM-дерево. Загрузка ресурсов CSS не заблокирует парсинг DOM, но также следует отметить, что если CSS не загружен и не парсится, он заблокирует конечный результат. рендеринг.

На панели «Производительность» вы можете четко увидеть, как браузер анализирует HTML:

parsehtml.jpg

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

parsehtml2.jpg

Здесь есть еще много вещей, которые можно сделать на переднем конце, а затем мы начнем сверху вниз.

визуализировать страницу

Предварительная загрузка/подключение контента

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

preload

использовать ссылкуpreloadсвойство для предварительной загрузки ресурса.

<link rel="preload" href="style.css" as="style">

Атрибут as может указывать предварительно загруженный тип.В дополнение к стилю также поддерживаются многие типы.Обычно используемые обычноstyleиscript, css и js.

Другие типы могут просматривать документацию:

preload

prefetch

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

Конечно, для текущей страницы используйте предварительную загрузку вместо предварительной выборки.Сценарий, который можно использовать, заключается в выполнении предварительной выборки, когда пользователь перемещает мышь в тег a.

prefetch

preconnect

Preconnect и dns-prefetch делают похожие вещи. TCP и SSL рукопожатия выполняются заранее, чтобы сэкономить эту часть времени. Основываясь на функциях HTTP1.1 (keep-alive) и HTTP2 (мультиплексирование), все они будут в ту же ссылку TCP.Выполните следующую задачу передачи.

пометка скрипта

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

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

асинхронный тег

<script src="main.js" async>

Тег async сообщает браузеру, что он может делать другие вещи, ожидая загрузки js.Когда загрузка js будет завершена, она будет выполнена немедленно (как можно скорее), и несколько js могут быть загружены параллельно.

Преимущество асинхронности в том, что несколько js не будут ждать друг друга, во время загрузки браузер будет заниматься другими делами (продолжать парсить HTML и т. д.), асинхронная загрузка и асинхронное выполнение.

отложить отметку

<script src="main.js" defer></script>

Как и асинхронный, тег defer сообщает браузеру, что он может делать другие вещи, ожидая загрузки js.Несколько js могут быть загружены параллельно, но он не будет выполняться сразу после завершения загрузки js, а будет ждать загрузки js. полный HTML-код, который необходимо проанализировать перед началом выполнения. , и несколько js с отложенной маркировкой будут выполняться последовательно,

<script src="main.js" defer></script>
<script src="main2.js" defer></script>

Несмотря на тоmain2.jsдоmain.jsОн также будет ждать завершения загрузкиmain.jsВыполнить после выполнения.

Какой тег использовать?

Оба тега предназначены для асинхронной загрузки тегов script, основное отличие в том, чтоasyncЗаказ не гарантируется и будет выполнен после скачиванияdeferОн будет ждать, пока весь HTML будет проанализирован, прежде чем начать выполнение, и выполнит его в порядке вставки.

Если между двумя сценариями нет зависимости и их можно выполнить как можно быстрее, лучше использоватьasync, с другой стороны, если между двумя сценариями есть зависимость или если вы хотите сначала проанализировать HTML, тогдаdeferболее подходящий.

Ленивая загрузка контента вне окна

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

Уменьшить бессмысленный обратный поток

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

reflow.jpg

Это очень требовательная к производительности штука.В некоторых случаях без перекомпоновки не обойтись.В некоторых случаях можно обойтись без бессмысленной перекомпоновки.Например,используйте Js для конвертации 20liПри переходе на тот же размер избегайте размещения каждогоliизменяются на лету и должны использоваться сclassРазовая смена.

Выберите разумный размер для фотографий и видео

Чем выше разрешение картинки, тем больше потребляется производительность.Конечно, благо четче, но во многих случаях четкость не является особо важным критерием.Можно пожертвовать частью четкости, чтобы сделать картинку и видео меньше.Обычно ПК использует изображение 1x, а мобильный терминал использует изображение 2x. Исходное изображение может быть загружено в сочетании с ленивой загрузкой и ожиданием простоя или активного срабатывания. Как и пакет смайликов, отправленный во время чатов, таких как WeChat QQ, он будет открыт только после нажатия Загрузите исходное изображение.

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

Выберите облачный сервис, который поддерживает динамическую настройку, чтобы насладиться этой красотой~.

Что делать при написании кода

Вышеупомянутое с точки зрения написания кода, а следующее с точки зрения написания кода.

Первое – это упаковка.

Tree-shaking

Tree-shakingОтносится к устранению кода модуля, на который нет ссылок, уменьшению размера кода для повышения производительности страницы, первоначально предложенному свертыванием.

webpack2 добавил паруTree-shakingподдержка в webpack4Tree-shakingПо умолчаниюTree-shakingна основеESModuleОн скомпилирован статически, поэтому, если вы хотите, чтобы он вступил в силу, будьте осторожны, чтобы не использовать модули CommonJS при написании кода, а также будьте осторожны, чтобы не допустить, чтобы babel скомпилировался в форму CommonJS.

Tree-shakingсвязанный с однимsideEffectsКонцепция, поскольку характеристики Js делают полный статический анализ сложной задачей, многие коды часто имеют побочные эффекты, такие как следующий код:

class Handler {
    handleEvent() {
        console.log('You called me.')
    }
}

window.addEventListener('visibilitychange', new Handler())

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

Если вы уверены, что файл является таким файлом с побочными эффектами, вы можетеpackage.jsonдобавлено вsideEffects: ['class.js']Пусть webpack заставит это сделать.

Для некоторых сторонних библиотек входной файл обычно имеет форму CommonJS из соображений совместимости.В настоящее время обычно есть два способа успешно избавиться от ненужных частей.

с высокой экспозициейlodashНапример.

lodashПо умолчанию используется форма CommonJS с использованием обычного метода.import { cloneDeep } from 'lodash'После импорта webpack поместит весьlodashУпаковку, что явно неприемлемо для нас, использующих только одну функцию, можно переписать так:

import cloneDeep from 'lodash/cloneDeep'

Или, если предоставляется версия ESModule, ее также можно использовать напрямую:

import { cloneDeep } from 'lodash-es

Первый является точным импортом и не зависит отre-exports, последнее серьезноTree-shaking.

компрессия

Код в производственной среде не предназначен для просмотра людьми, поэтому нет необходимости учитывать удобочитаемость (уменьшение удобочитаемости также может увеличить стоимость взлома o(≧口≦)o), лучший вариант — как можно меньше символов , webpack4+ не нужен Конфигурация будет сжимать код по умолчанию, если хотите попробовать сами, Js необязателенUglifyJS, CSS необязательноmini-css-extract-plugin.

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
    ],
  },
  optimization: {
    minimizer: [
      new CssMinimizerPlugin(),
    ],
  },
};

Используйте динамический импорт() вместо статического импорта для ленивой загрузки условного рендеринга

Это снова ты~, ленивая загрузка.

Если вы игрок Vue, первый контактimport()может бытьvue-routerДокументация оОтложенная загрузка маршрутаНа самом деле, это специфично для внутренней части компонента, и некоторые подкомпоненты/сторонние библиотеки на основе условий суждения также могут быть переданы таким же образом.import()Таким образом, webpack будет отображать его как отдельный блок при упаковке и попытается загрузить файл, когда будут выполнены условия оценки.

<template>
    <div>
        <sub-component v-if="status" />
    </div>
</tamplate>
<script>
export default {
    components: {
        "sub-component": () => import('./sub-component') // 感谢imluch 指正~ 

    },
    data() {
        return {
            status: false
        }
    },
    mounted() {
        setTimeout(() => {
            this.status = true
        }, 10000)
    }
}
</script>

SSR

Используйте серверную часть для рендеринга определенной части важного контента в первую очередь, а другой контент загружайте лениво, чтобы часть HTML-кода уже существовала, когда он достигает браузера, и определенный контент можно было отобразить на странице. часть, отображаемая на стороне сервера, является лучшей Не превышайте 14 КБ Правило медленного запуска TCP делает размер первого пакета TCP 14 КБ, который является первым пакетом, который будет получен при взаимодействии с веб-сайтом.

Дополнительные методы оптимизации

Вышеупомянутые методы оптимизации известны до сих пор ~, больше оптимизаций еще предстоит обнаружить, проходящие мимо старшие братья и сестры, пожалуйста, поставьте лайк 👍, и вы можете оставить сообщение для обмена, если у вас есть какие-либо вопросы ~ 😝.

zan.jpg