Давай тайком оптимизируем производительность front-end запросов, а потом всех удивим

оптимизация производительности
Давай тайком оптимизируем производительность front-end запросов, а потом всех удивим

xuqiao.png

предисловие

В эту эпоху бурного развития Интернета у людей все выше и выше требования к скорости открытия веб-страниц. Время загрузки слишком велико, обработка совместимости не является достаточно полной и т. д., это легко может привести к потере пользователя. Для фронтенд-разработчика оптимизация взаимодействия с пользователем — бесконечная задача, лучшего нет, есть только лучше. Направлений по оптимизации производительности фронтенда много, сегодня я в основном объясню оптимизацию сетевых запросов. Поскольку задействовано много направлений оптимизации, конкретные детали повторяться не будут.

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

  • запросить управление данными
  • уменьшение размера запроса
  • просьба сделать все возможное

~~

Уменьшено количество запросов

Уменьшить DNS-запросы

DNS-запрос сначала проверяет, существует ли кеш браузера. Если он не существует, он обращается к локальному кешу DNS. Если он не существует, он обращается к локальному DNS-серверу. В течение этого периода браузер не может загружать какие-либо другие ресурсы контента, что много накладных расходов. Таким образом, идеальный способ - поместить статические ресурсы в один и тот же домен как можно больше, чтобы происходил только один поиск DNS, но это также вызывает другую проблему, количество параллельных загрузок браузера ограничено, разные браузеры Серверы разные , а при превышении лимита будет стоять в очереди.Рекомендуется, чтобы сайт использовал 2-4 домена для запроса ресурсов, не слишком разбросанных и не слишком сконцентрированных.

запрос на вытягивание

Количество запросов, необходимых для загрузки веб-страницы, может варьироваться от десятков до сотен. Сюда входят XHR, JS, CSS, Img, Font, Doc и многое другое. В разных браузерах есть ограничения на количество одновременных запросов, если вы обновили HTTP 2.0, этот приоритет можно отложить. Для ресурсов одного типа проверьте, есть ли возможность слияния запросов.Предпосылка слияния также должна учитывать бизнес-сценарий и не будет ли объединенный объем слишком большим. Маленькая иконка ресурса изображения учитывает комбинацию изображения Sprite (CSS Sprites)background-positionиспользовать. Изображения, которые слишком малы, могут быть преобразованы в Base64, доступны в веб-пакете.url-loaderконфигурация. В дополнение к обработке слияния для статических ресурсов взаимодействие интерфейса с серверной частью также может быть объединено в зависимости от ситуации, не влияя на производительность интерфейса.

нагрузка по требованию

Проверяйте, нужен ли каждый запрос для текущей страницы, и максимально загружайте ее, чтобы избежать лишнего занятия ресурсов.Это может не только повысить скорость открытия страницы и сэкономить ресурсы пользовательского трафика, но и уменьшить запросы трафика сервера. Отложенная загрузка маршрутизации может быть включена в Vue, и JS и CSS страницы будут запускать запрос только при загрузке страницы. Ленивая загрузка изображений может предотвратить загрузку некоторых изображений в невидимых областях, избежать одновременной загрузки слишком большого количества изображений и вызвать блокировку запросов, повысить скорость загрузки веб-сайта и улучшить взаимодействие с пользователем.

Повторная обработка запроса

Пользователи часто переключают данные в столбцах вкладок, отправка форм часто нажимается, при переключении маршрутизации остаются незавершенные запросы. Все они генерируют недопустимые запросы, которые вредны как для сервера, так и для пользователей. Повторные запросы могут хранить текущие сохраненные теги в массиве или на карте при инициации каждого запроса.Для каждого запроса проверьте, повторяется ли он в перехвате запроса.Если он повторяется, отмените повторный запрос в истории, а затем инициируйте Текущий запрос Запрос, если нет дубликатов, добавьте тег хранилища и запросите как обычно, запрошено завершение очистки тега хранилища, доступно в AxiosCancelTokenфункция, функция этой функции состоит в том, чтобы отменить запрос интерфейса; когда маршрут переключает страницы в Vue, его можно использовать в маршрутизаторе.beforeEachОтмените все запросы, которые в настоящее время выполняются в функции ловушки.

Добавить в журнал запросов:

