Мониторинг производительности сайта и стратегия оптимизации
0 Предисловие
Для интернет-проекта самое главное — пользовательский опыт. Во время бума «Интернет +» по всей стране большинство предприятий признали превосходство пользователей, особенно в сегодняшнюю эпоху быстрого развития мобильных терминалов, наши веб-страницы не только представлены в браузерах ПК пользователей, но чаще всего пользователь просматривает наши веб-страницы через мобильный продукт. Кроме того, все больше и больше разработчиков вкладывают средства в команду разработчиков веб-приложений и гибридных приложений, и производительность снова стала темой, на которой сосредоточились программисты. Я видел такое предложение: впечатления от веб-сайта определяют, хотят ли пользователи понять функции веб-сайта, а функции веб-сайта определяют, будут ли пользователи голосовать против использования веб-сайта. Это крылатая фраза, модифицированная из Интернета, но она делает работу веб-сайта очень тщательной, особенно в таком проекте, как веб-сайт, если пользователю требуется более 5 с, чтобы увидеть страницу, он без колебаний закроет ее.
Оптимизация производительности, как «высшее боевое искусство» в инженерном мире, — это тема, о которой мы часто говорим в процессе разработки, и это также необходимый этап для разработчика, чтобы перейти от начального уровня к старшему. норм, но на практике часто перегружается, не знаю, чего не хватает, и не знаю, есть ли место для дальнейшей оптимизации производительности.
Для производительности веб-сайта в отрасли существует множество установленных показателей, но что касается внешних интерфейсов, мы должны уделять больше внимания следующим показателям: время белого экрана, время первого экрана, время полной страницы, время DNS, загрузка ЦП. . И веб-сайт, который я создал сам раньше (URL:jerryonlyzrj.com/resume/, недавно из-за того, что регистрацию доменного имени не удалось открыть, через несколько дней она вернется в нормальное состояние), когда вообще не производилась оптимизация производительности, первое экранное время составляло 12,67 с, и, наконец, после различных оптимизаций оно было окончательно уменьшено. до 1,06 с, а ускорение CDN не настроено. В процессе я наступил на множество ям, а также перелистал много профессиональных книг и, наконец, решил организовать усилия последних нескольких дней в документ, чтобы помочь энтузиастам фронтенда избежать окольных путей.
Сегодня мы постепенно представим три аспекта оптимизации производительности, включая производительность передачи по сети, производительность рендеринга страниц и производительность блокировки JS, а также систематически познакомим читателей с практическим процессом оптимизации производительности.
1. Оптимизация производительности передачи по сети
Прежде чем мы начнем знакомить с работой по оптимизации производительности передачи по сети, нам необходимо понять процесс обработки запросов пользователей браузером, тогда мы должны представить такую картину:
Это график индикатора мониторинга времени навигации.Из рисунка видно, что после того, как браузер получает запрос пользователя, он проходит следующие этапы: перенаправление → вытягивание кэша → DNS-запрос → установка TCP-соединения → инициация запроса → получение ответа → обработка Элементы HTML → Загрузка элемента завершена. Не волнуйтесь, мы обсудим детали шаг за шагом:
1.1 Кэш браузера
Все мы знаем, что перед тем, как браузер инициирует запрос к серверу, он сначала запросит, есть ли тот же файл локально, и если да, то он напрямую извлечет локальный кеш, который похож на Redis и Memcache, которые мы развернули в фон Роль промежуточной буферизации, давайте сначала посмотрим на стратегию браузера по обработке кэширования:
Поскольку картинки в Интернете слишком общие, а я читал много статей о кешировании, редко систематически систематизируют код состояния и когда хранить кеш в памяти, а когда хранить кеш на жестком диске (диске). Поэтому я сам нарисовал блок-схему механизма кэширования браузера и объединил эту схему, чтобы более подробно объяснить механизм кэширования браузера.
Здесь мы можем использовать сетевую панель в chrome devtools для просмотра информации о сетевых передачах:
(Особое внимание нужно обратить на это, когда мы отлаживаем кеш, нам нужно снять верхнюю часть сетевой панелиDisable cache
Отметьте эту опцию, иначе браузер никогда не будет тянуть данные из кеша)
Кэш браузера по умолчанию помещается в память, но мы знаем, что кеш в памяти будет очищен при завершении процесса или закрытии браузера, а кеш на жестком диске может сохраняться длительное время. Много раз мы будем видеть два разных состояния в элементе размера каждого запроса на сетевой панели:from memory cache
иfrom disk cache
, первое относится к кэшу из памяти, второе относится к кэшу с жесткого диска. Это не что иное, как поле Etag, которое мы устанавливаем на сервере, которое управляет местом хранения кеша. После того, как браузер получит ответ сервера, он обнаружит заголовок ответа (Header), и при наличии поля Etag браузер запишет этот кеш на жесткий диск.
Причина, по которой при извлечении кеша появляются два разных кода состояния 200 и 304, зависит от того, инициировал ли браузер запрос проверки на сервер. Код состояния 304 будет возвращен только в том случае, если на сервер будет отправлен запрос аутентификации, а кеш не был обновлен.
Здесь я беру nginx в качестве примера, чтобы рассказать о том, как настроить кеш:
Во-первых, давайте войдем в документ конфигурации nginx
$ vim nginxPath/conf/nginx.conf
Вставьте следующие два элемента в документ конфигурации:
etag on; //开启etag验证
expires 7d; //设置缓存过期时间为7天
Откройте наш веб-сайт и наблюдайте за нашими ресурсами запроса в сетевой панели chrome devtools.Если вы видите поля Etag и Expires в заголовке ответа, это означает, что наша конфигурация кеша прошла успешно.
【! ! ! обращать внимание! ! ! ] Когда мы настраиваем кеш, мы должны помнить, что когда браузер обрабатывает запросы пользователей, если он попадает в сильный кеш, браузер будет напрямую извлекать локальный кеш без какой-либо связи с сервером.То есть, если мы обновляем серверную часть Если файл будет удален, он не будет известен браузеру, и недействительный кеш нельзя будет заменить. Поэтому на этапе построения нам нужно добавить суффикс хеша md5 к нашим статическим ресурсам, чтобы избежать проблемы, связанной с тем, что интерфейсные и внутренние файлы не могут быть синхронизированы из-за обновления ресурсов.
1.2. Упаковка и сжатие ресурсов
Работа по кэшированию браузера, которую мы выполняли ранее, может быть эффективной только тогда, когда пользователь посещает нашу страницу во второй раз.Если мы хотим добиться хорошей производительности, когда пользователь открывает страницу в первый раз, мы должны оптимизировать ресурсы. Мы часто объединяем меры по оптимизации производительности сети в три основных аспекта: сокращение количества запросов, уменьшение объема запрашиваемых ресурсов и увеличение скорости передачи по сети. Теперь давайте разберем его по одному:
В сочетании с передовыми инженерными идеями нам обычно требуется помощь инструментов упаковки, когда мы автоматизируем упаковку и компиляцию онлайн-файлов.Здесь я рекомендую веб-пакет, я обычно использую Gulp и Grunt для компиляции узла, Parcel слишком новый, а веб-пакет был По своим характеристикам ближе к Parcel.
При настройке вебпака онлайн мы должны обратить особое внимание на следующие моменты:
①Сжатие JS: (это должно считаться знакомым, поэтому я не буду вводить его дальше)
new webpack.optimize.UglifyJsPlugin()
②HTML-сжатие:
new HtmlWebpackPlugin({
template: __dirname + '/views/index.html', // new 一个这个插件的实例,并传入相关的参数
filename: '../index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
chunksSortMode: 'dependency'
})
мы используемhtml-webpack-plugin
При автоматическом инжекте JS и CSS для упаковки HTML-файлов в него крайне редко добавляются элементы конфигурации, здесь я привожу пример, можно просто скопировать напрямую.
PS: Вот хитрость в нашем написании HTML-элементаsrc
илиhref
При использовании атрибута часть протокола может быть опущена, что также может просто сэкономить ресурсы.
③Извлечь общедоступные ресурсы:
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'scripts/common/vendor-[hash:5].js'
})
PS: Вот синтаксис webpack3, который был изменен в webpack4, надеюсь все обратят внимание
④ Извлеките css и сожмите:
В процессе использования вебпака мы обычно вводим css файлы в виде модулей (идея вебпака в том, что все является модулем), но когда мы выходим в интернет, нам тоже нужно извлекать и сжимать эти css файлы. сложный процесс требует всего несколько простых строк конфигурации:
(PS: нам нужно использоватьextract-text-webpack-plugin
, так что вы должны сделать это самиnpm install
)
const ExtractTextPlugin = require('extract-text-webpack-plugin')
module: {
rules: [..., {
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: {
loader: 'css-loader',
options: {
minimize: true
}
}
})
}]
}
⑤ Используйте новые функции webpack3: ModuleConcatenationPlugin
new webpack.optimize.ModuleConcatenationPlugin()
Если вы можете полностью настроить онлайн-конфигурацию вебпака в соответствии с вышеуказанными пятью пунктами, вы можете в принципе сжать объем файлового ресурса до предела.Если есть какие-то упущения, я надеюсь, вы можете это добавить.
Я дам вам копию моего онлайн-документа по настройке webpack, пожалуйста, обратитесь к:
//webpack.pro.js
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
entry: __dirname + '/public/scripts/index.js',
output: {
path: __dirname + '/build/static', // 打包后的文件存放的地方
filename: 'scripts/[name]-[hash:5].js' // 打包后输出文件的文件名,带有md5 hash戳
},
resolve: {
extensions: ['.jsx', '.js']
},
module: {
rules: [{
test: /(\.jsx|\.js)$/,
use: {
loader: 'babel-loader'
},
exclude: /node_modules/ // 不进行编译的目录
}, {
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: {
loader: 'css-loader',
options: {
minimize: true
}
}
})
}]
},
plugins: [
new HtmlWebpackPlugin({
template: __dirname + '/views/index.html',
filename: '../index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
chunksSortMode: 'dependency'
}),
new ExtractTextPlugin('styles/style-[hash:5].css'),
new CleanWebpackPlugin('build/*', {
root: __dirname,
verbose: true,
dry: false
}),
new webpack.optimize.UglifyJsPlugin(),
new CopyWebpackPlugin([{
from: __dirname + '/public/images',
to: __dirname + '/build/static/images'
}, {
from: __dirname + '/public/scripts/vector.js',
to: __dirname + '/build/static/scripts/vector.js'
}]),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
filename: 'scripts/common/vendor-[hash:5].js'
})
]
}
Наконец, мы также должны включить сжатие передачи Gzip на сервере. Он может сжимать наши текстовые файлы до четверти исходного размера, и эффект будет немедленным. Переключитесь на наш файл конфигурации nginx и добавьте следующие два элемента конфигурации:
gzip on;
gzip_types text/plain application/javascriptapplication/x-javascripttext/css application/xml text/javascriptapplication/x-httpd-php application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
Если вы видите такое поле в заголовке ответа на запрос веб-сайта, это означает, что наша конфигурация сжатия Gzip прошла успешно:
【! ! ! обращать внимание! ! ! 】 Не сжимайте файл изображения! Не выполняйте сжатие Gzip для файлов изображений! Не выполняйте сжатие Gzip для файлов изображений! Скажу только, что эффект соответствующий.Что касается конкретной причины, я должен учитывать степень сжатия процессора в процессе сжатия сервера.Сжатие картинки не только займет много ресурсов, но и эффект сжатия незначителен, можно сказать, что он «неудобен», поэтому, пожалуйста,gzip_types
Удалите связанные элементы изображения. Для связанной обработки картины мы представим более конкретно.
1.3. Оптимизация ресурсов изображения
Мы только что ввели упаковку ресурсов и сжатие, но это осталось на уровне кода.В нашей реальной разработке не эти файлы, а изображения действительно занимают много ресурсов передачи по сети.Если вы оптимизируете изображения, вы увидите видимые результаты. сразу видно.
1.3.1. Не масштабируйте изображения в HTML
У многих разработчиков может быть такая иллюзия (на самом деле я раньше был таким), например, мы будем для удобства напрямую использовать картинку 400✖400 в контейнере картинок 200✖200. Мы даже думаем, что это заставит пользователей чувствовать себя Картинка четче, на самом деле ее нет На обычном мониторе пользователь не почувствует, что увеличенная большая картинка четче, но все это приводит к снижению скорости разгона веб-страницы и трате пропускной способности. Вы можете не знать, что файл 200Кб Время передачи картинок и 2М картинок будет разница между 200мс и 12с (личный опыт, страдаю от этого (┬_┬)). Поэтому, когда вам нужно использовать большое изображение, подготовьте большое количество изображений на сервере и постарайтесь зафиксировать размер изображения.
1.3.2 Использование CSS-спрайтов
Вы, должно быть, услышали концепцию карты спрайты в разработке. На самом деле, карта Sprite является примерным представителем снижения количества запросов. И удивительно, что после того, как несколько изображений собраны вместе, общий объем будет меньше, чем сумма всех предыдущих картинок (вы можете попробовать сами). Вот инструмент для автоматической генерации карт спрайтов:woohoo.topthem.com/developers/…(Изображение взято с главной страницы официального сайта)
Если вы добавите соответствующие файлы ресурсов, он автоматически создаст для вас изображения Sprite и соответствующие стили CSS.Все, что вам нужно сделать, это загрузить и скопировать.
1.3.3 Использование значков шрифтов (iconfont)
Будь то сжатое изображение или изображение Sprite, это все равно изображение, и пока это изображение, оно все равно будет занимать много сетевых ресурсов передачи. Но появление иконок шрифтов позволило фронтенд-разработчикам увидеть другой волшебный мир.
Мне больше всего нравится библиотека векторных иконок Али (URL:www.iconfont.cn/), в нем много ресурсов векторной графики, и вам нужно только добавить их в корзину, как и при покупке на Taobao, вы можете забрать их домой, и вы можете автоматически генерировать CDN-ссылки после сортировки ресурсов, которые можно сказать, идеальный.Дракон служил. (Изображение взято с главной страницы официального сайта)
Есть много вещей, которые могут делать картинки, и векторная графика, и она просто вставляет символы и стили CSS в HTML.По сравнению с запросами изображений, они совершенно разные с точки зрения ресурсов передачи по сети.Если в вашем проекте есть тонны маленькие значки, просто используйте векторную графику.
1.3.4 Использование WebP
Формат WebP — это формат изображений, разработанный Google для ускорения загрузки изображений. Объем сжатия изображения составляет всего около 2/3 от объема сжатия JPEG, и это может сэкономить много ресурсов пропускной способности сервера и места для данных. Известные веб-сайты, такие как Facebook и Ebay, начали тестировать и использовать формат WebP.
Мы можем использовать инструмент командной строки Linux, предоставленный на официальном веб-сайте, для кодирования WebP изображений в проекте, или мы можем использовать наш онлайн-сервис, здесь я рекомендую Forkpai Cloud (URL:www.upyun.com/webp). Однако в реальной онлайн-работе нам по-прежнему приходится писать шелл-скрипты и использовать инструменты командной строки для пакетного кодирования, а на этапе тестирования нам достаточно использовать онлайн-сервисы, что удобно и быстро. (Картинка взята с официального сайта Chapaiyun)
1.4. Инструмент обнаружения производительности передачи сети - скорость страницы
В дополнение к сетевым страницам, на самом деле, хром также подготовил для нас хороший плагин - мониторинг производительности сети передачи скорости страницы, наша статья на обложке, является официальной пропагандой с цифрой скорости страницы (потому что я думаю, что эта картинка очень уместно). Для установки нам нужны только следующие шаги, вы можете найти их в chrome devtools в: меню chrome → More → Tools → chrome развернуть программу после интернет-магазина приложений → поиск pagespeed безопасно включить.
(PS: Вам нужно перевернуть стену, чтобы использовать магазин приложений Chrome, поэтому я не буду больше говорить о том, как перевернуть стену)
Это функциональный интерфейс Page Speed:
Нам нужно только открыть веб-страницу для тестирования, а затем нажать кнопку «Начать анализ» в Page Speed, это автоматически поможет нам протестировать производительность передачи по сети, это результат теста моего веб-сайта:
Самая удобная часть Page Speed заключается в том, что она будет делать полные предложения по узким местам производительности тестового сайта, и мы можем оптимизировать работу в соответствии с ее подсказками. Здесь мой сайт оптимизирован до лучших показателей (•́⌄•́๑)૭✧, Page Speed Score означает ваш балл теста производительности, 100/100 означает, что оптимизировать некуда.
После оптимизации используйте сетевой раздел chorme devtools, чтобы измерить время белого экрана и время первого экрана нашей веб-страницы. Значительно ли это улучшилось?
1.5 Использование CDN
Последний, но тем не менее важный,
Независимо от того, насколько хорош экземпляр оптимизации производительности, он должен поддерживаться CDN, чтобы достичь предела.
Если мы используем команду под Linux$ traceroute targetIp
Или используйте пакетную обработку под Windows> tracert targetIp
, может найти все маршрутизаторы, пройденные между пользователем и целевым компьютером Само собой разумеется, что чем дальше расстояние между пользователем и сервером, тем больше маршрутизаторов проходит и тем выше задержка. Одной из целей использования CDN является решение этой проблемы, конечно, не только это, CDN также может разделить давление IDC.
Конечно, с нашей индивидуальной финансовой мощью (если вы не Ван Сиконг) мы не можем построить CDN, но мы можем использовать услуги, предоставляемые крупными компаниями, такими как Tencent Cloud и т. д. Конфигурация также очень проста.
Фактически, наше доменное имя CDN обычно отличается от основного доменного имени нашего веб-сайта.Вы можете взглянуть на официальные сайты Taobao и Tencent, чтобы увидеть, что доменные имена CDN, на которых они хранят статические ресурсы, отличаются от основного домена. название. почему ты хочешь сделать это? Есть две основные причины: [Содержимое взято из:Не совсем. aliyun.com/simple/he 116… ]
① Сервисам CDN удобно быть независимыми, а кеш можно настроить независимо. Чтобы уменьшить веб-давление, система CDN будет следовать стандартам HTTP-заголовков Cache-Control и Expires для кэширования содержимого, возвращаемого запросом на изменение, чтобы последующие запросы не возвращались к источнику, что может ускорить работу функции. В традиционном методе CDN (имя общего домена в Интернете и CDN) необходимо установить соответствующие правила кэширования для разных типов файлов или следовать внутренним HTTP-заголовкам, но воспользоваться преимуществами CDN сложно, потому что вероятность динамических запросов обратно к источнику очень велика. , если линия между посетителем и исходным сайтом не медленная, запрос через CDN может быть не быстрее, чем прямой запрос к исходному сайту. Чтобы максимально повысить производительность веб-сайтов, крупные веб-сайты обычно устанавливают большие заголовки кеша. Например, Google JS устанавливает кеш на один год, а логотип главной страницы Baidu устанавливает кеш на десять лет. Если вы извлекаете статические элементы, вы можно легко развернуть правила для всех статических элементов, независимо от динамических запросов. Сокращение количества правил может повысить эффективность CDN.
②Откажитесь от бесполезных файлов cookie и уменьшите использование полосы пропускания. Мы все знаем, что протокол HTTP будет автоматически добавлять файлы cookie под доменное имя и имя родительского домена каждый раз при отправке запроса, но для ресурсов CSS, JS и изображений эти файлы cookie бесполезны, но будут тратить пропускную способность посетителя и сервер. входящая полоса пропускания. Наш основной сайт, чтобы поддерживать сессию или делать другое кеширование, будет хранить большое количество куки, поэтому, если CDN и доменное имя основного сайта разделены, эту проблему можно решить.
Однако при этом возникает новая проблема: доменное имя CDN отличается от доменного имени основного сайта, и DNS требуется дополнительное время для разрешения доменного имени CDN, что увеличивает задержку в сети. Но это не может помочь нашим великим предшественникам-программистам, дебюту DNS Prefetch.
Если вы посмотрите на исходный код HTML большого веб-сайта, вы найдете такую ссылку в заголовке: (здесь в качестве примера используется домашняя страница Taobao)
Это предварительная выборка DNS. Предварительная выборка DNS — это технология предварительного разрешения DNS.Когда мы просматриваем веб-страницу, браузер предварительно разрешает и кэширует доменное имя на веб-странице при загрузке веб-страницы, чтобы, когда браузер загружает ссылки на веб-странице , нет необходимости в разрешении DNS. , сократите время ожидания пользователя и улучшите взаимодействие с пользователем. Предварительная выборка DNS теперь поддерживается основными браузерами. Большинство браузеров оптимизированы для разрешения DNS. Типичное разрешение DNS занимает от 20 до 120 мс. Это хорошая мера оптимизации, позволяющая сократить время и время разрешения DNS. Вот карта поддержки DNS Prefetch на официальном сайте Can I use it:
Так что смело используйте его.
2. Оптимизация производительности рендеринга страницы
2.1 Процесс рендеринга в браузере (Webkit)
На самом деле, вы должны быть знакомы с механизмом рендеринга HTML в браузере.Основной процесс такой же, как на картинке выше.Когда вы начинаете, ваш инструктор или старший может сказать вам, что нам нужно уменьшить перестановку и перерисовку с точки зрения рендеринга, т.к. они могут повлиять на производительность браузера. Но вы не должны знать, что такое принцип, верно? Сегодня мы объединим актуальные знания "Webkit Technology Insider" (все равно всем рекомендую купить и прочитать эту книгу. В любом случае, как фронтенд-инженер, вы должны знать, как работает ядро браузера, к которому мы прикасаемся каждый день), чтобы дать Мы популяризируем эти глубоко укоренившиеся концепции.
PS: Здесь упоминается ядро Webkit, и я упомяну взаимосвязь между движком рендеринга, интерпретатором и другими компонентами внутри браузера, потому что часто младшие братья или какие-то энтузиасты фронтенда спрашивают меня об этих знаниях, и я могу' т рассказать отношения между ними.Я сделаю снимок для иллюстрации: (Эта часть не имеет ничего общего с этой статьей, если вам это не интересно, вы можете сразу пропустить его)
Интерпретатор браузера включен в механизм рендеринга.Мы часто ссылаемся на Chrome (теперь использующий движок Blink) и движок Webkit, используемый Safari, и на движок Gecko, используемый Firefox, который относится к движку рендеринга. В механизме рендеринга он также включает наш интерпретатор HTML (используемый для построения дерева DOM во время рендеринга), интерпретатор CSS (используемый для синтеза правил CSS во время рендеринга) и наш интерпретатор JS. Однако позже, по мере того, как использование JS становилось все более важным и работа становилась все более сложной, интерпретатор JS постепенно стал самостоятельным и превратился в отдельный JS-движок. часто связывались и используют его.
2.2. Уровень рендеринга DOM и аппаратное ускорение графического процессора
Если я скажу вам, что страница состоит из многих, многих уровней, они похожи на лазанью, как вы можете себе представить, как на самом деле выглядит эта страница? Чтобы облегчить это, как мы представляем, я добавляю страницу перед тем, как плагин Firefox предоставляет иерархическую диаграмму 3D View Layers:
Да, вы не ошиблись, реальный вид страницы таков, что он состоит из нескольких слоев рендеринга элементов DOM (слоев).На самом деле, после построения дерева рендеринга он испытал такой процесс, который в конечном итоге представлен в нас Перед:
① Браузер сначала получит дерево DOM и разделит его на несколько независимых слоев рендеринга в соответствии со стилем.
②ЦП рисует каждый слой в чертеже
③ Загрузите растровое изображение в виде текстуры в GPU (видеокарту) для рисования.
④Графический процессор кэширует все слои рендеринга (если слой рендеринга, загруженный в следующий раз, не изменится, графическому процессору не нужно его перерисовывать) и объединяет несколько слоев рендеринга, чтобы окончательно сформировать наше изображение.
Из приведенных выше шагов мы можем знать, что макет обрабатывается ЦП, а рисование выполняется графическим процессором.
Фактически, в Chrome, он также предоставляет нам соответствующие плагины для нас для просмотра распределения слоя рендеринга страниц и скорости размещения GPU: (Итак, мы обычно должны пробовать эти необъяснимые плагины Chrome, и мы найдем много из них. Все - артефакт)
Меню инструментов разработчика Chrome→дополнительные инструменты→Слои (откройте функциональный модуль слоя рендеринга)
Меню инструментов разработчика Chrome→дополнительные инструменты→рендеринг (открыть инструмент мониторинга производительности рендеринга)
После выполнения вышеуказанной операции вы увидите такой эффект в браузере:
Слишком много всего, давайте поговорим о модулях:
(1) Во-первых, это маленькое черное окошко в правом верхнем углу страницы: на самом деле, подсказка уже очень ясно сказала об этом.Он показывает уровень загрузки нашего GPU, что позволяет нам четко знать, имеет ли большое количество перерисовок произошло на странице.
(2) Раздел «Слои»: это инструмент, используемый для отображения только что упомянутого слоя рендеринга DOM.В списке слева перечислены слои рендеринга, существующие на странице, а также подробная информация об этих слоях рендеринга.
(3) Раздел рендеринга: этот раздел находится в том же месте, что и наша консоль, поэтому не найдите его. Первые три клещей - это те, которые мы используем больше всего, позвольте мне объяснить свою функцию (ACT в качестве бесплатного переводчика)
①Проблеск краски: после проверки элементы, которые перерисовываются на странице, будут выделены.
②Границы слоя: как и в разделе «Слой», он будет выделять каждый слой рендеринга на нашей странице с выделенными границами.
③ Измеритель FPS: нужно открыть маленькое черное окошко, о котором мы упоминали в (1), чтобы увидеть уровень загрузки нашего графического процессора.
Может быть, вы спросите меня, а какой смысл упоминать такое глубокое понятие слоя рендеринга DOM, которое, кажется, не имеет ничего общего с оптимизацией производительности? Вы должны помнить, что я только что сказал, что GPU будет кэшировать наш слой рендеринга, верно? Тогда представьте, если мы извлечем элементы, которые были сильно переставлены и перерисованы, и вызовем слой рендеринга отдельно, то этот элемент В противном случае он не будет «задействовать» другие элементы и перерисовать их вместе, верно?
Итак, вопрос в том, при каких обстоятельствах будет запущен слой рендеринга? Просто помни:
Видеоэлементы, WebGL, Canvas, CSS3 3D, фильтры CSS и элементы, чьи Z-индекс больше, чем соседний узел, будет вызвать новый слой. На самом деле наиболее часто используемый метод состоит в том, чтобы добавить следующие стили к элементу:
transform: translateZ(0);
backface-visibility: hidden;
Это активирует слой рендеринга.
Мы отделяем элементы, которые легко инициировать переупорядочение и перерисовку, чтобы вызвать уровень рендеринга, изолируем его от этих «статических» элементов и позволяем графическому процессору совместно использовать больше работы по рендерингу.Мы обычно называем такие меры аппаратным ускорением или ускорением графического процессора. Вы, должно быть, слышали это утверждение раньше, и теперь вы полностью понимаете, как оно работает.
2.3. Перекомпоновка и перерисовка
Теперь к нашему главному событию, перестановке и перерисовке. Сначала выбросьте концепцию:
① Перекомпоновка: макет элементов в слое визуализации изменяется, что приводит к изменению порядка страницы, например, изменение размера окна, удаление или добавление элементов DOM и изменение свойств CSS, влияющих на размер поля элемента. (такие как: ширина, высота, отступы).
②Перекрашивание: рисование, то есть рендеринг и раскрашивание, все изменения атрибутов визуальной производительности элемента приведут к перекрашиванию.
Мы привыкли использовать раздел производительности chrome devtools для измерения времени, необходимого для перекомпоновки и перерисовки страницы:
①Синяя часть: время, затрачиваемое на синтаксический анализ HTML и обмен данными по сети.
②Желтая часть: время, затраченное на выполнение оператора JavaScript.
③Фиолетовая часть: изменить занятое время
④ Зеленая часть: перерисовка требует времени
Либо перекомпоновка, либо перерисовка заблокируют браузер. Чтобы повысить производительность веб-страницы, необходимо снизить частоту и стоимость перекомпоновки и перерисовки, а также уменьшить вероятность повторной отрисовки. Как мы упоминали в 2.3, переупорядочение обрабатывается ЦП, а перерисовка обрабатывается ГП, эффективность обработки ЦП намного меньше, чем у ГП, и переупорядочение определенно вызовет перерисовку, а перерисовка не обязательно приведет к перераспределению. . Поэтому в работе по оптимизации производительности мы должны больше сосредоточиться на снижении частоты перестановок.
Вот рекомендуемый веб-сайт, на котором подробно перечислены свойства CSS, вызывающие перекомпоновку или перерисовку в различных механизмах рендеринга:
csstriggers.com/(картинка взята с официального сайта)
2.4 Стратегия оптимизации
После разговоров о стольких теориях самое практичное решение.Все должны спешить.Приготовьтесь к большой волне галантерейных товаров:
(1) Разделение чтения и записи свойств CSS: каждый раз, когда браузер читает стиль элемента, он должен повторно отображать (переставлять + перерисовывать), поэтому, когда мы используем JS для чтения и записи стиля элемента, самое лучшее чтобы разделить их, сначала прочитайте, а затем запишите, чтобы избежать ситуации, когда они используются взаимозаменяемо. Самое объективное решение — манипулировать стилями элементов без JS, что я и рекомендую больше всего.
(2) Пакетное управление стилями элементов путем переключения классов или использования свойства элемента style.csstext.
(3) Автономное обновление элементов DOM: при выполнении связанных операций с DOM, например, appendChild и т. д., можно использовать объект «Фрагмент документа» для выполнения автономных операций и снова вставить страницу после «сборки» элемента, или использоватьdisplay:none
Скройте элемент и выполните соответствующие операции после того, как элемент «исчезнет».
(4) Сделать бесполезные элементы невидимыми:visibility: hidden
Это снижает нагрузку на перерисовку, и элементы отображаются при необходимости.
(5) Сжимайте глубину DOM, не используйте слишком глубокие подэлементы в слое рендеринга, используйте меньше DOM для завершения стиля страницы и вместо этого используйте больше псевдоэлементов или box-shadow.
(6) Укажите размер изображения перед рендерингом: Поскольку элемент img является встроенным элементом, ширина и высота будут изменены после загрузки изображения. В тяжелых случаях вся страница будет перестроена, поэтому лучше указать его размер перед рендерингом или убрать его из потока документов.
(7) Активируйте слой рендеринга отдельно для элементов на странице, которые могут быть переупорядочены и перерисованы много раз, и используйте GPU, чтобы распределить нагрузку на CPU. (Эту стратегию следует использовать с осторожностью, и важно учитывать, можно ли ожидать оптимизации производительности за счет загрузки графического процессора. В конце концов, слишком много слоев рендеринга на странице также являются ненужной нагрузкой для графического процессора. Обычно В этом случае мы аппаратно ускоряем анимированные элементы.)
3. Производительность блокировки JS
JavaScript почти занял монопольное положение в разработке веб-сайтов.Даже если это простая статическая страница, вы можете увидеть существование JS.Можно сказать, что без JS веб-сайт в основном попрощается с взаимодействием с пользователем. Однако проблема скрипта в том, что он блокирует параллельную загрузку страницы и увеличивает загрузку процессора процессом. Более того, теперь, когда node.js популяризировался во фронтенд-разработке, если мы немного непреднамеренны, мы вызовем утечку памяти или напишем бесконечный цикл в коде по ошибке, что напрямую приведет к сбою нашего сервера. В нынешнюю эпоху, когда JS распространился по всему переднему и заднему концам, узкое место в производительности не только влияет на пользовательский опыт, но и будет возникать все больше и больше серьезных проблем.Не следует недооценивать оптимизацию производительности JS.
В процессе программирования, если мы используем замыкание и не освобождаем соответствующие ресурсы, или обращаемся к внешней цепочке и не очищаем ее (например, обратный вызов события привязывается к элементу DOM, но элемент удаляется позже ) вызовет утечку памяти, которая займет много ресурсов ЦП пользователя, что приведет к зависаниям или сбоям. Мы можем использовать раздел «Профиль JavaScript», предоставляемый хромом, который открывается так же, как разделы «Слои» и другие.Я не буду здесь говорить больше, просто перейду непосредственно к рендерингу:
Мы можем четко видеть время выполнения и загрузку ЦП каждой функции при выполнении JS.Если я добавлю строку в кодwhile(true){}
, то его заполняемость обязательно взлетит до аномального показателя (93,26% в про-тесте).
На самом деле, мощный механизм рециркуляции памяти браузера позволяет избежать этой ситуации большую часть времени.Даже если у пользователя произошел сбой, он может решить эту проблему, завершив соответствующий процесс (или закрыв браузер), но мы должны знать, что та же ситуация будет также происходят на стороне нашего сервера, то есть в нашем узле.В тяжелых случаях это напрямую приведет к сбою нашего сервера и сбою веб-сайта. Поэтому чаще всего мы используем раздел «Профиль JavaScript» для стресс-тестирования наших узловых служб сnode-inspector
Плагин, мы можем более эффективно определять использование ЦП каждой функцией при выполнении JS и соответствующим образом оптимизировать его.
(PS: Так что, если вы не доросли до определенного уровня, не используйте замыкания на стороне сервера. Во-первых, это действительно бесполезно. У нас будет больше отличных решений. Во-вторых, это очень легко утечка памяти, а последствий ожидать не приходится)
4. [Расширение] Балансировка нагрузки
Причина, по которой балансировка нагрузки используется в качестве расширения, заключается в том, что если вы создаете свой собственный личный веб-сайт или веб-сайт малого и среднего размера, вам не нужно учитывать степень параллелизма, но если вы создаете большой веб-сайт, балансировка нагрузки это процесс разработки.необходимый шаг.
4.1. Node.js обрабатывает запросы с интенсивным вводом-выводом
Текущий процесс разработки обращает внимание на разделение передней и задней части, что является идеей «высокой сплоченности и низкой связанности», часто упоминаемой в разработке программного обеспечения.Вы также можете использовать идею модульности, чтобы понять. а тыл эквивалентен разделению проекта на Фронтенд и Бэкенд модули связаны интерфейсами и разрабатываются отдельно. Какая польза от этого? Приведу самый практический момент: «асинхронное программирование». Это название я придумал сам, потому что я думаю, что форма передней и задней развязки очень похожа на асинхронную очередь в нашем JS. Традиционный режим разработки — «синхронный». инкапсулировать интерфейс и знать какие данные можно взять., а потом разрабатывать, времени мало, проект большой. После разделения нам нужно только заранее согласовать интерфейс, и передняя и задняя части могут быть разработаны одновременно, что не только эффективно, но и экономит время.
Все мы знаем, что ядро узла управляется событиями. Он использует цикл событий для асинхронной обработки пользовательских запросов. По сравнению с традиционными серверными службами все они назначают процесс каждому запросу пользователя для обработки. Рекомендуется прочитать это статья. Запись в блоге:Tickets.WeChat.QQ.com/Yes?__Author=M za…. Механизм работы, управляемый событиями, объяснен особенно ярко и легко для понимания. В чем самое большое преимущество управления событиями? То есть, когда есть высокий параллельный ввод-вывод, это не вызовет блокировки.Для веб-сайтов прямых трансляций это очень важно.У нас есть успешный прецедент - Kuaishou, мощный высокий параллелизм ввода-вывода Kuaishou должен быть прослежен до узла.
Фактически, сегодняшние веб-сайты корпоративного уровня будут строить уровень узла в качестве среднего уровня. Примерный каркас сайта показан на рисунке:
4.2.pm2 реализует «многопроцессность» Node.js
Мы все знаем плюсы и минусы узла. Вот ссылка, чтобы поделиться. После долгого поиска я подробно написал:Ууху. Call.com/question/19…. На самом деле, многие из них являются старыми подпрограммами.Те, кто говорят, что узел не годится, указывают на слабость, что узел - это единый процесс.Позвольте мне сказать вам, что у нас есть решение - pm2. Это его официальный сайт:pm2.keymetrics.io/. Это менеджер процессов node.js, Конкретная функция состоит в том, чтобы запустить службу node.js в каждом ядре вашего компьютера, то есть, если ваш компьютер или сервер является многоядерным процессором (теперь также редко см. одно ядро), он может запускать несколько сервисов node.js, а также может автоматически управлять балансировкой нагрузки и автоматически распределять пользовательские запросы на менее напряженные сервисные процессы для обработки. Похоже, эта штука — волшебное оружие! И его функций гораздо больше, я не буду вводить здесь слишком много, все знают, что нам нужно использовать его, когда мы выходим в интернет, и метод установки также очень прост, просто используйте npm для загрузки в глобальную$ npm i pm2 -g
Информацию об особенностях использования и связанных с ними функциях см. на официальном веб-сайте.
Ниже показан рендеринг pm2 после запуска:
4.3.nginx создает обратный агент
Прежде чем приступить к сборке, вы должны сначала узнать, что такое обратный прокси. Возможно, вы не знакомы с этим термином, поэтому давайте сначала сделаем снимок:
Так называемый прокси — это то, что мы обычно называем посредником.Обратный прокси веб-сайта относится к серверу между пользователем и нашим реальным сервером (я не могу этого сказать), и его функция заключается в распределении запроса пользователя. менее нагруженные серверы, механизм опроса. Звучит ли это знакомо после прослушивания этого предложения? Да, я сказал то же самое, когда представлял pm2. Роль обратного прокси-сервера заключается в достижении балансировки нагрузки, как и pm2. Теперь вы должны понять разницу между ними. обратный прокси-сервер предназначен для балансировки нагрузки на сервер, а pm2 — для балансировки нагрузки на процесс. Если вы хотите узнать больше об обратном прокси, я рекомендую пост на Zhihu:Ууху. Call.com/question/24…. Но все будут думать, что конфигурация сервера — это вопрос эксплуатации и обслуживания, какое это имеет отношение к нашему интерфейсу? Действительно, в этой части нашей работы немного, и нам нужно только предоставить документ конфигурации для эксплуатации и обслуживания.
http {
upstream video {
ip_hash;
server localhost:3000;
}
server {
listen: 8080;
location / {
proxy_pass: http://video
}
}
}
То есть при подключении к эксплуатации и техническому обслуживанию нам нужно всего лишь изменить приведенные выше строки кода на документы, которые мы настроили, и отправить его ему.Для других вещей брат по эксплуатации и техническому обслуживанию поймет, разумеется , Все в вине.
Но как изменить эти строки кода? Во-первых, мы должны знать, что в Nginx модуль делится на три категории: обработчик, фильтр и восходящий поток. Модуль UPStream отвечает за завершение приема, обработки и пересылки сетевых данных, а модуль, который нам нужно использовать в обратном агенте. Далее мы представим смысловое представление содержимого в коде конфигурации:
4.3.1.Информация о конфигурации восходящего потока
Идентификатор, следующий сразу за ключевым словом upstream, — это имя нашего пользовательского проекта, в которое мы добавляем нашу информацию о конфигурации с помощью пары фигурных скобок.
ip_hash
Ключевое слово: контролировать, подключается ли пользователь к ранее подключенному серверу, когда пользователь снова обращается к нему.
server
Ключевое слово: Адрес нашего реального сервера, содержимое здесь должно быть заполнено нами, иначе как эксплуатация и обслуживание узнают, что вы поставили проект на этот сервер, и не знают, что вы инкапсулировали слой узла и имеете слушать порт 3000 .
4.3.2.информация о конфигурации сервера
Сервер — это базовая конфигурация nginx.Нам нужно применить апстрим, который мы определили, к серверу через server.
listen
Ключевые слова: порт, который прослушивает сервер.
location
Ключевое слово: у него та же функция, что и у маршрутизации, о которой мы упоминали ранее на уровне узла, здесь нужно назначить запрос пользователя соответствующему восходящему каналу.
5. Расширенное чтение
Производительность и мониторинг веб-сайта - это сложный проект, и есть много, много последующих задач.То, что я упомянул ранее, это только вершина айсберга. При знакомстве со спецификациями разработки, это также требует накопления практического опыта. .
После прочтения многих книг, связанных с производительностью веб-сайтов, я все еще больше люблю "Мониторинг, анализ и оптимизация производительности больших веб-сайтов" под редакцией Тан Вэня. Знания в ней относительно новые и практичные. Урожай, просветление, я также надеюсь, что читатели кто интересуется производительностью, может прочитать эту книгу после прочтения моей статьи.
Оригинальный автор: IMWeb jerryOnlyZRJ
Первоисточник:Оптимизация производительности веб-сайта на практике — история с 12,67 до 1,06 с — Tencent Web Front-end Сообщество IMWeb Team
Wechat Mini Program Development - Регистрация на курс NEXT Degree горячая, заинтересованные друзья, нажмите на картинку, чтобы узнать подробности курса!