Как бы вы сделали оптимизацию интерфейса?

внешний интерфейс JavaScript
Как бы вы сделали оптимизацию интерфейса?

предисловие

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

Решение для внешней оптимизации

Начнем с обязательного вопроса на собеседовании: "Давайте поговорим о том, как вы занимаетесь фронтенд-оптимизацией?Так как же должно выглядеть относительно законченное решение по оптимизации интерфейса?

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

  • Определите, какие страницы необходимо оптимизировать
    • Установить систему мониторинга
    • Определение показателей мониторинга
    • Анализировать страницы на основе информации о мониторинге
  • Целевая оптимизация
    • Оптимизация ресурсов
    • Оптимизация сборки
    • Оптимизация передачи
    • Оптимизация сети

Определите, какие страницы необходимо оптимизировать

Установить систему мониторинга

Первым шагом является создание системы мониторинга производительности переднего плана. Существует два основных решения для мониторинга производительности переднего плана:

  1. Зрелые услуги, предоставляемые третьими сторонами: такие как Alibaba Cloud ARMS, Tingyun, Monitoring Bao и т. д.
  2. Сделай сам

Я не буду здесь повторять услуги, предоставляемые различными сторонними платформами, а в основном объясню примерную реализацию идеи самостоятельного построения front-end платформы мониторинга производительности.

Определить метрики сбора

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

  • RUM (Наблюдение за реальными пользователями) Метрики: Включая FP, TTI, FCP, FMP, FID, MPFID.

  • Navigation Timing: Включая индикаторы DNS, TCP, парсинга DOM и других этапов.

  • JS Error: после синтаксического анализа его можно разделить на исключения времени выполнения и исключения статических ресурсов.

  • запросить исключение: собирает исключения запросов ajax.

Тогда давайте разберем, как собрать каждый индикатор по отдельности

индикатор РОМ

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

Составляющие метрики основных веб-метрик со временем меняются.развитие. Текущий состав метрик фокусируется на трех аспектах взаимодействия с пользователем:Загрузка производительности,интерактивность,визуальная стабильность

В основном он включает следующие индикаторы (и соответствующие пороговые значения для каждого индикатора):

image-20211014135446592

LCP, FID, CLS

Максимальная прорисовка контента (LCP):которыйLargest Contentful Paint, чтобы измерить производительность загрузки. Чтобы обеспечить хороший пользовательский опыт,LCPдолжен начинаться после первой загрузки страницы2,5 секундыпроисходит внутри.

Время до первого взаимодействия (FID):которыйFirst Input Delay, чтобы записать время задержки первой интерактивной операции пользователя на этапе загрузки страницы.FIDПоказатели влияют на первое впечатление об интерактивности и отзывчивости пользователя.

Совокупное смещение макета (CLS):которыйCumulative Layout Shift, для измерения стабильности зрения. Чтобы обеспечить удобство для пользователей, страницаCLSследует держать на0.1или менее.

дляLCP,FID,CLSмы можем напрямую использоватьweb-vitalsДля сбора код сбора следующий

import { getLCP, getFID, getCLS } from 'web-vitals';

getLCP((data) => console.log('LCP', data))
getFID((data) => console.log('FID', data))
getCLS((data) => console.log('CLS', data))

image-20211014153344548

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

ФП, ФКП

время первой покраски (FP):которыйFirst Paint, что является моментом времени первого рендеринга.

Впервые содержимое времени рендеринга (FCP):которыйFirst Contentful Paint, который является моментом времени, когда содержимое отображается в первый раз.

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

img

Согласно официальному рекомендованному времени, мы должны поставитьFPа такжеFCPсжато до2 секундыВнутри.

Код коллекции выглядит следующим образом

window.performance.getEntriesByType('paint')

image-20211014155422915

TTI

Время до полной интерактивности (TTI):которыйTime to interactive, который записывает время, прошедшее с момента загрузки страницы до момента, когда страница становится полностью интерактивной.

ПолучатьTTIПравила следующие:

  • Рисовать из первого контента (FCP)Начинать

  • Поиск вперед в течение 5 секунд, никаких длинных задач и не более 2 запросов на получение

  • Поиск последней длинной задачи в обратном направлении (занимает более50миллисекундные задачи), если длинные задачи не найденыFCPостановка

  • TTIВремя - это время последней длинной задачи, если длинной задачи нет, то оно равноFCPвремя

Google надеется наTTIПоказатели стандартизированы и переданыPerformanceObserverДоступен в браузерах, но в настоящее время не поддерживается.

В настоящее время только одинpolyfill, чтобы определить текущийTTIдля всех поддерживаемыхLong Tasks APIБраузер.

image-20211014160055611

Согласно официальному рекомендованному времени, мы должны поставитьTTIконтроль над3,8 секундыВнутри

Код коллекции выглядит следующим образом

import ttiPolyfill from 'tti-polyfill'

// collect the longtask
if (PerformanceLongTaskTiming) {
  window.__tti = { e: [] };
  const observer = new PerformanceObserver((list) => {
    for (const entry of list.getEntries()) {
      // observe the longtask to get the time to interactive (TTI)
      if (entry.entryType === 'longtask') {
        window.__tti.e.concat(entry);
      }
    }
  });
  observer.observe({ entryTypes: ['longtask'] });
}

ttiPolyfill.getFirstConsistentlyInteractive().then((tti) => {
  console.log('TTI', tti)
});

Navigation Timing

Здесь мы обращаем внимание на показатели в основном

  • DNSвремя запроса
  • TCPвремя ссылки
  • requestкропотливый
  • РазобратьDOMдерево отнимает много времени
  • время белого экрана
  • domreadyвремя
  • onloadвремя

Способ получить его очень прост, мы можем напрямую пройтиPerformanceTimingчтобы получить их

window.addEventListener('load', () => {
  setTimeout(() => {
    const timing = window.performance.timing;
    console.log('DNS查询耗时:', timing.domainLookupEnd - timing.domainLookupStart)
    console.log('TCP链接耗时:', timing.connectEnd - timing.connectStart)
    console.log('request耗时:', timing.responseEnd - timing.responseStart)
    console.log('解析DOM树耗时:', timing.domComplete - timing.domInteractive)
    console.log('白屏时间:', timing.domLoading - timing.fetchStart)
    console.log('domready时间:', timing.domContentLoadedEventEnd - timing.fetchStart)
    console.log('onload时间:', timing.loadEventEnd - timing.fetchStart)
  }, 0);
})

JS Error

сборJS ErrorЗдесь мы можем использоватьerrorа такжеunhandledrejectionЭти два события для обнаружения ошибок JS иPromiseнеобработанныйrejectionаномальный.

Ниже приведен простой код

window.onerror = (errorMsg, url, lineNumber, columnNumber, errorObj) => {
  let errorStack = errorObj ? errorObj.stack : null;
  // 这里进行上报
  console.log(errorMsg, url, lineNumber, columnNumber, errorStack)
};

window.onunhandledrejection = (e) => {
  let errorMsg = "", errorStack = "";
  if (typeof e.reason === "object") {
    errorMsg = e.reason.message;
    errorStack = e.reason.stack;
  } else {
    errorMsg = e.reason;
  }
  // 这里进行上报
  console.log(errorMsg, errorStack)
}

запросить исключение

Чтобы поймать исключения запросов, мы можем переписатьwindow.fetchа такжеXMLHttpRequestреализовать.

Анализ страниц на основе данных мониторинга

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

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

Вот также предложение по оптимизации целиЦель: быть как минимум на 20% быстрее своего самого быстрого конкурента.

согласно сИсследование пользовательской психологии, если вы хотите, чтобы пользователи чувствовали вашуwebВеб-сайт быстрее, чем конкуренты, поэтому вы должны быть быстрее, чем они20%над. Изучите своих основных конкурентов, соберите показатели их производительности на мобильных и настольных устройствах и установите пороговые значения, которые помогут вам превзойти конкурентов. Однако для получения точных показателей производительности и постановки целей важно сначала получить полное представление о пользовательском опыте с помощью анализа исследований. Затем вы можете смоделировать тесты, основанные на отзывах и опыте 90% ваших ключевых пользователей.

Целевая оптимизация

Оптимизация ресурсов

Сжатие обычного текста с помощью Brotli

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

image-20211014180650040

