предисловие
В последнее время я прочитал много статей, связанных с оптимизацией интерфейса. Когда дело доходит до оптимизации внешнего интерфейса, это огромный диапазон. Возможно, больше статей обычно основано на определенном моменте, который нужно подробно объяснить. Так что воспользуйтесь возможностью организовать набор базовых набросков для фронтенд-оптимизации, с одной стороны, чтобы позволить себе накапливать эти знания, с другой стороны, также удобно иметь список для сравнения и оптимизации при последующей оптимизации.
Решение для внешней оптимизации
Начнем с обязательного вопроса на собеседовании: "Давайте поговорим о том, как вы занимаетесь фронтенд-оптимизацией?Так как же должно выглядеть относительно законченное решение по оптимизации интерфейса?
По прошлому опыту я думаю: в первую очередь нужно знать, какие страницы нужно оптимизировать и как оптимизировать, а затем уже можно целенаправленно их оптимизировать. Итак, я разделю оптимизацию интерфейса на следующие этапы:
- Определите, какие страницы необходимо оптимизировать
- Установить систему мониторинга
- Определение показателей мониторинга
- Анализировать страницы на основе информации о мониторинге
- Целевая оптимизация
- Оптимизация ресурсов
- Оптимизация сборки
- Оптимизация передачи
- Оптимизация сети
Определите, какие страницы необходимо оптимизировать
Установить систему мониторинга
Первым шагом является создание системы мониторинга производительности переднего плана. Существует два основных решения для мониторинга производительности переднего плана:
- Зрелые услуги, предоставляемые третьими сторонами: такие как Alibaba Cloud ARMS, Tingyun, Monitoring Bao и т. д.
- Сделай сам
Я не буду здесь повторять услуги, предоставляемые различными сторонними платформами, а в основном объясню примерную реализацию идеи самостоятельного построения front-end платформы мониторинга производительности.
Определить метрики сбора
Во внешнем мониторинге мы обычно фокусируемся на двух направлениях:производительность и устойчивость. Поэтому нам нужно собрать показатели, чтобы иметь четыре индикатора.
-
RUM (Наблюдение за реальными пользователями) Метрики: Включая FP, TTI, FCP, FMP, FID, MPFID.
-
Navigation Timing: Включая индикаторы DNS, TCP, парсинга DOM и других этапов.
-
JS Error: после синтаксического анализа его можно разделить на исключения времени выполнения и исключения статических ресурсов.
-
запросить исключение: собирает исключения запросов ajax.
Тогда давайте разберем, как собрать каждый индикатор по отдельности
индикатор РОМ
Основные веб-показатели — это подмножество веб-показателей, которые применяются ко всем веб-страницам, которые должен измерять каждый веб-разработчик и которые также будут отображаться во всех инструментах Google. Каждая основная веб-метрика представляет отдельный аспект взаимодействия с пользователем и может бытьдействительныйизмерить и отразитьОриентированный на пользователяреальный опыт ключевых результатов.
Составляющие метрики основных веб-метрик со временем меняются.развитие. Текущий состав метрик фокусируется на трех аспектах взаимодействия с пользователем:Загрузка производительности,интерактивность,визуальная стабильность
В основном он включает следующие индикаторы (и соответствующие пороговые значения для каждого индикатора):
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))
В дополнение к трем вышеуказанным показателям мы также можем отслеживать следующие показатели.
ФП, ФКП
время первой покраски (FP):которыйFirst Paint
, что является моментом времени первого рендеринга.
Впервые содержимое времени рендеринга (FCP):которыйFirst Contentful Paint
, который является моментом времени, когда содержимое отображается в первый раз.
Эти две метрики выглядят одинаково, ноFP
должно произойти до или равноFCP
.FP
Относится к рисованию пикселей. Например, цвет фона страницы серый, то он записан, когда отображается серый фон.FP
показатель. Но в это времяDOM
Контент еще не начал отрисовываться и может потребовать загрузки файла, парсинга и других процессов.DOM
Он будет срабатывать только при изменении содержимого, например, если фрагмент текста отрисовывается, он будет записан в это время.FCP
показатель. Таким образом, мы можем думать об этих двух индикаторах как об индикаторах, связанных со временем белого экрана, поэтому он должен быть самым быстрым, тем лучше.
Согласно официальному рекомендованному времени, мы должны поставитьFP
а такжеFCP
сжато до2 секундыВнутри.
Код коллекции выглядит следующим образом
window.performance.getEntriesByType('paint')
TTI
Время до полной интерактивности (TTI):которыйTime to interactive
, который записывает время, прошедшее с момента загрузки страницы до момента, когда страница становится полностью интерактивной.
ПолучатьTTI
Правила следующие:
-
Рисовать из первого контента (
FCP
)Начинать -
Поиск вперед в течение 5 секунд, никаких длинных задач и не более 2 запросов на получение
-
Поиск последней длинной задачи в обратном направлении (занимает более
50
миллисекундные задачи), если длинные задачи не найденыFCP
остановка -
TTI
Время - это время последней длинной задачи, если длинной задачи нет, то оно равноFCP
время
Google надеется наTTI
Показатели стандартизированы и переданыPerformanceObserver
Доступен в браузерах, но в настоящее время не поддерживается.
В настоящее время только одинpolyfill
, чтобы определить текущийTTI
для всех поддерживаемыхLong Tasks API
Браузер.
Согласно официальному рекомендованному времени, мы должны поставить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
, который является новым форматом данных без потерь с открытым исходным кодом,и теперь поддерживается всеми современными браузерами.
Brotli
Существует соотношениеGzip
а такжеDeflate
Более высокая степень сжатия, но также требуется более длительное время сжатия, поэтому не рекомендуется выполнять сжатие в режиме реального времени по запросу. Но мы можем предварительно сжать статические файлы и передать их клиенту напрямую, поэтому мы избегаемBrotli
Проблема низкой эффективности сжатия, и, используя этот метод, мы можем использовать самый высокий уровень качества сжатия, чтобы сжать файл и минимизировать размер файла.
Кроме того, поскольку не все браузеры поддерживаютBrotli
Алгоритм, поэтому сервисной стороне нам нужно предоставить два документа, один сквознойBrotli
Сжатые файлы, один из которых является исходным файлом, который не поддерживается в браузере.Brotli
случай, мы можем использоватьgzip
Распакуйте исходный файл и передайте его клиенту.
Brotli
Может использоваться для любого простого текстового содержимого, такого какHTML
,CSS
,SVG
,JavaScript
Ждать.
Настроен с максимальной степенью сжатияПредварительно сжатые статические ресурсы Brotli + Gzipи использоватьBrotli
Настройте 3-5 коэффициентов сжатия для быстрого сжатияHTML
. Убедитесь, что сервер обрабатывает его правильноBrotli
илиgzip
Заголовок согласования содержания.
Использование адаптивных изображений и WebP
WebP
Изображение — это новый формат изображений, разработанный Google. а такжеpng
,jpg
По сравнению с тем же визуальным опытом,WebP
Размер изображения был уменьшен примерно30%. Кроме того,WebP
Формат изображения также поддерживает сжатие с потерями, сжатие без потерь, прозрачность и анимацию. Теоретически его можно полностью заменить.png
,jpg
,gif
и другие форматы изображений, но в настоящее времяWebP
еще не полностью поддерживается, но мы все еще можем использовать его в нижней строке.
Поэтому при использовании изображений используйте изображения сsrcset
,sizes
а также<picture>
элементальадаптивные изображения. При использовании вы также можете<picture>
элементы иJPEG
карман для использованияWebP
Формат.
ноWebP
Не без недостатков, не поддерживаетПрогрессивный рендеринг, такой как JPEG, поэтому пользователи используютJPEG
Может быть, быстрее увидеть фактическое изображение! несмотря на то чтоWebP
Изображения могут загружаться быстрее в сети. использоватьJPEG
Мы можем дать пользователю более «приличный» опыт за половину или даже четверть времени, а остальные данные загрузить позже, а не какWebP
Это просто полупустой образ. Так что это зависит от того, что мы хотим: используйтеWebP
, уменьшит размер изображения; используйтеJPEG
, что улучшит воспринимаемость изображения.
Правильно ли оптимизированы изображения?
В нашем проекте очень важна быстрая загрузка изображений, поэтому нужно быть внимательным при использовании изображений:
-
убедись
JPEG
постепенно визуализируется и используетmozJPEG
илиGuetzli
сжатие. -
использовать
Pingo
компрессияpng
-
использовать
SVGO
илиSVGOMG
правильноSVG
сжать -
Изображение или
iframe
ленивая загрузка -
По возможности рекомендуется использовать петлевой
video
илиWebP
заменятьgif
[использовать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
Сравнение процессов:
Используете ли вы шаблон модуля/номодуля в 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
Синтаксис для браузеров, как средство.
использовать
type=module
Оптимизация объема встроенного файла снижена на 30% ~ 50% по сравнению с обычным встроенным файлом, и мы также можем ожидать оптимизации производительности нового синтаксиса в браузере.
Определите и удалите неиспользуемый CSS/JS
в ChromeИнструмент покрытия кода CSS и JavaScript (Coverage)Может дать нам представление о том, какой код был выполнен или применен, а какой нет. Мы можем начать проверку покрытия и посмотреть результаты покрытия. После обнаружения неиспользуемого кодаНайдите эти модули и используйте import() для их ленивой загрузки.. Затем повторите проверку покрытия кода, чтобы убедиться, что теперь при инициализации загружается меньше кода.
вы можете использоватьPuppeteer
для сбора покрытия кода,Puppeteer
многое другоеДругое использование,НапримерСледите за неиспользуемым CSS в каждой сборке.
также,purgecss,UnCSSа такжеHeliumможет помочь вам отCSS
Удалите неиспользуемые стили в .
Уменьшить размер пакета JavaScript
Добавьте проверку зависимостей в свой ежедневный рабочий процесс. Замените некоторые из больших библиотек, которые вы, возможно, добавили много лет назад, на меньшие и более легкие библиотеки, например, с помощьюDay.js
заменятьMoment.js
использоватьBundlephobiaТакие инструменты, как npm, могут помочь вам понять стоимость добавления пакета npm.size-limitНе только проверит размер, но и отобразитJavaScript
время исполнения.
Используйте оптимизации для целевого движка 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
Схема связи: -
Полностью серверный рендеринг (SSR)
Рендеринг сервера реагирует на навигацию, создавая полную страницу для страницы на сервере.
HTML
. Это позволяет избежать дополнительной выборки данных и обработки шаблонов на стороне клиента, поскольку они обрабатываются до того, как браузер получит ответ.FP
а такжеFCP
Разрыв обычно невелик, запуск логики страницы и рендеринга на сервере позволяет избежать отправки клиенту большой суммы.JavaScript
, что помогает добиться быстрой интерактивности (TTI
). и можетHTML
для потоковой передачи в браузер и немедленного отображения страницы. Однако для синтаксического анализа требуется больше времени, в результате чего приходит первый байт (TTFB
) браузеры, и мы не используем преимущества скорости отклика и других богатых функций современных приложений. -
Создание статического сайта (SSG)
Генерация статического сайта похожа на рендеринг на стороне сервера, но вво время сборкиа не впо запросуОтрисовка страницы. В отличие от серверного рендеринга, потому что страницу не нужно генерировать динамически.
HTML
, поэтому он также поддерживает стабильно быстрое время до первого байта (TTFB
).通常,静态呈现意味着提前为每个URL
создать отдельныйHTML
документ. с предварительно сгенерированнымHTML
отзывчивые, статические рендереры могут быть развернуты на несколькихCDN
, чтобы воспользоваться преимуществом пограничного кэширования. Таким образом, мы можем быстро отобразить страницу, а затем получить ее заранее для последующих страниц.SPA
Рамка. Но этот подход подходит только для сценариев, где генерация страницы не зависит от ввода пользователя. -
Рендеринг на стороне сервера (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
и перед присоединением обработчика событий,Не могу ответить на ввод.Уведомление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.Идеальный процесс рендеринга потокового сервера выглядит следующим образом:
- просить
HTML
, сервер сначала возвращает скелетный экранHTML
, затем верните нужные данные илиHTML
и, наконец, закрыть запрос. - просить
js
,js
После возвращения и выполнения вы можете взаимодействовать.
- просить
-
Предварительный рендеринг на стороне клиента
Подобно предварительному рендерингу на стороне сервера, но вместо динамического рендеринга страниц на сервере приложение визуализируется статически во время сборки.
HTML
.используется в процессе сборки
renderToStaticMarkup
метод вместоrenderToString
метод, который генерируетdata-reactid
Статическая страница с такими атрибутами, главная страница этой страницыJS
и последующие маршруты, которые могут быть использованы, будут предварительно загружены. Другими словами, какой была страница, когда она была упакована, на что похожа предварительная визуализация. Подожди покаJS
Загрузите и завершите выполнение, если на странице есть обновление данных, то страница будет отрисована снова. Это создает иллюзию задержки данных.оказаться
TTFB(第一字节到达时间)
а такжеFCP
меньше времени и корочеTTI
а такжеFCP
Интервал между. Этот метод нельзя использовать, если ожидаемое содержимое изменится. Кроме того, вы должны знать все заранее.URL
для создания всех страниц. -
Трехсторонний изоморфный рендеринг
если вы можете использовать
Service Worker
, также может пригодиться трехсторонний рендеринг. Этот метод относится к: рендерингу начальной страницы с потоковым сервером и т. д.Service Worker
После загрузки взять на себяHTML
работа по рендерингу. Это обеспечивает актуальность кэшированных компонентов и шаблонов, а также позволяет использовать одностраничную навигацию в стиле приложения для предварительного рендеринга новых представлений в том же сеансе. При наличии на сервере, клиентских страницах иService Worker
Этот метод работает лучше всего, когда между ними используется один и тот же шаблон и код маршрутизации.
Трехсторонний рендеринг, рендеринг одним и тем же кодом в трех местах: на сервере, в DOM или в сервис-воркере.
Технический спектр от рендеринга на стороне сервера до рендеринга на стороне клиента.
Что касается того, как выбрать, вот несколько незрелых предложений:
- правильно
SEO
требования не высоки, и в то же время对操作需求比较多
проектов, таких как некоторые фоновые системы управления, рекомендуется использоватьCSR
. потому что только после казниbundle
После этого со страницей можно взаимодействовать, а элементы можно только видеть, но нельзя взаимодействовать, что не имеет большого значения, иSSR
Принесет дополнительные затраты на разработку и обслуживание. - если страница
无数据
,или纯静态
страницу, рекомендуется использоватьSSG
. Поскольку это способ создания страницы путем предварительного просмотра пакета, он не увеличивает нагрузку на сервер. - правильно
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
Ленивая загрузка поддерживается.
Самый эффективный способ ленивой загрузки скриптов — использоватьIntersection Observer API,этоAPI
Целевой элемент можно наблюдать асинхронно с элементом-предком или документом.viewport
Пересечение между изменениями. Нам нужно создатьIntersectionObserver
Object, он получает 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-канал находится в низкоскоростном этап передачи), чтобы избежать описанного выше явления. Эта стратегиямедленный старт.
- алгоритм медленного старта
Идея алгоритма медленного старта состоит в том, чтобы добавитьОкно перегрузки, обозначаемый какcwnd.
Окно перегрузки относится к максимальному MSS, которое может быть отправлено при получении ACK от однорангового узла (Максимальный размер сегмента)количество. Окно перегрузки — это значение, поддерживаемое отправителем, и оно не будет объявлено партнеру, как окно получателя (rwnd).Размер окна отправителя равен минимуму cwnd и rwnd.. Начальное значение текущего окна перегрузки Linux — 10 MSS.
Алгоритм медленного старта, после каждого RTT cwnd становится в два раза больше, чем раньше. Отправитель начинает отправлять сегменты initcwnd (Предположим, что окно получателя не имеет ограничений) и дождитесь ACK (То есть символ подтверждения.При передаче данных - символ управления передачей, посылаемый принимающей станцией на передающую станцию. Указывает, что отправленные данные были подтверждены для получения без ошибок.). Когда этот ACK получен, окно перегрузки расширяется до
initcwnd*2
, то есть можно отправитьinitcwnd*2
сегмент. Когда ACK для этого исходящего сегмента получен, окно перегрузки продолжает расширяться доinitcwnd*4
, что является экспоненциально возрастающей зависимостью.
- Алгоритм предотвращения перегрузок
Алгоритм предотвращения перегрузки и алгоритм медленного старта — это два разных алгоритма, но оба они предназначены для решения проблемы перегрузки, и на практике эти два алгоритма обычно реализуются вместе. По сравнению с алгоритмом медленного старта, алгоритм предотвращения перегрузки поддерживает еще одинПорог медленного запуска ssthresh.
Когда cwnd ssthresh, окно перегрузки использует алгоритм предотвращения перегрузки и растет линейно.
Алгоритм предотвращения перегрузки увеличивает окно перегрузки после каждого RTT.
initcwnd
.Когда возникает перегрузка (тайм-аут или получен дубликат подтверждения), RFC5681 считает, что ssthresh нужно установить на половину неподтвержденных пакетов, но не менее чем на два MSS. также,Если перегрузка вызвана тайм-аутом, для cwnd устанавливается значение initcwnd..
Повторная передача с течением времени оказывает серьезное влияние на производительность передачи. Причины: 1. В РТО (Период ожидания повторной передачи, то есть с момента отправки данных, повторная передача выполняется по истечении этого времени.) этап не может передать данные, что эквивалентно потере периода времени 2. Резкое сокращение окна перегрузки эквивалентно тому, что последующая передача будет намного медленнее.
- Алгоритм быстрой ретрансляции
Иногда перегрузка незначительна, теряется всего несколько пакетов, а последующие пакеты могут приходить нормально. Когда последующие пакеты прибудут к получателю, получатель обнаружит, что его номер последовательности больше, чем ожидалось, поэтому каждый раз, когда он получает пакет, он будет подтверждать ожидаемый номер последовательности, чтобы напомнить отправителю о повторной передаче. когда отправитель получает3 или большеКогда Dup Ack повторяется, он понимает, что соответствующий пакет потерян, и немедленно передает его повторно. Этот процесс называется быстрой повторной передачей.
Зачем нужно делать до 3? Это связано с тем, что сетевые пакеты иногда не по порядку, а не по порядку пакеты будут вызывать повторные подтверждения, но повторная передача не требуется для не по порядку. Так как общее расстояние вне очереди не слишком отличается, например, пакет № 2 может бежать за пакетом № 4, но вряд ли он будет бежать за пакетом № 6, поэтому его можно избежать. в значительной степени, ограничив его до 3 или более.Быстрая повторная передача запускается из-за нарушения порядка.
Кроме того, есть еще одна проблема, если мы теряем оба пакета 2 и 3, но последние 4, 5, 6 и 7 принимаются нормально, а ACK 2 срабатывает три раза. В это время, если отправитель получает несколько дубликатов ACK, он считает, что произошла потеря пакета, и TCP будет повторно передавать последующие пакеты, начиная с последнего подтвержденного пакета. Таким образом, пакеты, которые были переданы правильно, могут быть отправлены повторно, что снижает производительность TCP. Чтобы исправить эту ситуацию, SACK (выборочное подтверждение), используя опцию SACK, можно сообщить отправителю, какие данные были получены, а отправитель будет знать, какие данные потеряны после получения этой информации, а затем немедленно повторно передать потерянную часть.
- Алгоритм быстрого восстановления
Если быстрая повторная передача происходит во время фазы перегрузки, нет необходимости обрабатывать окно перегрузки, как повторную передачу по тайм-ауту.Учитывая, что если сеть перегружена, она не получит несколько дублирующих подтверждений, поэтому отправитель теперь думает, что сеть не может быть перегруженным. . Таким образом, вместо выполнения алгоритма медленного запуска в это время установите для cwnd значение после того, как ssthresh уменьшится вдвое, а затем выполните алгоритм предотвращения перегрузки, чтобы медленно увеличить cwnd. Этот процесс называетсябыстрое восстановление.
Суммировать:
Повторные передачи по тайм-ауту оказывают наибольшее влияние на производительность, поскольку во время RTO данные не могут быть переданы, а окно перегрузки резко сокращается. Таким образом, вы должны попытаться избежать повторной передачи по тайм-ауту.
Влияние потери пакетов на очень маленькие файлы более серьезное, чем на большие файлы, потому что маленькие файлы могут не вызывать три повторных подтверждения, что приводит к невозможности быстрой повторной передачи.
При использовании алгоритма быстрого восстановления алгоритм медленного запуска используется только при установленном TCP-соединении и тайм-ауте сети.
TCP BBR — это новый алгоритм управления перегрузкой TCP, опубликованный Google, который широко использовался в Google и был официально выпущен в версии Linux 4.9.
Название BBR на самом деле является аббревиатурой от узкой полосы пропускания и времени распространения туда и обратно (полоса пропускания узкого места и время распространения туда и обратно), что указывает на основной рабочий механизм BBR:Контроль перегрузки осуществляется путем обнаружения двух показателей, пропускной способности и RTT.Основные особенности алгоритма BBR заключаются в следующем:
- BBR не учитывает потерю пакетов, потому что потеря пакетов (в наши дни) не обязательно является признаком перегрузки сети.
- BBR полагается на обнаруженную пропускную способность в реальном времени и RTT для определения размера окна перегрузки: размер окна = пропускная способность * RTT.
Попробуйте перекомпоновать свои правила CSS
согласно сCSS and Network Performanceисследование, согласно запросу СМИCSS
Разделение файлов может в определенной степени улучшить производительность нашей страницы. Таким образом, браузер будет извлекать критический CSS с высоким приоритетом и обрабатывать все остальное с низким приоритетом.
Например:
<link rel="stylesheet" href="all.css" />
Мы помещаем все css в один файл, и браузер будет обрабатывать его следующим образом:
<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
При запросе браузер будет выглядеть так:
Избегайте использования в файлах 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
, вы можете использовать следующие решения для повышения производительности вашей программы:
-
Не перекомбинируйте вложенные компоненты стиля: это позволяет
React
Меньше компонентов для управления и более быстрый рендеринг -
Отдавайте предпочтение «статическим» компонентам:Немного
CSS-in-JS
библиотека будет в вашемCSS
нет темы зависимости илиprops
оптимизировать его выполнение. Чем более «статичными» являются ваши шаблоны тегов, тем большеCSS-in-JS
Среда выполнения, скорее всего, будет выполняться быстрее. -
Избегайте недопустимых повторных рендеров React: Убедитесь, что рендерите только при необходимости, это позволяет избежать
React
а такжеCSS-in-JS
Работа библиотеки во время выполнения. -
Может ли библиотека 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 (илиJavaScript
JavaScript
HTML
preload
preload
Early HintHTML
preload
Priority Hints
preload
as
crossorigin
<link rel="preload" href="style.css" as="style"> <link rel="preload" href="main.js" as="script">
CSS
will-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
CSS
CPU
CSS
GPU
CSS
GPU
transform
opacity
filter
will-change
GPU
will-change
GPU
-
-
HMTL
AST
-
-
-
rem
->px
white
->#FFFFFF
-
CSS
DOM 树
render 树
-
-
-
dispy:none
render
-
-
-
-
-
-
GPU
-
GPU
-
построить дерево слоевОчень важно, давайте сосредоточимся на этом снова. браузер изDOM 树
Для преобразования качества изображения в экранную графику необходимо преобразовать древовидную структуру в структуру слоев. Вот 4 пункта:
-
РендерОбъект
Один
DOM
Узел соответствует объекту рендеринга, а объект рендеринга поддерживаетDOM
структура дерева. Объект рендеринга умеет рисоватьDOM
Содержимое узла, которое рисуется путем выдачи необходимых команд рисования в GraphicsContext.DOM
узел. -
РендерСлой
Когда браузер визуализирует построенную модель первого слоя, объекты визуализации, расположенные в координатном пространстве одного уровня, будут объединены в один и тот же слой визуализации, поэтому в соответствии с контекстом наложения объекты визуализации в координатных пространствах разных уровней будут формировать несколько слоев визуализации. чтобы отразить каскадную связь между ними. Поэтому для отрисовки объектов, удовлетворяющих условиям формирования контекста наложения, браузер автоматически создаст для них новый слой отрисовки. Обычно следующие распространенные ситуации заставляют браузер создавать для него новый слой рендеринга:
-
document
элемент position: relative | fixed | sticky | absolute
-
opacity
< 1 will-change | fliter | mask | transform != none | overflow != visible
-
-
Графический слой
Графический слой — это модель слоя, отвечающая за генерацию конечной представляемой графики контента.Он имеет графический контекст (GraphicsContext), а графический контекст отвечает за вывод растрового изображения слоя. Растровые изображения, хранящиеся в общей памяти, будут использоваться в качестве текстур (Думайте об этом как о растровом изображении, которое перемещается из основной памяти в память изображений.)загрузить на
GPU
, и, наконец, поGPU
Объедините несколько растровых изображений и нарисуйте их на экране.В этот момент наша страница отображается на экране.Таким образом, графический слой является важным носителем и инструментом рендеринга, но он имеет дело не напрямую со слоем рендеринга, а со слоем композитинга.
-
Композитный слой
Слои рендеринга, отвечающие определенным особым условиям, будут автоматически преобразованы браузером в составные слои. Композитный слой имеет отдельный графический слой, в то время как другие слои рендеринга, которые не являются композитными слоями, будут совместно использовать один слой с первым родительским слоем, имеющим графический слой.
Итак, каким особым условиям должен соответствовать слой рендеринга, прежде чем его можно будет повысить до составного слоя? Вот несколько распространенных случаев:
3D transforms
-
video
,canvas
,iframe
-
opacity
анимация перехода position: fixed
will-change
-
animation
илиtransition
уже настроенopacity
,transform
,fliter
,backdropfilter
Слой рендеринга, отвечающий некоторым особым условиям, упомянутым выше, в конечном итоге будет повышен браузером до слоя композиции, называемогоЯвный синтез. Кроме того, в браузере также естьНеявный синтез. Давайте рассмотрим это на примере:
- Допустим, у нас есть два
absolute
позиционируетсяdiv
перекрываются на экране, согласноz-index
отношения, один изdiv
Он будет «накрыт» поверх другого.
- В это время, если мы дадим
z-index: 3
настраиватьtransform: translateZ(0)
, пусть браузер продвинет его досинтетический слой. После подъемаz-index: 3
Этот составной слой будетdocuemnt
выше, то логичноz-index: 3
будет вz-index: 5
Выше мы установилиz-index
Будет произвольное отношение перекрытия.
- Чтобы исправить этот неправильный порядок перекрытия, браузер должен сделать слой рендеринга, который должен «перекрывать» его, одновременно продвигаться к слою композиции. это называетсяНеявный синтез
После того, как слой рендеринга будет повышен до составного слоя, это принесет нам много преимуществ:
- Растровое изображение композитного слоя будет передано
GPU
синтетический, чемCPU
Обработка намного быстрее; - Когда вам нужно перерисовать, вам нужно перерисовать только себя, не затрагивая другие слои;
- После того, как элемент переведен в составной слой,
transform
а такжеopacity
Он не вызовет перерисовку, если это не составной слой, он все равно вызовет перерисовку.
Конечно, неправильное использование чего-либо будет иметь побочные эффекты, такие как:
- Окрашенные слои необходимо перенести на
GPU
, количество и размер этих слоев достигают определенной величины, что может привести к очень медленной передаче, что, в свою очередь, может привести к мерцанию на некоторых бюджетных и средних устройствах; - Неявный синтез склонна к чрезмерным слоям синтеза, каждый из которых занимает дополнительную память, образуявзрыв слоя. Занять
GPU
и большой объем ресурсов памяти, серьезно снижающий производительность страницы. А память — ценный ресурс на мобильных устройствах, и использование слишком большого объема памяти может привести к сбою в работе браузера, что сделает оптимизацию производительности контрпродуктивной.
Хорошо, примерно зная принцип рендеринга браузера, давайте посмотрим, как на практике уменьшить перекомпоновку и перерисовку:
- всегда на картинкеУстановить свойства ширины и высоты: Браузер выделяет кадр и резервирует место по умолчанию, и после загрузки последующих ресурсов изображения перекомпоновка не требуется.
- Избегайте множественных модификаций: например, нам нужно изменить
DOM
изheight/width/margin
Три свойства, в это время мы можем пройтиcssText
модифицировать, а неdom.style.height
модифицировать. - Массовое редактирование DOM: поставить
DOM
Скройте или клонируйте его и измените, а затем замените, но теперь браузер будет использовать очередь для хранения нескольких модификаций для оптимизации. Сфера применения этого не столь широка. - Вне потока документов: для некоторых частых изменений, таких как анимация
DOM
.Вы можете использовать абсолютное позиционирование, чтобы вывести его из потока документов, чтобы избежать частого перекомпоновки родительских элементов.
Оптимизация сети
Включено ли сшивание OCSP?
пройти черезВключить сшивание OCSP на сервере, что может ускоритьTLS
Скорость рукопожатия. «Протокол статуса онлайн-сертификата» (OCSP
) — это список отозванных сертификатов (CRL
) альтернативный протокол. Оба протокола используются для проверкиSSL
Был ли отозван сертификат. но,OCSP
Протокол не требует, чтобы браузеры тратили время на загрузку и поиск списков информации о сертификатах, тем самым сокращая время, необходимое для рукопожатий.
Список отозванных сертификатов (CRL):CRL распространяются в общедоступных репозиториях, и браузеры могут получать и обращаться к последнему CRL ЦС при проверке сертификатов. Недостатком этого подхода является то, что временная гранулярность списка отзыва ограничена периодом выдачи CRL. Браузеры уведомляются об отзыве только после того, как поставщик центра сертификации обновит все опубликованные в настоящее время CRL. Стратегии каждого поставщика ЦС подписи разные, у некоторых несколько часов, у некоторых несколько дней или даже несколько недель.
Протокол статуса онлайн-сертификата (OCSP): Чтобы решить проблему больших одиночных файлов и высокой задержки, было введено новое решение OCSP. Браузер запрашивает статус отзыва сертификата у онлайн-сервера OCSP (также известного как сервер ответов OCSP), и сервер OCSP отвечает. Такой подход позволяет избежать проблемы с задержкой обновления CRL. Недостатками этого метода являются:
- Каждый раз, когда браузер создает запрос HTTPS, ему необходимо подключиться к серверу CA OCSP для проверки.Сеть между IP-адресом браузера и сервером CA OCSP не является гладкой. Более того, проверка OCSP имеет сетевой ввод-вывод, который занимает много времени, что серьезно влияет на работу пользователя с браузером, обращающимся к серверу.
- Когда браузер отправляет серийный номер HTTPS-сертификата сервера на сервер CA OCSP, он также раскрывает конфиденциальность пользователя и раскрывает URL-адрес, к которому обращается пользователь, серверу CA OCSP.
Сшивание OCSP: OCSP Stapling устраняет недостатки CRL и OCSP и переносит процесс вызова OCSP Server для получения статуса отзыва сертификата на веб-сервер.Веб-сервер может не только напрямую запрашивать информацию OCSP, но и избегать
网络访问限制
,OCSP服务器离用户的物理距离较远
Вы также можете кэшировать ответ на запрос и использовать его для других браузеров. Поскольку ответ OCSP также подписан закрытым ключом CA RSA, не нужно беспокоиться о подделке.
Решена проблема медленного доступа
Решена проблема утечки конфиденциальности пользователей
Правильно ли он оптимизирован для протокола 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
Сжатие экономит трафик, занимаемый заголовком пакета.- Та же самая информация заголовка не будет отправлена через запрос, и будет использоваться информация заголовка, переданная в предыдущем запросе.
- Информация о новом/измененном заголовке будет добавлена к
HEAD
, оба конца обновляются постепенно.
- приоритет запроса: Каждый поток имеет собственный приоритет, который может быть указан клиентом. И может сделать управление потоком.
- Пуш сервера: Например, мы загружаем index.html, также нам могут понадобиться index.js, index.css и другие документы. Традиционный запрос, только если клиент таким образом получит index.html, будет введен для разбора html index.js / index.css, снова запрошенный ресурс будет загружен, но сервер через данные, вы можете протолкнуть продвижение ресурсов к клиенту, чтобы при использовании для прямых вызовов вам не нужно отправлять запрос.
-
бинарный протокол: использует бинарный протокол, разница
与HTTP/1.X的
Гипертекстовый протокол. Когда клиент (сервер) отправляет (принимает) данные, он будет разгонять данные и отправлять их не по порядку.streamID
ID для объединения данных. Бинарные протоколы более эффективны для разбора, более компактны «на проводе» и, что самое главное, менее глючны.
Здесь добавлено, что 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) -
TCP не поддерживает мультиплексирование на уровне потока.:несмотря на то что
TCP
допускает несколько логических соединений между уровнями приложений, но не позволяетTCP
Мультиплексирование пакетов в потоке. использоватьHTTP/2
Когда браузер может открыть только один с серверомTCP
соединение и использовать одно и то же соединение для запроса нескольких объектов, таких какCSS
,JavaScript
и другие документы. При получении этих объектовTCP
Все объекты будут сериализованы в одном потоке. Поэтому и не знаетTCP
Разделение сегментов на уровне объекта. -
TCP создает избыточную связь:
TCP
Рукопожатия соединения имеют избыточные последовательности обмена сообщениями, даже для соединений с известными хостами.
-
-
Преимущества протокола QUIC
-
Выберите UDP в качестве базового протокола транспортного уровня.:существует
TCP
построить новый транспортный механизм поверх него, который унаследуетTCP
из всех перечисленных недостатков. следовательно,UDP
это мудрый выбор. также,QUIC
построен на пользовательском уровне, поэтому при каждом обновлении протокола не требуется никаких модификаций ядра. -
Мультиплексирование потоков и управление потоком:
QUIC
Введена концепция мультиплексирования потоков по соединениям.QUIC
По замыслу он реализует отдельное управление потоком для каждого потока и решает проблему блокировки очереди всего соединения. -
Гибкий механизм управления перегрузкой:
TCP
Механизм контроля заторов является жестким. Каждый раз, когда протокол обнаруживает перегрузку, он уменьшает размер окна перегрузки наполовину. Напротив,QUIC
Управление перегрузкой спроектировано так, чтобы быть более гибким и может более эффективно использовать доступную полосу пропускания сети, что приводит к повышению пропускной способности. -
улучшенная обработка ошибок:
QUIC
Используйте улучшенные механизмы восстановления после потерь и прямое исправление ошибок для лучшей обработки ошибочных пакетов. Эта функция полезна для пользователей, которые имеют доступ к Интернету только через медленные беспроводные сети, которые часто имеют высокий уровень ошибок при передаче. -
более быстрое рукопожатие:
QUIC
использовать то же самоеTLS
Модули надежно соединены. Однако сTCP
разница в том,QUIC
Механизм рукопожатия оптимизирован, чтобы избежать избыточного обмена протоколами каждый раз, когда устанавливается связь между двумя известными одноранговыми узлами.
-
-
Вот две формулы, чтобы увидеть сравнение между 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
В эпоху , какие стратегии оптимизации устарели или вообще анти-оптимизация?
-
уменьшить количество запросов:
HTTP/1.1
Из-за «блокировки головы очереди» мы обычно используем такие методы, как слияние ресурсов, объединение файлов (изображения спрайтов и т. д.), чтобы уменьшить количество запросов. но вHTTP/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
В то же время он укажет на недостатки оптимизации веб-сайта и предоставит предложения по оптимизации.
WebPageTestТесты скорости веб-сайта предоставляются бесплатно в нескольких местах по всему миру. Он также может предоставлять обширную диагностическую информацию на основе результатов тестирования, включая каскадные диаграммы загрузки ресурсов, проверки оптимизации скорости страницы и предложения по улучшению, а также дает каждому контенту окончательную оценку.
Аварийный план
Список огромен, и на выполнение всех оптимизаций может уйти много времени. Итак, что бы вы сделали, если бы у вас было очень ограниченное количество времени для оптимизации? Давайте сконденсируем его в15 простых пунктов.
- Установите соответствующие цели, основанные на практическом опыте. Разумная цель состоит в том, чтобы визуализировать видимую область 1s, страница отображается 3s, время работы слабой сети 3G 5s, Время до взаимодействия (TTI) для повторных посещений 2s.
- Подготовьте важный CSS для верхней части страницы и вставьте его на страницу. для
CSS
/JS
, максимальный размер файла ключа170 КБ в сжатом видеВнутри. - Извлекайте, оптимизируйте и лениво загружайте как можно больше сценариев, выбирайте облегченные альтернативы (например, использование
DayJs
заменятьMomentJs
) и ограничить влияние сторонних скриптов. - только иметь
<script type="module">
а такжемодуль/номодульный режимСтарые версии браузеров предоставляют устаревший код. - попробуй перегруппироваться
CSS
правило. - Добавить подсказки ресурсов (
resource hints
) для ускорения загрузки страницы, например.dns-prefetch
,preconnect
,prefetch
,preload
,prerender
Ждать. - Установите подмножество веб-шрифтов и загрузите их асинхронно, а также используйте
CSS
серединаfont-display
Включает быстрый первый рендеринг. - использоватьmozjpeg,guetzli,pingoа такжеSVGOMGОптимизируйте изображения и рассмотрите возможность использования изображений
CDN
дляWebP
Служить. - экзамен
HTTP
Правильно ли установлены заголовок кэша и заголовок безопасности. - включить на сервере
Brotli
сжатие. (Если нет, то включитьGzip
сжатие. ) - пока сервер работает
Linux
В ядре версии 4.9+ он включенTCP BBR
скопление. - Включите, если возможно
OCSP stapling
. - если
HTTP/2
доступно, включитьHPACK
сжатие. Если вы настроены более агрессивно, попробуйте включитьHTTP/3
. - существует
Service worker
Такие ресурсы, как шрифты, стили, JavaScript и изображения, кэшируются в файлах . - попробуй использовать прогрессив
hydration
и сервер потоковой передачи для отображения вашего одностраничного приложения.
Справочная статья
Woohoo.smashing magazine.com/2021/01/Вставь...
сегмент fault.com/ah/119000002…
у-у-у. Краткое описание.com/afraid/1ad439279…
zhuanlan.zhihu.com/p/364991981