const addPendingXHR = (config) => {
  if (!cancelDuplicated) {
    return
  }
  const duplicatedKey = JSON.stringify({
    duplicatedKey: duplicatedKeyFn(config),
    type: REQUEST_TYPE.DUPLICATED_REQUEST
  })
  config.cancelToken = config.cancelToken || new axios.CancelToken((cancel) => {
    if (duplicatedKey && !pendingXHRMap.has(duplicatedKey)) {
      pendingXHRMap.set(duplicatedKey, cancel)
    }
  })
}

Отменить запрос и удалить запись запроса:

const removePendingXHR = (config) => {
  if (!cancelDuplicated) {
    return
  }
  const duplicatedKey = JSON.stringify({
    duplicatedKey: duplicatedKeyFn(config),
    type: REQUEST_TYPE.DUPLICATED_REQUEST
  })
  if (duplicatedKey && pendingXHRMap.has(duplicatedKey)) {
    const cancel = pendingXHRMap.get(duplicatedKey)
    cancel(duplicatedKey)
    pendingXHRMap.delete(duplicatedKey)
  }
}

Использование в аксиомах:

// 请求拦截处理
axios.interceptors.request.use(config => {
    removePendingXHR(config)
    addPendingXHR(config)
    ...
    return config
})

// 响应拦截处理
axios.interceptors.response.use(response => {
    removePendingXHR(response.config)
    ...
}, error => {
    // 如果是取消请求类型则忽略异常处理
    let isDuplicatedType;
    try {
      const errorType = (JSON.parse(error.message) || {}).type
      isDuplicatedType = errorType === REQUEST_TYPE.DUPLICATED_REQUEST;
    } catch (error) {
      isDuplicatedType = false
    }
    if (!isDuplicatedType) {
        // 其他异常处理
    }
})

В Vue, когда маршрут переключает страницы, все запросы к предыдущей странице отменяются:

router.beforeEach((to, from, next) => {
    pendingXHRMap.forEach((cancel) => {
        cancel();
    });
    pendingXHRMap.clear()
})

данные интерфейса кеша

Сокращение взаимодействия с данными означает снижение нагрузки на полосу пропускания сети, предоставление большего количества одновременных услуг, сокращение времени передачи по сети и значительное снижение нагрузки на сервер. Решение: после того, как данные запрашиваются в первый раз, они кэшируются локально на внешнем интерфейсе, а последующие источники данных извлекаются из кэша для анализа и использования данных, из него извлекается и затем отображается информация, необходимая для операций со страницами. , эффективно уменьшая количество запросов к фоновому серверу. Формат кеша может бытьMapилиJSON. Необходимо установить соответствующую стратегию кэширования и периодически очищать исторические данные.Если данные интерфейса часто меняются, данные интерфейса можно извлечь из кеша, а затем запустить для покрытия содержимого страницы.

Предварительный запрос CORS OPTIONS

Когда внешний интерфейс использует сценарий для запроса ресурса из другого источника, если онне простой запрос, браузер сначала автоматически отправит запрос OPTIONS, называемый cors-preflight-request, который используется, чтобы узнать у сервера, находится ли доменное имя текущей веб-страницы в списке разрешенных сервером, и какие HTTP-команды и заголовки могут быть разрешены. Информационное поле; браузер выдаст только формальный перекрестный запрос с утвердительным ответом. Итак, как сохранить запрос OPTIONS для повышения производительности?

  1. сделать простой запрос;
  2. Настройки сервераAccess-Control-Max-AgeПоле кэширует результат ответа на предварительный запрос OPTIONS. Кэш предназначен только для этого URL-адреса запроса и того же заголовка и не может быть кэширован для всего домена или нечеткого соответствия URL-адреса.

уменьшение размера запроса

сжатие ресурсов

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

HTTP-сжатие