BrotliСуществует соотношениеGzipа такжеDeflateБолее высокая степень сжатия, но также требуется более длительное время сжатия, поэтому не рекомендуется выполнять сжатие в режиме реального времени по запросу. Но мы можем предварительно сжать статические файлы и передать их клиенту напрямую, поэтому мы избегаемBrotliПроблема низкой эффективности сжатия, и, используя этот метод, мы можем использовать самый высокий уровень качества сжатия, чтобы сжать файл и минимизировать размер файла.

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

BrotliМожет использоваться для любого простого текстового содержимого, такого какHTML,CSS,SVG,JavaScriptЖдать.

Настроен с максимальной степенью сжатияПредварительно сжатые статические ресурсы Brotli + Gzipи использоватьBrotliНастройте 3-5 коэффициентов сжатия для быстрого сжатияHTML. Убедитесь, что сервер обрабатывает его правильноBrotliилиgzipЗаголовок согласования содержания.

image-20211014180532153

Использование адаптивных изображений и WebP

WebPИзображение — это новый формат изображений, разработанный Google. а такжеpng,jpgПо сравнению с тем же визуальным опытом,WebPРазмер изображения был уменьшен примерно30%. Кроме того,WebPФормат изображения также поддерживает сжатие с потерями, сжатие без потерь, прозрачность и анимацию. Теоретически его можно полностью заменить.png,jpg,gifи другие форматы изображений, но в настоящее времяWebPеще не полностью поддерживается, но мы все еще можем использовать его в нижней строке.

Поэтому при использовании изображений используйте изображения сsrcset,sizesа также<picture>элементальадаптивные изображения. При использовании вы также можете<picture>элементы иJPEGкарман для использованияWebPФормат.

image-20211014182421007

ноWebPНе без недостатков, не поддерживаетПрогрессивный рендеринг, такой как JPEG, поэтому пользователи используютJPEGМожет быть, быстрее увидеть фактическое изображение! несмотря на то чтоWebPИзображения могут загружаться быстрее в сети. использоватьJPEGМы можем дать пользователю более «приличный» опыт за половину или даже четверть времени, а остальные данные загрузить позже, а не какWebPЭто просто полупустой образ. Так что это зависит от того, что мы хотим: используйтеWebP, уменьшит размер изображения; используйтеJPEG, что улучшит воспринимаемость изображения.

Правильно ли оптимизированы изображения?

В нашем проекте очень важна быстрая загрузка изображений, поэтому нужно быть внимательным при использовании изображений:

  • убедисьJPEGпостепенно визуализируется и используетmozJPEGилиGuetzliсжатие.

  • использоватьPingoкомпрессияpng

  • использоватьSVGOилиSVGOMGправильноSVGсжать

  • Изображение илиiframeленивая загрузка

  • По возможности рекомендуется использовать петлевойvideoилиWebPзаменятьgif

    image-20211014184339051

[использоватьffmpegБудуgifПревратиться вMP4Пост-оптимизация производительности]

Оптимизированы ли веб-шрифты?

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

  • Если позволяют условия, мы можемподмножество(можно использоватьsubfontчтобы помочь нам проанализировать проект)
  • использоватьpreloadдля предварительной нагрузки шрифтов
  • При необходимости кэшируйте шрифты вService Workerсередина

Оптимизация сборки

Используете ли вы встряхивание дерева, подъем области видимости и разделение кода?

  • tree-shaking— это способ убрать бесполезные зависимости в пакете сборки, он делает результат сборки только кодом, фактически используемым в производстве, и устраняетWebpack中未使用的引入。 с помощьюWebpackа такжеRollup, мы также можем достичьscope hoisting, оба инструмента могут обнаруживатьimportГде можно прервать цепочку и превратить ее во встроенную функцию, не нарушая код. с помощьюWebpack, мы также можем использоватьJSON Tree Shaking

  • code-splitingдаWebpackЕще одна функция, которая разбивает ваш код на загрузку по требованию.chunk. Не всеJavaScriptВсе должно быть загружено, проанализировано и скомпилировано немедленно. Как только точка разделения определена в коде,WebpackЗатем зависимости и выходные файлы могут быть обработаны. Это позволяет браузеру сохранять первоначальную загрузку небольшой и запрашивать код по требованию, когда его запрашивает приложение.

  • рассмотрите возможность использованияpreload-webpack-plugin, этот плагин может использоваться браузером в соответствии с разделением вашего кода<link rel="preload">или<link rel="prefetch">код с разделителями парchunkпредварительная загрузка.Встроенные директивы Webpackтоже правильноpreload/prefetchнекоторый контроль (но будьте осторожныприоритетный вопрос. )

Можно ли абстрагировать JavaScript в Web Worker?

Чтобы сократить отнимающее много времени интерактивное время, лучше всего иметь тяжелые вычисления.JavaScriptотстраниласьWeb Workerсредний или проходнойService Workerкеш. потому чтоМанипуляции с DOM выполняются в основном потоке вместе с JavaScript.. использоватьWeb workerЭти дорогостоящие операции можно разгрузить для выполнения в других потоках в фоновом режиме. в состоянии пройтиWeb WorkerПредварительно загрузите и сохраните некоторые данные для последующего использования при необходимости. можно использоватьComlinkупростить сWeb Workerобщение между.

Можно ли абстрагировать часто выполняемые функции в WebAssembly?

мы можемИзбавьтесь от тяжелых вычислительных задачприбытьWebAssembly(WASM) Исполнение, это бинарный формат инструкции, он разработан как переносимый скомпилированный объект языка высокого уровня (например, C/C++/Rust). И большинство современных браузеров уже поддерживаютWebAssembly, и сВызовы функций между JavaScript и WASM становятся все быстрее и быстрее, этот метод будет становиться все более и более осуществимым.WebAssemblyне предназначен для заменыJavaScript, но может использоваться, когда вы обнаружите, что загрузка ЦП слишком высокаJavaScriptдобавкаJavaScriptбольше подходит для большинства веб-приложений, аWebAssemblyЛучше всего подходит для ресурсоемких веб-приложений, таких как веб-игры.

Прилагается нижеJavaScriptа такжеWebAssemblyСравнение процессов:

05-01-diagram_now01.png

image-20211015112700280

Используете ли вы шаблон модуля/номодуля в JavaScript?

Мы просто хотим отправить необходимоеJavaScript, но это означает больше внимания и детализации при предоставлении этих ресурсов.module/nomoduleИдея состоит в том, чтобы скомпилировать и предоставить два отдельныхJavaScriptПакеты: «Обычная» сборка строится таким образом, что пакет, содержащийBabelКонвертировать иpolyfills, только для старых браузеров, которым они действительно нужны, другой пакет (такой же функциональности) не содержитBabelКонвертировать иpolyfills.

JS module(или называетсяES module,ECMAScript module) — это основная новая функция или набор новых функций. Возможно, вы использовали стороннюю систему загрузки модулей.CommonJsТакие какnodeJs,AMDТакие какrequireJsи т.п. Все эти системы загрузки модулей имеют одну общую черту: они позволяют выполнять операции импорта и экспорта.

способен распознатьtype=moduleсинтаксис, который браузеры игнорируютnomoduleатрибутscripts. Тем не менее, мы можем использовать какой-нибудь скриптовый сервис для поддержкиmoduleсинтаксис для браузеров, предоставляяnomoduleСкрипты, используемые для которых не поддерживаютсяmoduleСинтаксис для браузеров, как средство.

image-20211015113845674

использоватьtype=moduleОптимизация объема встроенного файла снижена на 30% ~ 50% по сравнению с обычным встроенным файлом, и мы также можем ожидать оптимизации производительности нового синтаксиса в браузере.

Определите и удалите неиспользуемый CSS/JS

в ChromeИнструмент покрытия кода CSS и JavaScript (Coverage)Может дать нам представление о том, какой код был выполнен или применен, а какой нет. Мы можем начать проверку покрытия и посмотреть результаты покрытия. После обнаружения неиспользуемого кодаНайдите эти модули и используйте import() для их ленивой загрузки.. Затем повторите проверку покрытия кода, чтобы убедиться, что теперь при инициализации загружается меньше кода.

вы можете использоватьPuppeteerдля сбора покрытия кода,Puppeteerмногое другоеДругое использование,НапримерСледите за неиспользуемым CSS в каждой сборке.

также,purgecss,UnCSSа такжеHeliumможет помочь вам отCSSУдалите неиспользуемые стили в .

image-20211015120017651

Уменьшить размер пакета JavaScript

Добавьте проверку зависимостей в свой ежедневный рабочий процесс. Замените некоторые из больших библиотек, которые вы, возможно, добавили много лет назад, на меньшие и более легкие библиотеки, например, с помощьюDay.jsзаменятьMoment.js

использоватьBundlephobiaТакие инструменты, как npm, могут помочь вам понять стоимость добавления пакета npm.size-limitНе только проверит размер, но и отобразитJavaScriptвремя исполнения.

image-20211015133611523

Используйте оптимизации для целевого движка JavaScript.

что посмотретьJavaScriptДвижок доминирует над вашей пользовательской базой, а затем изучите способы его оптимизации. Например, при нацеливанииBlinkбраузер,Node.jsвремя выполнения иElectronПри оптимизации для V8, используемого в , вы можете использоватьпоток сценариевдля обработки общего сценария.

Оптимизирован поток скриптовJavaScriptПарсинг файлов. Предыдущая версияChromeПроще говоря, сценарий полностью загружается перед началом анализа сценария, но ЦП не используется полностью, пока загрузка не будет завершена. Начиная с версии 41,Chromeбудет проанализирован в отдельном потоке, как только начнется загрузкаАсинхронные и отложенные сценарии. Это означает, что синтаксический анализ может быть завершен в течение миллисекунд после загрузки и приводит к ускорению загрузки страницы до 10%. Это особенно эффективно для больших скриптов и медленных сетевых подключений.

После того, как загрузка начнется,поток сценариевразрешатьasyncилиdefer scriptsАнализируя фон на отдельной резьбе, поэтому в некоторых случаях время загрузки страницы может быть уменьшена до 10%. а также,использовать отсрочку скрипта в заголовке,Может сделатьБраузеры обнаруживают ресурсы раньше, а затем проанализируйте его в фоновом потоке.

предупреждать:Opera Mini Задержки скрипта не поддерживаются, поэтому, если ваш основной пользователь используетOpera Mini,deferбудет игнорироваться, что приведет к блокировке рендеринга до завершения выполнения скрипта.

Рендеринг на стороне клиента или рендеринг на стороне сервера?

Использовать рендеринг на стороне клиента или рендеринг на стороне сервера? Все зависит от производительности приложения. Лучший способ - установить какой-либопрогрессивный бутстрап: используйте рендеринг на стороне сервера, чтобы быстро получить первый осмысленный график (FCP), включая некоторые требуемые минимальные объемыJavaScript, попробуйте сделать интерактивное время (TTI) рядом с рисунком первой значимой фигуры. еслиJavaScriptвыполнить вFCPКогда станет слишком поздно, браузер проанализирует, скомпилирует и выполнитJavaScriptВремяЗаблокируйте основной поток, тем самым ослабляяинтерактивность веб-сайта или приложения.

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

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

Проанализируем текущие механизмы рендеринга:

  • Полная визуализация на стороне клиента (CSR)

    Вся логика, рендеринг и запуск выполняются на стороне клиента. Результат обычноTTIа такжеFCPИнтервал между ними увеличен. Поскольку все приложение должно быть запущено на клиенте для рендеринга чего-либо, приложение работает довольно вяло. как правилоSSR быстрее, чем CSR. Но для многих приложенийCSRявляется наиболее распространенной реализацией.

    прикрепить традициюCSRСхема связи:

    image-20211031150627907
  • Полностью серверный рендеринг (SSR)

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

    FPа такжеFCPРазрыв обычно невелик, запуск логики страницы и рендеринга на сервере позволяет избежать отправки клиенту большой суммы.JavaScript, что помогает добиться быстрой интерактивности (TTI). и можетHTMLдля потоковой передачи в браузер и немедленного отображения страницы. Однако для синтаксического анализа требуется больше времени, в результате чего приходит первый байт (TTFB) браузеры, и мы не используем преимущества скорости отклика и других богатых функций современных приложений.

  • Создание статического сайта (SSG)

    Генерация статического сайта похожа на рендеринг на стороне сервера, но вво время сборкиа не впо запросуОтрисовка страницы. В отличие от серверного рендеринга, потому что страницу не нужно генерировать динамически.HTML, поэтому он также поддерживает стабильно быстрое время до первого байта (TTFB).通常,静态呈现意味着提前为每个URLсоздать отдельныйHTMLдокумент. с предварительно сгенерированнымHTMLотзывчивые, статические рендереры могут быть развернуты на несколькихCDN, чтобы воспользоваться преимуществом пограничного кэширования. Таким образом, мы можем быстро отобразить страницу, а затем получить ее заранее для последующих страниц.SPAРамка. Но этот подход подходит только для сценариев, где генерация страницы не зависит от ввода пользователя.

    image-20211107194256621
  • Рендеринг на стороне сервера (SSR + CSR) с (ре)гидратацией

    Hydrationперевести как水合. Вы не ошеломлены! говорить на английском,Процесс повторного рендеринга HTML, который когда-то был визуализирован, называется гидратацией.

    Запросы навигации (такие как полная загрузка или перезагрузка страницы) обрабатываются сервером, который отображает приложение какHTML,ПотомJavaScriptи данные для рендеринга, встроенные в сгенерированный документ. В идеале, так же быстро, как рендеринг на стороне сервера.FCP, а затем с помощью метода, называемого(Re)HydrationТехника снова рендерится на клиенте修补.

    с помощьюReact, мы можемна узлеиспользоватьReactDOMServerмодуль, затем вызовитеrenderToStringметод для создания компонентов верхнего уровня как статическихHTMLнить. использоватьVue, мы можем использоватьvue-server-renderer,передачаrenderToStringспособVueЭкземпляры отображаются какHTML.

    Этот подход также имеет свои недостатки, мы сохраняем полную гибкость клиентской стороны, обеспечивая более быстрый рендеринг на стороне сервера, ноFCPа такжеTTIИнтервал между ними также увеличивается, иFIDтакже увеличилось.Увлажнение очень дорого, с гидратациейSSRСтраницы часто выглядят обманчиво и интерактивны, но выполняются на стороне клиента.JSи перед присоединением обработчика событий,Не могу ответить на ввод.

    img

    Уведомлениеbundle.jsЭто по-прежнему полный код CSR, и страница действительно интерактивна после выполнения этих кодов. Поэтому в этом режимеFP (первая краска)Несмотря на улучшение,TTI (время до интерактивности)Может быть медленнее, потому что страница не может реагировать на пользовательский ввод (заблокировано выполнением кода JS), пока не завершится вторичный рендеринг клиента.

    Для проблемы неотзывчивого взаимодействия, вызванного вторичным рендерингом, возможным направлением оптимизации является инкрементный рендеринг (например,React Fiber) и прогрессивный/частичный

  • Потоковая передача на стороне сервера (SSR + CSR) с прогрессивной (ре)гидратацией

    Чтобы свести к минимумуTTIа такжеFCPинтервал, мы можем инициировать несколько запросов и отправлять содержимое пакетами по мере его создания (возвращаемое тело ответапоток). Так что нам не нужно ждать полногоHTMLстрок, а также сокращает время до первого байта (TTFB).

    существуетReact, мы можем использоватьrenderToNodeStreamвместоrenderToStringпередать ответ иHTMLОтправляйте кусками. существуетVue, мы можем использоватьrenderToStreamреализовать каналы и потоки. вместе сReact Suspenseприходит, мы также можем использоватьАсинхронный рендерингдля достижения той же цели.

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

    дляVue,когдаИспользуйте гидратацию во время взаимодействия с пользователемили использоватьvue-lazy-hydration(вы можете определить, когда компонент виден или когда компонент активируется при определенном взаимодействии с пользователем) может уменьшитьSSRВремя взаимодействия приложения. вы также можетеЧастичная гидратация с Preact и Next.js.

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

    1. проситьHTML, сервер сначала возвращает скелетный экранHTML, затем верните нужные данные илиHTMLи, наконец, закрыть запрос.
    2. проситьjs,jsПосле возвращения и выполнения вы можете взаимодействовать.
    image-20211031151026287
  • Предварительный рендеринг на стороне клиента

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

    используется в процессе сборкиrenderToStaticMarkupметод вместоrenderToStringметод, который генерируетdata-reactidСтатическая страница с такими атрибутами, главная страница этой страницыJSи последующие маршруты, которые могут быть использованы, будут предварительно загружены. Другими словами, какой была страница, когда она была упакована, на что похожа предварительная визуализация. Подожди покаJSЗагрузите и завершите выполнение, если на странице есть обновление данных, то страница будет отрисована снова. Это создает иллюзию задержки данных.

    оказатьсяTTFB(第一字节到达时间)а такжеFCPменьше времени и корочеTTIа такжеFCPИнтервал между. Этот метод нельзя использовать, если ожидаемое содержимое изменится. Кроме того, вы должны знать все заранее.URLдля создания всех страниц.

    image-20191231113759430

  • Трехсторонний изоморфный рендеринг

    если вы можете использоватьService Worker, также может пригодиться трехсторонний рендеринг. Этот метод относится к: рендерингу начальной страницы с потоковым сервером и т. д.Service WorkerПосле загрузки взять на себяHTMLработа по рендерингу. Это обеспечивает актуальность кэшированных компонентов и шаблонов, а также позволяет использовать одностраничную навигацию в стиле приложения для предварительного рендеринга новых представлений в том же сеансе. При наличии на сервере, клиентских страницах иService WorkerЭтот метод работает лучше всего, когда между ними используется один и тот же шаблон и код маршрутизации.

    image-20211024170611954