gzip является наиболее распространенным и наиболее поддерживаемым браузером методом сжатия данных. Заголовок запроса браузера отправленAccept-Encodingполе, указывающее поддерживаемые алгоритмы сжатия и соответствующие им приоритеты, из которых сервер выбирает метод сжатия и возвращает заголовок ответаContent-Encodingполе, чтобы сообщить браузеру, какой алгоритм выбрать. На рисунке ниже видно, что после включения gzip-сжатия исходный ресурс в 182кб после сжатия составляет всего 75кб, что экономит около 60% передачи данных. Независимо от того, является ли запрос интерфейса отправкой или получением данных, ненужные поля не должны передаваться как можно больше.Это требует большего взаимодействия с одноклассниками сервера, чтобы избежать избыточных данных, влияющих на скорость передачи запроса. Сжатие HTTP может значительно уменьшить объем данных, передаваемых по сети, и повысить скорость отображения страниц, но процесс сжатия также принесет определенные накладные расходы на сервер.image.png image.png

Использовать WebP

Формат webp — это формат изображения, разработанный Google для ускорения загрузки изображений. Объем сжатия изображения составляет всего около 2/3 от объема сжатия JPEG, и это может сэкономить много ресурсов пропускной способности сервера и места для данных. Использование webp позволяет не только экономить ресурсы пользовательского трафика, но и уменьшать ресурсы трафика сервера. Недостаток в том, что некоторые браузеры пока не поддерживают формат webp, поэтому при его использовании нужно обращать внимание на совместимость. Во-первых, проверьте, поддерживает ли текущий браузер webp. Метод обнаружения можно использовать для загрузки однопиксельного изображения webp через холст или JS. Если webp поддерживается, вы можете добавить класс идентификатора webp в корневой узел, чтобы обрабатывать изображение может загрузить файл в формате webp. В настоящее время все основные cdn-сервисы поддерживают вывод в формате webp.Если cdn-сервиса до сих пор нет, вам необходимо сгенерировать картинки в формате webp, которые могут быть сгенерированы в процессе компиляции внешнего интерфейса или могут быть преобразованы на уровне nginx.

Проверьте, поддерживается ли webp

// 使用 canvas 的 toDataURL 进行判断
function isSupportWebp() {
  try {
    return document.createElement('canvas').toDataURL('image/webp', 0.5).indexOf('data:image/webp') === 0;
  } catch(err) {
    return false;
  }
}

// 通过加载一张 webp 图片判断
function checkWebpFeature(feature, callback) {
    var kTestImages = {
        lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
        lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
        alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
        animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
    };
    var img = new Image();
    img.onload = function () {
        var result = (img.width > 0) && (img.height > 0);
        callback(feature, result);
    };
    img.onerror = function () {
        callback(feature, false);
    };
    img.src = "data:image/webp;base64," + kTestImages[feature];
}

Как написать sass в CSS

@mixin webpbg($url) {
    background-image: url($url);
    @at-root .webpa & {
        background-image: url($url+'.webp');
    }
}

@include webpbg('../image/header.jpg');

Использование обнаружения img в HTML

const changeToWebp = (url) => {
    if (isSupportWebp()) {
        return `${url}${url.indexOf('?') > 0 ? '&' : '?'}x-oss-process=image/format,webp`
    } else {
        return url
    }
}

До и после сравнения企业微信截图_16181952052171.pngimage.png

Оптимизация передачи файлов cookie

  • Используйте поле cookie разумно, удалите ненужные файлы cookie и избегайте избыточных данных файлов cookie.
  • При использовании файлов cookie для междоменных операций будьте осторожны, чтобы установить файлы cookie (домен) на доменном имени уровня адаптации, чтобы они не влияли на поддомены.
  • Установите разумное время истечения файла cookie, разумное время истечения срока действия и не удаляйте файлы cookie слишком рано.Браузер имеет ограничения на размер и количество хранилища, и необходимо избегать заполнения доступного пространства браузера.
  • Статические ресурсы используют независимую стратегию доступа к доменному имени, чтобы избежать отправки файлов cookie при запросе статических ресурсов, что снижает объем HTTP-запросов.

image.png

делай все возможное

Включить ускорение CDN

Полное название CDN — Content Delivery Network, то есть сеть распространения контента.Когда пользователь инициирует запрос на служебный контент, запрос будет отправлен на ближайший к пользователю сервисный узел, и сервисный узел быстро ответит напрямую. , эффективно уменьшая задержку доступа пользователей и повышая доступность. В дополнение к общему открытому cdn для статических ресурсов, таких как JS, CSS и IMG, ускорение cdn также может быть включено для некоторых запросов интерфейса, данные которых не меняются часто.