Трехсторонний рендеринг, рендеринг одним и тем же кодом в трех местах: на сервере, в DOM или в сервис-воркере.

image-20211024170857785

Технический спектр от рендеринга на стороне сервера до рендеринга на стороне клиента.

Что касается того, как выбрать, вот несколько незрелых предложений:

  1. правильноSEOтребования не высоки, и в то же время对操作需求比较多проектов, таких как некоторые фоновые системы управления, рекомендуется использоватьCSR. потому что только после казниbundleПосле этого со страницей можно взаимодействовать, а элементы можно только видеть, но нельзя взаимодействовать, что не имеет большого значения, иSSRПринесет дополнительные затраты на разработку и обслуживание.
  2. если страница无数据,или纯静态страницу, рекомендуется использоватьSSG. Поскольку это способ создания страницы путем предварительного просмотра пакета, он не увеличивает нагрузку на сервер.
  3. правильноSEOЕсли существует относительно большой спрос и одновременно много запросов данных страницы, рекомендуется использоватьSSR.

Правильно установить заголовки кэша HTTP

тщательно проверитьexpires,max-age,cache-controlи другиеHTTPПравильно ли установлен заголовок кеша. В общем, ресурсы можно найти вна короткое время или на неопределенный сроккешируется, и его версия может быть изменена в URL-адресе, если это необходимо.

использоватьCache-control: immutable, для тела ответане меняется со временем. Если срок действия ресурса не истек, он не изменится на сервере, поэтому браузер не будет отправлять проверку кеша (например:If-None-MatchилиIf-Modified-Since) для проверки обновлений, даже если пользователь обновляет страницу.

мы можем использоватьCache-ControlЗаголовок ответа указывает время кэширования, например.Cache-Control: max-age=60. Через 60 секунд браузер повторно загрузит ресурс, но из-за этого страница будет загружаться медленнее. Итак, мы можем сделать это, используяstale-while-revalidateчтобы избежать этой проблемы, например:Cache-Control: max-age=60, stale-while-revalidate=3600То есть этот кеш «свежий» в течение секунд 60. В час с 60 секунд до 3660 секунд, хотя срок действия кеша истек, вы все равно можете использовать этот кеш с истекшим сроком действия напрямую и одновременно выполнять асинхронные обновления в 3660 секунд. После этого он полностью истекает, поэтому требуется традиционное получение ресурса синхронизации.

В июне 2019 года по июль,Chromeа такжеFirefoxначать правильноHTTP Cache-Control stale-while-revalidateДа, это может улучшить последующие загрузки страниц, поскольку ресурсы с истекшим сроком действия больше не будут блокировать рендеринг. Эффект:Для повторно подключенных просмотров RTT равен нулю..

RTT: Это аббревиатура от Round Trip Time, с точки зрения непрофессионала, это время для связи туда и обратно.

Также следите за тем, чтобы не отправлятьненужные заголовки(Напримерx-powered-by,pragma,x-ua-compatible,expiresи т. д.) и убедитесь, что сообщение содержитПолезные заголовки, связанные с безопасностью и производительностью(Такие какContent-Security-Policy,X-XSS-Protection,X-Content-Type-OptionsЖдать). Наконец, обратите внимание, что в одностраничных приложенияхСтоимость выполнения запросов CORS.

Оптимизация передачи

Загружаются ли библиотеки JavaScript асинхронно?

Когда пользователь запрашивает страницу, браузер получаетHTMLструктураDOM,ПолучатьCSSструктураCSSOM, затем, сопоставивDOMа такжеCSSOMСоздайте дерево рендеринга. Но пока вам нужно разобратьJavaScript, браузер задерживает отображение страницы. Поэтому, как разработчики, мы должны явно указать браузеру, что нужно немедленно начать рендеринг страницы. можно добавить в скрипт, добавивHTMLсерединаdeferа такжеasyncАтрибуты.

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

Кроме того, чтобы ограничить влияние сторонних библиотек и скриптов, обратите особое внимание: например, на кнопки социальных сетей.SDKа такжеiframeИспользование меток, таких как карты. можно использоватьбиблиотека ограничения размеране допуститьJavaScriptРаздувание библиотеки: если случайно добавлена ​​большая зависимость, инструмент уведомит вас и выдаст ошибку.

Ленивая загрузка изображений с помощью IntersectionObserver

Вообще говоря, мы должны сделать ленивую загрузку всех компонентов, потребляющих производительность, таких как большиеJavaScript,видео,iframe, виджеты и, возможно, изображение для загрузки. Например:Native lazy-loadingможет помочь нам лениво загружать изображения иiframe.

Native lazy-loadingэто браузерimgэтикетки иiframeТеги поддерживают встроенные функции ленивой загрузки, используйтеloading="lazy"Достаточно грамматической разметки.

По тесту: нужно быть вimgВидимые настройки в ярлыкеwidthа такжеheightЛенивая загрузка поддерживается.

image-20211101131403567

Самый эффективный способ ленивой загрузки скриптов — использоватьIntersection Observer API,этоAPIЦелевой элемент можно наблюдать асинхронно с элементом-предком или документом.viewportПересечение между изменениями. Нам нужно создатьIntersectionObserverObject, он получает callback-функцию и соответствующие параметры, после чего мы добавляем цель наблюдения. следующим образом

let options = {
  root: document.querySelector('#scrollArea'),
  rootMargin: '0px',
  threshold: 1.0
}

let observer = new IntersectionObserver(callback, options);

let target = document.querySelector('#listItem');
observer.observe(target);

// threshold = 1.0 意味着 target 元素完全出现在 root 选项指定的元素中可见时,回调函数将会被执行。

Функция обратного вызова выполняется, когда цель становится видимой или невидимой, поэтому, когда она иviewportПри пересечении мы можем выполнить какое-то действие до того, как элемент станет видимым. Итак, мы можем пройтиrootMargin(поле вокруг корня) иthreshold(Число или набор чисел, представляющих процент видимости цели) Детальный контроль над тем, когда вызывается обратный вызов наблюдателя.

постепенно загружать изображения

Мы можем сделать это с помощьюпрогрессивная загрузка изображенийПоднимите эффект ленивой загрузки на новый уровень. а такжеFacebook,Pinterestа такжеMediumТочно так же мы можем сначала загрузить некачественные или даже размытые изображения, а затем, по мере загрузки страницы, использоватьТехнология LQIP (заполнитель изображения низкого качества)Замените их качественными полными версиями.

При ленивой загрузке мы можем использовать готовые библиотеки:lozad.js

Приведите простейший демонстрационный код:

<img data-src="https://assets.imgix.net/unsplash/jellyfish.jpg?w=800&h=400&fit=crop&crop=entropy"
          src="https://assets.imgix.net/unsplash/jellyfish.jpg?w=800&h=400&fit=crop&crop=entropy&px=16&blur=200&fm=webp"
>
<script>
    function init() {
        var imgDefer = document.getElementsByTagName('img');
        for (var i=0; i<imgDefer.length; i++) {
            if(imgDefer[i].getAttribute('data-src')) {
                imgDefer[i].setAttribute('src',imgDefer[i].getAttribute('data-src'));
            }
        }
    }
    window.onload = init;
</script>

Вы отправили критический CSS?

Чтобы браузер начал рендеринг страницы как можно скорее, включите только все необходимое для рендеринга видимой части в верхней части страницы.CSSназывается "Критический CSS". Вставьте его в<head>теги, тем самым сокращая передачу запросов туда и обратно. из-зафаза медленного старта TCPРазмер обмениваемых пакетов ограничен, поэтому ключCSSне должен превышать размер14KB. (Это конкретное ограничение не применяетсяTCP BBR, но всегда полезно расставлять приоритеты для критически важных ресурсов и загружать их раньше). Если это ограничение превышено, браузеру потребуются дополнительные обращения, чтобы получить больше стилей.

Вот краткое введение к тому, что было сказано вышемедленный старта такжеTCP BBR, кстати, вкратце опишу несколько алгоритмов TCP для избежания перегрузок

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

  1. алгоритм медленного старта

Идея алгоритма медленного старта состоит в том, чтобы добавитьОкно перегрузки, обозначаемый какcwnd.

Окно перегрузки относится к максимальному MSS, которое может быть отправлено при получении ACK от однорангового узла (Максимальный размер сегмента)количество. Окно перегрузки — это значение, поддерживаемое отправителем, и оно не будет объявлено партнеру, как окно получателя (rwnd).Размер окна отправителя равен минимуму cwnd и rwnd.. Начальное значение текущего окна перегрузки Linux — 10 MSS.

Алгоритм медленного старта, после каждого RTT cwnd становится в два раза больше, чем раньше. Отправитель начинает отправлять сегменты initcwnd (Предположим, что окно получателя не имеет ограничений) и дождитесь ACK (То есть символ подтверждения.При передаче данных - символ управления передачей, посылаемый принимающей станцией на передающую станцию. Указывает, что отправленные данные были подтверждены для получения без ошибок.). Когда этот ACK получен, окно перегрузки расширяется доinitcwnd*2, то есть можно отправитьinitcwnd*2сегмент. Когда ACK для этого исходящего сегмента получен, окно перегрузки продолжает расширяться доinitcwnd*4, что является экспоненциально возрастающей зависимостью.

image-20211102150656462

  1. Алгоритм предотвращения перегрузок

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

Когда cwnd ssthresh, окно перегрузки использует алгоритм предотвращения перегрузки и растет линейно.

Алгоритм предотвращения перегрузки увеличивает окно перегрузки после каждого RTT.initcwnd.

Когда возникает перегрузка (тайм-аут или получен дубликат подтверждения), RFC5681 считает, что ssthresh нужно установить на половину неподтвержденных пакетов, но не менее чем на два MSS. также,Если перегрузка вызвана тайм-аутом, для cwnd устанавливается значение initcwnd..

Повторная передача с течением времени оказывает серьезное влияние на производительность передачи. Причины: 1. В РТО (Период ожидания повторной передачи, то есть с момента отправки данных, повторная передача выполняется по истечении этого времени.) этап не может передать данные, что эквивалентно потере периода времени 2. Резкое сокращение окна перегрузки эквивалентно тому, что последующая передача будет намного медленнее.

image-20211102152618349

  1. Алгоритм быстрой ретрансляции

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

Зачем нужно делать до 3? Это связано с тем, что сетевые пакеты иногда не по порядку, а не по порядку пакеты будут вызывать повторные подтверждения, но повторная передача не требуется для не по порядку. Так как общее расстояние вне очереди не слишком отличается, например, пакет № 2 может бежать за пакетом № 4, но вряд ли он будет бежать за пакетом № 6, поэтому его можно избежать. в значительной степени, ограничив его до 3 или более.Быстрая повторная передача запускается из-за нарушения порядка.

image-20211102153509995

Кроме того, есть еще одна проблема, если мы теряем оба пакета 2 и 3, но последние 4, 5, 6 и 7 принимаются нормально, а ACK 2 срабатывает три раза. В это время, если отправитель получает несколько дубликатов ACK, он считает, что произошла потеря пакета, и TCP будет повторно передавать последующие пакеты, начиная с последнего подтвержденного пакета. Таким образом, пакеты, которые были переданы правильно, могут быть отправлены повторно, что снижает производительность TCP. Чтобы исправить эту ситуацию, SACK (выборочное подтверждение), используя опцию SACK, можно сообщить отправителю, какие данные были получены, а отправитель будет знать, какие данные потеряны после получения этой информации, а затем немедленно повторно передать потерянную часть.

image-20211102154345754
  1. Алгоритм быстрого восстановления

Если быстрая повторная передача происходит во время фазы перегрузки, нет необходимости обрабатывать окно перегрузки, как повторную передачу по тайм-ауту.Учитывая, что если сеть перегружена, она не получит несколько дублирующих подтверждений, поэтому отправитель теперь думает, что сеть не может быть перегруженным. . Таким образом, вместо выполнения алгоритма медленного запуска в это время установите для cwnd значение после того, как ssthresh уменьшится вдвое, а затем выполните алгоритм предотвращения перегрузки, чтобы медленно увеличить cwnd. Этот процесс называетсябыстрое восстановление.

image-20211102162546985

Суммировать:

  • Повторные передачи по тайм-ауту оказывают наибольшее влияние на производительность, поскольку во время RTO данные не могут быть переданы, а окно перегрузки резко сокращается. Таким образом, вы должны попытаться избежать повторной передачи по тайм-ауту.

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

  • При использовании алгоритма быстрого восстановления алгоритм медленного запуска используется только при установленном TCP-соединении и тайм-ауте сети.

TCP BBR — это новый алгоритм управления перегрузкой TCP, опубликованный Google, который широко использовался в Google и был официально выпущен в версии Linux 4.9.

Название BBR на самом деле является аббревиатурой от узкой полосы пропускания и времени распространения туда и обратно (полоса пропускания узкого места и время распространения туда и обратно), что указывает на основной рабочий механизм BBR:Контроль перегрузки осуществляется путем обнаружения двух показателей, пропускной способности и RTT.Основные особенности алгоритма BBR заключаются в следующем:

  1. BBR не учитывает потерю пакетов, потому что потеря пакетов (в наши дни) не обязательно является признаком перегрузки сети.
  2. BBR полагается на обнаруженную пропускную способность в реальном времени и RTT для определения размера окна перегрузки: размер окна = пропускная способность * RTT.

Попробуйте перекомпоновать свои правила CSS

согласно сCSS and Network Performanceисследование, согласно запросу СМИCSSРазделение файлов может в определенной степени улучшить производительность нашей страницы. Таким образом, браузер будет извлекать критический CSS с высоким приоритетом и обрабатывать все остальное с низким приоритетом.

Например:

<link rel="stylesheet" href="all.css" />

Мы помещаем все css в один файл, и браузер будет обрабатывать его следующим образом:

image-20211102164235989

<link rel="stylesheet" href="all.css" media="all" />
<link rel="stylesheet" href="small.css" media="(min-width: 20em)" />
<link rel="stylesheet" href="medium.css" media="(min-width: 64em)" />
<link rel="stylesheet" href="large.css" media="(min-width: 90em)" />
<link rel="stylesheet" href="extra-large.css" media="(min-width: 120em)" />
<link rel="stylesheet" href="print.css" media="print" />

когда мы разделим его наmediaПри запросе браузер будет выглядеть так:

image-20211102164307446

Избегайте использования в файлах CSS@import, как это работает, влияет на параллельные загрузки для браузеров. Однако в настоящее время мы используем большеscss,lessони будут@importФайлы включаются непосредственно вCSS, без доп.HTTPпросить.

Кроме того, не<link rel="stylesheet">помещатьasyncперед фрагментом кода. еслиJavaScriptСкрипты не зависят от стилей, рассмотрите возможность размещения асинхронных скриптов поверх стилей. Если есть зависимость, можноJavaScriptна две части и поместите их вCSSобе стороны для загрузки.