Включить кэширование HTTP

HTTP-кеширование в основном используется для кэширования некоторых статических файлов с низкими требованиями к реальному времени.Он кэшируется на стороне браузера, чтобы предотвратить повторный доступ этих «лишних» запросов к серверу и давление на сервер.Ресурсы получаются непосредственно из браузера кэш, тем самым повышая производительность сайта. Существует два типа кэширования: обязательное кэширование и согласованное кэширование.

Принудительно кэшироватьЭто означает, что сервер возвращает время кеша браузеру.Пока время кеша еще до следующего запроса, запрос не будет инициирован, а кеш будет использоваться напрямую. Если время кеша превышено, выдается запрос на получение файла. В заголовке ответа будет два поля для указания правила истечения срока действия (Expires/Cache-Control).image.png Согласовать кешУказывает, следует ли использовать кеш, запрашивая файл и сравнивая, был ли изменен последний запрос. Когда браузер запрашивает данные в первый раз, сервер возвращает идентификатор кеша и данные клиенту, а клиент создает их резервную копию в базе данных кеша. При повторном запросе данных клиент отправляет резервный идентификатор кеша на сервер, и сервер выносит решение на основе идентификатора кеша.После определения того, что кеш действителен, он возвращает код состояния 304, чтобы уведомить клиента о необходимости использования кэшированные данные. Идентификатор кэша различается двумя способами:

Отметка времени последнего изменения файла:

  • Ответ:Last-Modified
  • Запрос:If-Modified-Since

Идентификатор содержимого файла:

  • Ответ:E-tag
  • Запрос:If-None-Match

image.pngСтарайтесь максимально избегать запросов 304, потому что будет выдан еще один запрос, позволяющий браузеру прочитать файл прямо из кеша, снизив потребление полосы пропускания и нагрузку на сервер.

Обновите HTTP 2.0

В протоколе HTTP/1.1 клиент браузера имеет определенное количество запросов для одного и того же доменного имени одновременно, и запросы, превышающие лимит, будут заблокированы. HTTP2.0 в основном имеет следующие новые функции:

  • мультиплексированиеЭто позволяет одновременно инициировать несколько запросов через одно соединение http/2.0 Все запросы выполняются одновременно через соединение TCP, что действительно обеспечивает параллельную передачу.
  • Каждый запрос HTTP/1.x будет содержать много избыточной информации в заголовке, что тратит впустую много ресурсов полосы пропускания.сжатие заголовка, что уменьшает объем передаваемых данных и позволяет сэкономить сетевой трафик, занимаемый заголовком сообщения.
  • **Server Push** может быстрее передавать ресурсы клиентам. Например, сервер может активно отправлять файлы JS и CSS клиенту, не требуя, чтобы клиент анализировал HTML, а затем отправлял эти запросы. Когда клиенту это нужно, ресурс уже находится на клиенте.

Предварительная загрузка

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

<link rel="dns-prefetch" href="//img.cdn.com">

Чтобы браузер установил соединение, ему сначала необходимо выполнить поиск DNS, трехстороннее рукопожатие TCP и согласование TLS (https), эти процессы занимают довольно много времени, поэтому preconnet — это метод, который позволяет браузеру установить соединение. заранее и т. д. Когда вам действительно нужно загрузить ресурсы, вы можете запросить их напрямую.

<link rel="preconnect" href="//example.com">

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

<link rel="prefetch" href="prefetch.js">

Суммировать

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

наконец

Наконец, спасибо за чтение. Если у вас есть какие-либо вопросы, оставьте сообщение в области комментариев, чтобы обсудить и поучиться друг у друга~ В этом месяце мы выпустим больше статей, связанных с практикой, и вознаградим за сообщения. Вы также можете отсканируйте QR-код ниже и вовремя подпишитесь на нашу публичную учетную запись WeChat. Получить↓

Ссылаться на

  1. Каковы основные улучшения HTTP/2 по сравнению с 1.0?
  2. Насколько dns-prefetch может улучшить скорость сайта?
  3. dns-prefetch, preconnect, prefetch и prerender в теге Head
  4. tinypng
  5. Сведения о кэше HTTP
  6. Некоторые мысли о предварительных запросах CORS OPTIONS