Динамический стиль также может быть дорогостоящим, хотя потому чтоReactПроизводительность хорошая, поэтому обычно это происходит только при параллельном рендеринге большого количества составных компонентов. согласно сThe unseen performance costs of modern CSS-in-JS libraries in React appsисследования вproductionКогда режим включен, пройтиCSS-in-JSСоздаваемые компоненты могут быть меньше обычныхReactРендеринг компонентов занимает в два раза больше времени. Итак, применяяCSS-in-JS, вы можете использовать следующие решения для повышения производительности вашей программы:

  1. Не перекомбинируйте вложенные компоненты стиля: это позволяетReactМеньше компонентов для управления и более быстрый рендеринг
  2. Отдавайте предпочтение «статическим» компонентам:НемногоCSS-in-JSбиблиотека будет в вашемCSSнет темы зависимости илиpropsоптимизировать его выполнение. Чем более «статичными» являются ваши шаблоны тегов, тем большеCSS-in-JSСреда выполнения, скорее всего, будет выполняться быстрее.
  3. Избегайте недопустимых повторных рендеров React: Убедитесь, что рендерите только при необходимости, это позволяет избежатьReactа такжеCSS-in-JSРабота библиотеки во время выполнения.
  4. Может ли библиотека CSS-in-JS с нулевым временем выполнения работать для вашего проекта?: Иногда мы выбираемJSнаписано наCSS, потому что он предоставляет отличные возможности для разработчиков, и нам не нужен доступ к дополнительнымJS API. Если вашему приложению не нужна поддержка тем, вам не нужно использовать множество сложныхCSS props, то нулевое время выполненияCSS-in-JSБиблиотеки могут быть хорошим вариантом. Используя библиотеку с нулевым временем выполнения, вы можетеbundleНа 12 КБ меньше в файле, потому что большая частьCSS-in-JSБиблиотеки имеют размер от 10 КБ до 15 КБ, в то время как нет библиотек времени выполнения, таких какlinaria) меньше 1 КБ.

Соединения для прогрева для более быстрой передачи

использоватьподсказка ресурсасэкономить время:

dns-prefetch: подсказывает браузеру, что ресурс требует поиска DNS и установления связи по протоколу, прежде чем пользователь щелкнет ссылку.

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

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

preload: указывает браузеру загрузить ресурс, поскольку он понадобится позже во время текущей навигации.

Потом я узнал, что здесь чего-то не хватает.prerender? (Рекомендуется, чтобы браузер заранее загружал связанный ресурс, и рекомендуется отображать предварительно загруженный контент за пределами экрана, чтобы при необходимости его можно было быстро представить пользователю.)

Но это действительно сложно использовать на практике. Поскольку это заставляет браузер не только извлекать ресурс, но и предварительно обрабатывать ресурс, аHTMLДругие ресурсы, от которых зависит страница, например<script>,<style>Ресурсы, требуемые другими страницами, также могут быть обработаны. Предварительная обработка будет отложена в разной степени в зависимости от браузера или текущего состояния компьютера и сети. Например, выбираются разные политики или операция блокируется в зависимости от использования ЦП, ГП и памяти, а также идемпотентности запрошенной операции.

Так что неудивительно, что он устарел. ноChromeИсходя из этого, команда предложилаМеханизм предварительной выборки NoState. В Chrome версии 63 и вышеChromeуже поставилprerenderрассматривается какNoState Prefetch, ведет себя какprerenderТакой же,NoState Prefetchбудет приобретать ресурсы заранее; но сprerenderОтличие в том, что он не выполняетсяJavaScript, и не обрабатывает какую-либо часть страницы заранее.NoState PrefetchИспользуется только около 45 МБ памяти, а приоритет обработки подресурсов только空闲(IDLE)уровень. Начиная с Chrome 69,NoState PrefetchПросто добавьте заголовок запроса ко всем запросамPurpose: Prefetch, чтобы они отличались от обычного просмотра.

На самом деле мы будем использовать по крайней мереpreconnectа такжеdns-prefetch, будет использоваться с осторожностьюprefetch, preloadа такжеprerender. Предупреждение: его следует использовать только в том случае, если вы уверены, какие ресурсы понадобятся пользователю дальше (например, процесс покупки, процесс регистрации).prerender.

даже использоватьpreconnectа такжеdns-prefetch, браузеры также ограничивают количество параллельно подключенных хостов, поэтому их лучше отсортировать по приоритету.

использоватьresource hintВероятно, это самый простой способ повысить производительность, и он дает вам прирост производительности.

Ниже приведена сравнительная таблица приоритета запроса ресурсов на каждом этапе:

图片

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

Вы также можетеДинамически загружать JavaScript, эффективное выполнение ленивой загрузки. Кроме того, поскольку<link rel="preload">приниматьmediaсвойства, поэтому может основываться на@mediaправила запросаВыборочно расставляйте приоритеты ресурсов.

наконец,Есть несколько проблем, о которых нужно знать:

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

preloadможно хорошо справитьсяHTTPкеш: если ресурс уже находится вHTTPВ кеше сетевой запрос никогда не будет отправлен.

следовательно,preloadДля ресурсов, которые впоследствии запускаются для загрузки, напримерbackground-imageЗагруженные изображения, встроенный критический CSS (илиJavaScriptJavaScriptHTMLpreloadpreload

Early HintHTMLpreloadPriority Hints

Nov-02-2021 20-25-58

preloadascrossorigin

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

CSSwill-change

will-change: auto
will-change: scroll-position
will-change: contents
will-change: transform
will-change: opacity
will-change: left, top

will-change: unset
will-change: initial
will-change: inherit

CSSCPUCSSGPU

CSSGPU

  • transform
  • opacity
  • filter
  • will-change

GPUwill-changeGPU

    • HMTLAST
    • rem -> pxwhite -> #FFFFFF

    • CSSDOM 树render 树

    • dispy:nonerender
    • GPU

    • GPU

图片描述

построить дерево слоевОчень важно, давайте сосредоточимся на этом снова. браузер изDOM 树Для преобразования качества изображения в экранную графику необходимо преобразовать древовидную структуру в структуру слоев. Вот 4 пункта:

  1. РендерОбъект

    ОдинDOMУзел соответствует объекту рендеринга, а объект рендеринга поддерживаетDOMструктура дерева. Объект рендеринга умеет рисоватьDOMСодержимое узла, которое рисуется путем выдачи необходимых команд рисования в GraphicsContext.DOMузел.

  2. РендерСлой

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

    • documentэлемент
    • position: relative | fixed | sticky | absolute
    • opacity < 1
    • will-change | fliter | mask | transform != none | overflow != visible
  3. Графический слой

    Графический слой — это модель слоя, отвечающая за генерацию конечной представляемой графики контента.Он имеет графический контекст (GraphicsContext), а графический контекст отвечает за вывод растрового изображения слоя. Растровые изображения, хранящиеся в общей памяти, будут использоваться в качестве текстур (Думайте об этом как о растровом изображении, которое перемещается из основной памяти в память изображений.)загрузить наGPU, и, наконец, поGPUОбъедините несколько растровых изображений и нарисуйте их на экране.В этот момент наша страница отображается на экране.

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

  4. Композитный слой

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

    Итак, каким особым условиям должен соответствовать слой рендеринга, прежде чем его можно будет повысить до составного слоя? Вот несколько распространенных случаев:

    • 3D transforms
    • video,canvas,iframe
    • opacityанимация перехода
    • position: fixed
    • will-change
    • animationилиtransitionуже настроенopacity,transform,fliter,backdropfilter

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

  • Допустим, у нас есть дваabsoluteпозиционируетсяdivперекрываются на экране, согласноz-indexотношения, один изdivОн будет «накрыт» поверх другого.
image-20211104165440485
  • В это время, если мы дадимz-index: 3настраиватьtransform: translateZ(0), пусть браузер продвинет его досинтетический слой. После подъемаz-index: 3Этот составной слой будетdocuemntвыше, то логичноz-index: 3будет вz-index: 5Выше мы установилиz-indexБудет произвольное отношение перекрытия.
image-20211104165908499
  • Чтобы исправить этот неправильный порядок перекрытия, браузер должен сделать слой рендеринга, который должен «перекрывать» его, одновременно продвигаться к слою композиции. это называетсяНеявный синтез

После того, как слой рендеринга будет повышен до составного слоя, это принесет нам много преимуществ:

  1. Растровое изображение композитного слоя будет переданоGPUсинтетический, чемCPUОбработка намного быстрее;
  2. Когда вам нужно перерисовать, вам нужно перерисовать только себя, не затрагивая другие слои;
  3. После того, как элемент переведен в составной слой,transformа такжеopacityОн не вызовет перерисовку, если это не составной слой, он все равно вызовет перерисовку.

Конечно, неправильное использование чего-либо будет иметь побочные эффекты, такие как:

  1. Окрашенные слои необходимо перенести наGPU, количество и размер этих слоев достигают определенной величины, что может привести к очень медленной передаче, что, в свою очередь, может привести к мерцанию на некоторых бюджетных и средних устройствах;
  2. Неявный синтез склонна к чрезмерным слоям синтеза, каждый из которых занимает дополнительную память, образуявзрыв слоя. ЗанятьGPUи большой объем ресурсов памяти, серьезно снижающий производительность страницы. А память — ценный ресурс на мобильных устройствах, и использование слишком большого объема памяти может привести к сбою в работе браузера, что сделает оптимизацию производительности контрпродуктивной.

Хорошо, примерно зная принцип рендеринга браузера, давайте посмотрим, как на практике уменьшить перекомпоновку и перерисовку:

  1. всегда на картинкеУстановить свойства ширины и высоты: Браузер выделяет кадр и резервирует место по умолчанию, и после загрузки последующих ресурсов изображения перекомпоновка не требуется.
  2. Избегайте множественных модификаций: например, нам нужно изменитьDOMизheight/width/marginТри свойства, в это время мы можем пройтиcssTextмодифицировать, а неdom.style.heightмодифицировать.
  3. Массовое редактирование DOM: поставитьDOMСкройте или клонируйте его и измените, а затем замените, но теперь браузер будет использовать очередь для хранения нескольких модификаций для оптимизации. Сфера применения этого не столь широка.
  4. Вне потока документов: для некоторых частых изменений, таких как анимацияDOM.Вы можете использовать абсолютное позиционирование, чтобы вывести его из потока документов, чтобы избежать частого перекомпоновки родительских элементов.

Оптимизация сети

Включено ли сшивание OCSP?

пройти черезВключить сшивание OCSP на сервере, что может ускоритьTLSСкорость рукопожатия. «Протокол статуса онлайн-сертификата» (OCSP) — это список отозванных сертификатов (CRL) альтернативный протокол. Оба протокола используются для проверкиSSLБыл ли отозван сертификат. но,OCSPПротокол не требует, чтобы браузеры тратили время на загрузку и поиск списков информации о сертификатах, тем самым сокращая время, необходимое для рукопожатий.

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

  • Протокол статуса онлайн-сертификата (OCSP): Чтобы решить проблему больших одиночных файлов и высокой задержки, было введено новое решение OCSP. Браузер запрашивает статус отзыва сертификата у онлайн-сервера OCSP (также известного как сервер ответов OCSP), и сервер OCSP отвечает. Такой подход позволяет избежать проблемы с задержкой обновления CRL. Недостатками этого метода являются:

    1. Каждый раз, когда браузер создает запрос HTTPS, ему необходимо подключиться к серверу CA OCSP для проверки.Сеть между IP-адресом браузера и сервером CA OCSP не является гладкой. Более того, проверка OCSP имеет сетевой ввод-вывод, который занимает много времени, что серьезно влияет на работу пользователя с браузером, обращающимся к серверу.
    2. Когда браузер отправляет серийный номер HTTPS-сертификата сервера на сервер CA OCSP, он также раскрывает конфиденциальность пользователя и раскрывает URL-адрес, к которому обращается пользователь, серверу CA OCSP.
  • Сшивание OCSP: OCSP Stapling устраняет недостатки CRL и OCSP и переносит процесс вызова OCSP Server для получения статуса отзыва сертификата на веб-сервер.Веб-сервер может не только напрямую запрашивать информацию OCSP, но и избегать网络访问限制,OCSP服务器离用户的物理距离较远Вы также можете кэшировать ответ на запрос и использовать его для других браузеров. Поскольку ответ OCSP также подписан закрытым ключом CA RSA, не нужно беспокоиться о подделке.

    1. Решена проблема медленного доступа

    2. Решена проблема утечки конфиденциальности пользователей

Правильно ли он оптимизирован для протокола HTTP?

вместе сHTTPSа такжеHTTP/2Популярные, многоHTTP/1.1Стратегия оптимизации того времени не сработала и даже имеет эффект антиоптимизации.

Здесь мы берем каждую версию кстатиHTTPПроведите простой анализ протокола:

  • HTTP/1.0

    • Браузер и сервер поддерживают только кратковременное соединение, и каждый запрос браузера должен установить TCP-соединение с сервером (Стоимость установления TCP-соединения высока, поскольку для этого требуется трехстороннее рукопожатие между клиентом и сервером.), сервер отключает TCP-соединение, как только сервер завершает обработку запроса, сервер не отслеживает каждого клиента и не записывает прошлые запросы
  • HTTP/1.1

    • Конвейерная обработка): предложите конвейерное решение для устранения задержки соединения, сервер может установитьKeep-Aliveзадержать время закрытия соединения, но из-за собственного браузераMax-ConnectionМаксимальный лимит подключений, лимит запросов на подключение под одним и тем же доменным именем (Google Chrome в одном и том же домене ограничен максимум 6 подключениями одновременно) может быть достигнут только путем открытия нескольких доменных имен, что является нашим выбором статического ресурса. .CDNНа или других доменных именах, для повышения скорости загрузки ресурсов. Конвейерные решения требуют внешней и внутренней поддержки, но большинствоHTTPПоддержка агентом конвейерной обработки не является дружественной.
    • Поддерживает только GET/HEAD: Конвейер поддерживает толькоGET / HEADспособ передачи данных, не поддерживаетсяPOSTи другие средства передачи.
    • избыточность информации в заголовке:HTTPне имеет состояния, клиент/сервер может только пройтиHEADИнформация о статусе получения обслуживания данных, которая приводит к большому количеству избыточной информации заголовка, включая информацию заголовка, включая каждый запрос на соединение.COOKIEИнформация и т. Д.
    • Гипертекстовый протокол:HTTP/1.Xпередача по гипертекстовому протоколу. Передача по гипертекстовому протоколу, при отправке запроса выясняет положение начала и конца фрейма данных, убирает лишние пробелы, выбирает оптимальный способ передачи. если используетсяHTTPS, то данные будут зашифрованы, что приведет к некоторой потере скорости передачи.
    • блокировка в начале очереди: Конвейерная обработка — это схема, которая откладывает закрытие соединения.Хотя одновременно могут быть инициированы несколько запросов к серверу,responseвсе еще следоватьFIFOПравила (первым пришел, первым обслужен) возвращаются последовательно. Например, клиент отправляет четыре запроса 1, 2, 3 и 4. Если клиенту не возвращается 1, то 2, 3 и 4 не возвращаются. Это называется "блокировка начала строки". Блокировка очевидна в сценариях с высокой степенью параллелизма и высокой задержкой.
  • HTTP/2.0

    • мультиплексирование: только один доменTCPсоединение, чтобы добиться реальных одновременных запросов, уменьшить задержку и улучшить использование полосы пропускания.
    • сжатие заголовка: клиент/сервер выполняет прогрессивное обновление и обслуживание, используяHPACKСжатие экономит трафик, занимаемый заголовком пакета.
      1. Та же самая информация заголовка не будет отправлена ​​через запрос, и будет использоваться информация заголовка, переданная в предыдущем запросе.
      2. Информация о новом/измененном заголовке будет добавлена ​​кHEAD, оба конца обновляются постепенно.
    • приоритет запроса: Каждый поток имеет собственный приоритет, который может быть указан клиентом. И может сделать управление потоком.
    • Пуш сервера: Например, мы загружаем index.html, также нам могут понадобиться index.js, index.css и другие документы. Традиционный запрос, только если клиент таким образом получит index.html, будет введен для разбора html index.js / index.css, снова запрошенный ресурс будет загружен, но сервер через данные, вы можете протолкнуть продвижение ресурсов к клиенту, чтобы при использовании для прямых вызовов вам не нужно отправлять запрос.
    • бинарный протокол: использует бинарный протокол, разница与HTTP/1.X的Гипертекстовый протокол. Когда клиент (сервер) отправляет (принимает) данные, он будет разгонять данные и отправлять их не по порядку.streamIDID для объединения данных. Бинарные протоколы более эффективны для разбора, более компактны «на проводе» и, что самое главное, менее глючны.

    Здесь добавлено, что HTTP2 не имеет всех преимуществ перед HTTP1.1: потому что HTTP2 помещает несколько потоков HTTP в одно и то же TCP-соединение и следует одному и тому же управлению состоянием потока. Пока первый HTTP-поток заблокирован, последующий HTTP-поток вообще не может быть отправлен, что является «блокировкой начала строки».

  • HTTP/3.0

    использоватьQUICсоглашение, основанное наUDPсоглашение, чтобы избежатьTCPНекоторые недостатки протокола, использованиеTLS1.3БудуHTTPSнужныйRTTдо минимума 0.

    • Недостатки протокола TCP

      • TCP может периодически зависать при передаче данных: Если сегмент с более низким порядковым номером не был получен, даже если были получены другие сегменты с более высоким порядковым номером,TCPСкользящее окно приемника также не будет продолжать обработку. это приведет кTCPПоток на мгновение зависает, а в худшем случае может привести к закрытию соединения, даже если один из всех сегментов не получен. Эта проблема называетсяTCPпотокНачальник линейной блокировки (HoL)

        image-20211107141850885
      • TCP не поддерживает мультиплексирование на уровне потока.:несмотря на то чтоTCPдопускает несколько логических соединений между уровнями приложений, но не позволяетTCPМультиплексирование пакетов в потоке. использоватьHTTP/2Когда браузер может открыть только один с серверомTCPсоединение и использовать одно и то же соединение для запроса нескольких объектов, таких какCSS,JavaScriptи другие документы. При получении этих объектовTCPВсе объекты будут сериализованы в одном потоке. Поэтому и не знаетTCPРазделение сегментов на уровне объекта.

      • TCP создает избыточную связь:TCPРукопожатия соединения имеют избыточные последовательности обмена сообщениями, даже для соединений с известными хостами.

        image-20211107142702865
    • Преимущества протокола QUIC

      • Выберите UDP в качестве базового протокола транспортного уровня.:существуетTCPпостроить новый транспортный механизм поверх него, который унаследуетTCPиз всех перечисленных недостатков. следовательно,UDPэто мудрый выбор. также,QUICпостроен на пользовательском уровне, поэтому при каждом обновлении протокола не требуется никаких модификаций ядра.

      • Мультиплексирование потоков и управление потоком:QUICВведена концепция мультиплексирования потоков по соединениям.QUICПо замыслу он реализует отдельное управление потоком для каждого потока и решает проблему блокировки очереди всего соединения.

      • Гибкий механизм управления перегрузкой:TCPМеханизм контроля заторов является жестким. Каждый раз, когда протокол обнаруживает перегрузку, он уменьшает размер окна перегрузки наполовину. Напротив,QUICУправление перегрузкой спроектировано так, чтобы быть более гибким и может более эффективно использовать доступную полосу пропускания сети, что приводит к повышению пропускной способности.

      • улучшенная обработка ошибок:QUICИспользуйте улучшенные механизмы восстановления после потерь и прямое исправление ошибок для лучшей обработки ошибочных пакетов. Эта функция полезна для пользователей, которые имеют доступ к Интернету только через медленные беспроводные сети, которые часто имеют высокий уровень ошибок при передаче.

      • более быстрое рукопожатие:QUICиспользовать то же самоеTLSМодули надежно соединены. Однако сTCPразница в том,QUICМеханизм рукопожатия оптимизирован, чтобы избежать избыточного обмена протоколами каждый раз, когда устанавливается связь между двумя известными одноранговыми узлами.

        image-20211107142820199

Вот две формулы, чтобы увидеть сравнение между HTTP/3 и HTTP/2 в сочетании с HTTPS, чтобы дать вам более интуитивное представление, и конкретные детали не будут кратко описаны. Ведь темы этой статьи здесь нет, если вам интересно, вы можете подробно рассказать о ней позже.

Под HTTP/2: Сумма времени связи HTTPS = время соединения TCP + время соединения TLS + время транзакции HTTP = 1,5 RTT + 1,5 RTT + 1RTT = 4 RTT

Под HTTP/3: при первом подключении QUIC использует TLS1.3, для которого требуется 1RTT, один запрос данных HTTP и всего 2RTT. Идентификатор сеанса используется непосредственно при повторном подключении, повторная проверка TLS не требуется, поэтому требуется только 1RTT.

ОК, наверное понялHTTPПосле характеристик версии протокола давайте посмотрим на текущий мейнстрим.HTTP2 + HTTPSВ эпоху , какие стратегии оптимизации устарели или вообще анти-оптимизация?

  1. уменьшить количество запросов:HTTP/1.1Из-за «блокировки головы очереди» мы обычно используем такие методы, как слияние ресурсов, объединение файлов (изображения спрайтов и т. д.), чтобы уменьшить количество запросов. но вHTTP/2Нам нужно уделять больше внимания настройке кеша веб-сайта, передавать легкие, мелкозернистые ресурсы и обеспечивать независимое кэширование и параллельную передачу.
  2. Мультидоменное хранилище:HTTP/1.1Поскольку у браузеров есть ограничение на максимальное количество подключений, мы будем распределять ресурсы по разным доменным именам, чтобы увеличить максимальное количество подключений. но вHTTP/2В домене только одна ссылка, поэтому нам не нужно хранить несколько доменных имен, а хранение нескольких доменных имен даже вызовет дополнительныеTLSпотреблять.

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

Уменьшите размер заголовка запроса, распространенная ситуацияCookie. Например, на нашем основном сайте (например:www.test.com) хранит многоCookie,нашCDNдоменное имя(cdn.test.com) совпадает с нашим основным доменом. В этот раз, когда мы перейдем к запросу, к нему будет прикреплен.test.comпод доменомCookie. и этиCookieдляCDNБесполезно и увеличит размер пакета нашего запроса. Таким образом, мы можем поставитьCDNДоменное имя отдельно от основного домена, например: Taobao (https://www.taobao.com)изCDNДоменhttps://img.alicdn.com.

Суммировать

инструмент оптимизации

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

PageSpeed InsightsЭлементы, которые помогают нам просматривать веб-сайтRUMВ то же время он укажет на недостатки оптимизации веб-сайта и предоставит предложения по оптимизации.

pagespeed_insights__url

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

webpagetest (1)

Аварийный план

Список огромен, и на выполнение всех оптимизаций может уйти много времени. Итак, что бы вы сделали, если бы у вас было очень ограниченное количество времени для оптимизации? Давайте сконденсируем его в15 простых пунктов.

  1. Установите соответствующие цели, основанные на практическом опыте. Разумная цель состоит в том, чтобы визуализировать видимую область 1s, страница отображается 3s, время работы слабой сети 3G 5s, Время до взаимодействия (TTI) для повторных посещений 2s.
  2. Подготовьте важный CSS для верхней части страницы и вставьте его на страницу. дляCSS / JS, максимальный размер файла ключа170 КБ в сжатом видеВнутри.
  3. Извлекайте, оптимизируйте и лениво загружайте как можно больше сценариев, выбирайте облегченные альтернативы (например, использованиеDayJsзаменятьMomentJs) и ограничить влияние сторонних скриптов.
  4. только иметь<script type="module">а такжемодуль/номодульный режимСтарые версии браузеров предоставляют устаревший код.
  5. попробуй перегруппироватьсяCSSправило.
  6. Добавить подсказки ресурсов (resource hints) для ускорения загрузки страницы, например.dns-prefetch,preconnect,prefetch,preload,prerenderЖдать.
  7. Установите подмножество веб-шрифтов и загрузите их асинхронно, а также используйтеCSSсерединаfont-displayВключает быстрый первый рендеринг.
  8. использоватьmozjpeg,guetzli,pingoа такжеSVGOMGОптимизируйте изображения и рассмотрите возможность использования изображенийCDNдляWebPСлужить.
  9. экзаменHTTPПравильно ли установлены заголовок кэша и заголовок безопасности.
  10. включить на сервереBrotliсжатие. (Если нет, то включитьGzipсжатие. )
  11. пока сервер работаетLinuxВ ядре версии 4.9+ он включенTCP BBRскопление.
  12. Включите, если возможноOCSP stapling.
  13. еслиHTTP/2доступно, включитьHPACKсжатие. Если вы настроены более агрессивно, попробуйте включитьHTTP/3.
  14. существуетService workerТакие ресурсы, как шрифты, стили, JavaScript и изображения, кэшируются в файлах .
  15. попробуй использовать прогрессивhydrationи сервер потоковой передачи для отображения вашего одностраничного приложения.

Справочная статья

Woohoo.smashing magazine.com/2021/01/Вставь...

nuggets.capable/post/701064…

nuggets.capable/post/684490…

сегмент fault.com/ah/119000002…

у-у-у. Краткое описание.com/afraid/1ad439279…

zhuanlan.zhihu.com/p/364991981

zhuanlan.zhihu.com/p/102382380

web.dev/vitals/