предисловие
性能优化
, тема, которую не может избежать каждый инженер. вот моя комбинацияMr.Max
Один из курсов , и кратко изложены некоторые методы оптимизации, надеюсь, он будет полезен всем, и будет продолжать обновляться в будущем.Те, кто хочет посмотреть видео, могут напрямую перейти к определенному курсу в онлайн-поиске. Исходный код демо и PPT являются условно общими (一个赞
👍), спасибо, ребята 😎
Первый личный блог
Лучшее время посадить дерево было десять лет назад, затем сейчас
демо
fe-оптимизировать исходный код
Презентация PPT (обязательно посмотрите, супер красавчик)
онлайн предварительный просмотр
Исходный код fe-ppt PPT, созданный с помощью HTML
Влияние на производительность внешнего интерфейса (многословное предупреждение ❗️❗️❗️)
Важным показателем производительности интерфейса является время загрузки страницы, которое зависит не только от пользовательского опыта, но и от рейтинга в поисковых системах.
- Данные Google показывают, что страница с 10 фрагментами данных, которые можно загрузить за 0,4 секунды, превращается в 30 фрагментов данных, которые можно загрузить за 0,9 секунды, а трафик и доходы от рекламы снижаются.
90%
. - Размер файла домашней страницы Google Map от
100KB
сокращено до70-80KB
После этого трафик увеличился в первую неделю10%
, выросла в течение следующих трех недель25%
. - Цифры Amazon показывают: время загрузки увеличивается
100毫秒
, продажи下降1%
.
Итак: мой долг переосмыслить перфоманс 😎
1. Инструменты отладки
Наточите нож, не нарубив случайно дрова, а после окончания университета подработайте!
1. Сеть
Здесь вы можете увидеть детали загрузки ресурсов и изначально оценить влияние页面性能
элементы. Правой кнопкой мыши можно настроить вкладку, а внизу страницы находится обзор загруженных в данный момент ресурсов.DOMContentLoaded
время завершения рендеринга DOM,Load
: время загрузки всех ресурсов на текущей странице.
Мысли: как определить, какие ресурсы бесполезны для текущей загрузки страницы, и провести соответствующую оптимизацию?
shift + cmd + P, чтобы вызвать инструмент расширения консоли и добавить правила
Расширенный инструмент Больше жестов
водопад водопад
-
Queueing
Браузер поставил ресурс в очередь -
Stalled
Мертвое время из-за времени постановки в очередь -
DNS Lookup
Время разрешения DNS -
Initial connection
Время установить HTTP-соединение -
SSL
Время, когда браузер устанавливает безопасное соединение с сервером -
TTFB
Время ожидания возврата данных сервером -
Content Download
время загрузки браузера
2. Маяк
-
First Contentful Paint
Время рендеринга первого экрана, зеленый в течение 1 с -
Speed Index
Индекс скорости, зеленый в течение 4 с -
Time to Interactive
время до страницы с заменой
Согласно некоторым стратегиям Chrome, он автоматически оценивает качество веб-сайта и дает некоторые предложения по оптимизации.
3. Производительность
Самый профессиональный анализ сайта~ Я расскажу об этом много раз позже
4. Тест веб-страницы
Вы можете имитировать доступ в различных сценариях, таких как имитация разных браузеров, разных стран и т. д., адрес онлайн-теста:webPageTest
5. Анализ упаковки ресурсов
webpack-bundle-analyzer
npm install --save-dev webpack-bundle-analyzer
// webpack.config.js 文件
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
module.exports={
plugins: [
new BundleAnalyzerPlugin({
analyzerMode: 'server',
analyzerHost: '127.0.0.1',
analyzerPort: 8889,
reportFilename: 'report.html',
defaultSizes: 'parsed',
openAnalyzer: true,
generateStatsFile: false,
statsFilename: 'stats.json',
statsOptions: null,
logLevel: 'info'
}),
]
}
// package.json
"analyz": "NODE_ENV=production npm_config_report=true npm run build"
Включить исходную карту
webpack.config.js
module.exports = {
mode: 'production',
devtool: 'hidden-source-map',
}
package.json
"analyze": "source-map-explorer 'build/*.js'",
npm run analyze
2. ВЕБ-API
Если рабочий хочет хорошо работать, он должен сначала заточить свои инструменты. Некоторые аналитические API, предоставляемые браузерами至关重要
1. Отслеживайте статус активации окна
Вы посещали МООК в колледже? Видео остановится, как только вы отойдете от окна~
Или некоторые экзаменационные сайты, которые напоминают вам, что вы не можете выйти из текущего окна.
Или этот эффект~
// 窗口激活状态监听
let vEvent = 'visibilitychange';
if (document.webkitHidden != undefined) {
vEvent = 'webkitvisibilitychange';
}
function visibilityChanged() {
if (document.hidden || document.webkitHidden) {
document.title = '客官,别走啊~'
console.log("Web page is hidden.")
} else {
document.title = '客官,你又回来了呢~'
console.log("Web page is visible.")
}
}
document.addEventListener(vEvent, visibilityChanged, false);
На самом деле скрытых API много, вот тут можете попробовать, если интересно:
2. Наблюдайте за длинными задачами (Задача в исполнении)
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(entry)
}
})
observer.observe({entryTypes: ['longtask']})
3. Отслеживайте изменения в сети
Дайте пользователям обратную связь о проблемах с сетью при изменении сети. Иногда ваша сеть зависает при просмотре прямой трансляции. Платформа прямой трансляции также напомнит вам или автоматически переключит разрешение для вас.
var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
var type = connection.effectiveType;
function updateConnectionStatus() {
console.log("Connection type changed from " + type + " to " + connection.effectiveType);
type = connection.effectiveType;
}
connection.addEventListener('change', updateConnectionStatus);
4. Рассчитайте время DOMContentLoaded
window.addEventListener('DOMContentLoaded', (event) => {
let timing = performance.getEntriesByType('navigation')[0];
console.log(timing.domInteractive);
console.log(timing.fetchStart);
let diff = timing.domInteractive - timing.fetchStart;
console.log("TTI: " + diff);
})
5. Дополнительные правила расчета
DNS 解析耗时: domainLookupEnd - domainLookupStart
TCP 连接耗时: connectEnd - connectStart
SSL 安全连接耗时: connectEnd - secureConnectionStart
网络请求耗时 (TTFB): responseStart - requestStart
数据传输耗时: responseEnd - responseStart
DOM 解析耗时: domInteractive - responseEnd
资源加载耗时: loadEventStart - domContentLoadedEventEnd
First Byte时间: responseStart - domainLookupStart
白屏时间: responseEnd - fetchStart
首次可交互时间: domInteractive - fetchStart
DOM Ready 时间: domContentLoadEventEnd - fetchStart
页面完全加载时间: loadEventStart - fetchStart
http 头部大小: transferSize - encodedBodySize
重定向次数:performance.navigation.redirectCount
重定向耗时: redirectEnd - redirectStart
3. Клише, военные правила Yahoo
После заточки ножа стоит подумать о том, куда его воткнуть~ 🗡🗡🗡
Сколько правил вы знаете о военных правилах Yahoo и о каких из них вы обычно пишете? Для следующих правил мы можем сделать много работы по оптимизации
1. Уменьшите передачу файлов cookie
Передача файлов cookie расходует полосу пропускания и может:
- Уменьшите количество файлов, хранящихся в файлах cookie.
- Статические ресурсы не нуждаются в файлах cookie, можно использовать другие доменные имена, и файлы cookie не будут активно использоваться.
2. Избегайте чрезмерного оплавления и перерисовки
Непрерывно запускать операцию перекомпоновки страницы
let cards = document.getElementsByClassName("MuiPaper-rounded");
const update = (timestamp) => {
for (let i = 0; i <cards.length; i++) {
let top = cards[i].offsetTop;
cards[i].style.width = ((Math.sin(cards[i].offsetTop + timestamp / 100 + 1) * 500) + 'px')
}
window.requestAnimationFrame(update)
}
update(1000);
Посмотрите на эффект, очевидно, что коробка
performance
результаты анализов,load
Существует значительный обратный поток после события, иchrome
отмечены красным
использоватьfastDom
Для оптимизации дом读和写
разделять, объединять
let cards = document.getElementsByClassName("MuiPaper-rounded");
const update = (timestamp) => {
for (let i = 0; i < cards.length; i++) {
fastdom.measure(() => {
let top = cards[i].offsetTop;
fastdom.mutate(() => {
cards[i].style.width =
Math.sin(top + timestamp / 100 + 1) * 500 + "px";
});
});
}
window.requestAnimationFrame(update)
}
update(1000);
Посмотрите еще раз на эффект, он очень плавный~
performance
Результаты анализа, после события загрузки не так много красных меток
Если вам интересно, вы можете узнать о fastDom:github fastdomонлайн просмотр:fastdom demo
Мысли о разделении и объединении задач,react fiber
Архитектура очень впечатляет.Если вам интересно, вы можете узнать о практике алгоритма планирования в волокне.
4. Сжатие
Хм, убедитесь, что вы не ошиблись, и продолжайте!
1. Сжатие
Для получения информации о способе открытия см.:nginx включает gzip
Есть еще один способ: сгенерировать файлы gz во время упаковки и загрузить их на сервер, чтобы для сжатия не требовался nginx, что может снизить нагрузку на сервер. Вы можете обратиться к:Сжатые файлы gzip и конфигурация веб-пакета Compression-webpack-plugin
2. Сжатие сервера
server.js
const express = require('express');
const app = express();
const fs = require('fs');
const compression = require('compression');
const path = require('path');
app.use(compression());
app.use(express.static('build'));
app.get('*', (req,res) =>{
res.sendFile(path.join(__dirname+'/build/index.html'));
});
const listener = app.listen(process.env.PORT || 3000, function () {
console.log(`Listening on port ${listener.address().port}`);
});
package.json
"start": "npm run build && node server.js",
3. Сжатие JavaScript, Css, HTML
Соответствующие плагины можно использовать непосредственно в инженерных проектах.Существует три основных типа веб-пакетов:
- UglifyJS
- webpack-parallel-uglify-plugin
- terser-webpack-plugin
Конкретные преимущества и недостатки см.:Три плагина сжатия JS, обычно используемые webpack.压缩原理
Проще говоря, нужно удалить некоторые пробелы, переводы строк и комментарии, а также использовать функцию модуляризации es6, чтобы выполнить некоторые действия.tree-shaking
Оптимизация. При этом делается некоторая обфускация кода, с одной стороны, для меньшего размера, с другой стороны, для безопасности исходного кода.
Сжатие CSS — это в основном плагин mini-css-extract-plugin, конечно, предыдущий плагин сжатия js также сделает сжатие CSS за вас. Используйте позу:
npm install --save-dev mini-css-extract-plugin
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
plugins:[
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
]
можно использовать сжатие htmlHtmlWebpackPlugin
, одностраничный проект имеет только один index.html, а прирост производительности минимален~
4. Сжатие заголовка http2
Особенности http2
- Бинарное кадрирование
- сжатие заголовка
- управление потоком
- мультиплексирование
- приоритет запроса
- пуш сервера
http2_push: 'xxx.jpg'
Конкретный метод обновления также очень прост, измените конфигурацию nginx, сделайте это самостоятельно.Google
Пять, оптимизация веб-пакета
Некоторые плагины для веб-пакетов также упомянуты выше, позвольте мне посмотреть, что еще есть~
1. DllPlugin повышает скорость сборки
пройти черезDllPlugin
Плагины, разделите несколько относительно больших пакетов, которые редко обновляются, и создайтеxx.dll.js
файл, черезmanifest.json
Цитировать
webpack.dll.config.js
const path = require("path");
const webpack = require("webpack");
module.exports = {
mode: "production",
entry: {
react: ["react", "react-dom"],
},
output: {
filename: "[name].dll.js",
path: path.resolve(__dirname, "dll"),
library: "[name]"
},
plugins: [
new webpack.DllPlugin({
name: "[name]",
path: path.resolve(__dirname, "dll/[name].manifest.json")
})
]
};
package.json
"scripts": {
"dll-build": "NODE_ENV=production webpack --config webpack.dll.config.js",
},
2, распаковка разделенных фрагментов
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
name: 'vendor',
test: /[\\/]node_modules[\\/]/,
minSize: 0,
minChunks: 1,
priority: 10,
chunks: 'initial'
},
common: {
name: 'common',
test: /[\\/]src[\\/]/,
chunks: 'all',
minSize: 0,
minChunks: 2
}
}
}
},
6. Скелетный экран
Используйте CSS, чтобы заранее занять хорошую позицию, а ее можно заполнить при загрузке ресурса, уменьшив перекомпоновку и перерисовку страницы, и в то же время предоставив пользователю самую прямую обратную связь. Плагины, использованные на рисунке:react-placeholder
Есть много способов реализовать каркасный экран, используяPuppeteer
Много рендеринга на стороне сервера
Используйте псевдоклассы css:Решение каркасного экрана, которое можно реализовать только с помощью css
и т.д
7. Работа с окнами
Принцип: загружайте только те элементы DOM, которые могут отображаться в текущем окне.При изменении вида удалите скрытые и добавьте отображаемые элементы DOM, чтобы количество элементов DOM на странице никогда не было маленьким, а страница не застрянет.
В картинке использованы плагины:react-window
Установить:npm i react-window
Вводить:import { FixedSizeList as List } from 'react-window';
использовать:
const Row = ({ index, style }) => (
<div style={style}>Row {index}</div>
);
const Example = () => (
<List
height={150}
itemCount={1000}
itemSize={35}
width={300}
>
{Row}
</List>
);
8. Кэш
1. HTTP-кеш
keep-alive
Чтобы определить, открывать ли: см.response headers
Есть лиConnection: keep-alive
. После открытия см.network
не в водопадеInitial connection
кропотливый
nginx устанавливает keep-alive (открыт по умолчанию)
# 0 为关闭
#keepalive_timeout 0;
# 65s无连接 关闭
keepalive_timeout 65;
# 连接数,达到100断开
keepalive_requests 100;
Cache-Control / Expires / Max-Age
Установите, кэшируется ли ресурс, и время кэширования
Etag / If-None-Match
Сравнивается уникальный идентификатор ресурса, и если есть изменения, ресурс извлекается с сервера. Если изменений нет, ресурс кеша занят, а код состояния равен 304, то есть кэш согласования
Last-Modified / If-Modified-Since
Сравнивая разницу во времени, чтобы решить, следует ли получать ресурсы с сервера
Для получения дополнительных параметров кэша HTTP см.:Использование кэширования HTTP: Etag, Last-Modified и Cache-Control
2. Сервисный работник
С помощью плагина webpackWorkboxWebpackPlugin
иManifestPlugin
, загрузить serviceWorker.js, передатьserviceWorker.register()
регистр
new WorkboxWebpackPlugin.GenerateSW({
clientsClaim: true,
exclude: [/\.map$/, /asset-manifest\.json$/],
importWorkboxFrom: 'cdn',
navigateFallback: paths.publicUrlOrPath + 'index.html',
navigateFallbackBlacklist: [
new RegExp('^/_'),
new RegExp('/[^/?]+\\.[^/]+$'),
],
}),
new ManifestPlugin({
fileName: 'asset-manifest.json',
publicPath: paths.publicUrlOrPath,
generate: (seed, files, entrypoints) => {
const manifestFiles = files.reduce((manifest, file) => {
manifest[file.name] = file.path;
return manifest;
}, seed);
const entrypointFiles = entrypoints.app.filter(
fileName => !fileName.endsWith('.map')
);
return {
files: manifestFiles,
entrypoints: entrypointFiles,
};
},
}),
Девять, предварительная загрузка и отложенная загрузка
1. Предварительная загрузка
В качестве примера возьмем шрифт в демо, нормальный порядок загрузки следующий:
加入preload:
<link rel="preload" href="https://fonts.gstatic.com/s/longcang/v5/LYjAdGP8kkgoTec8zkRgqHAtXN-dRp6ohF_hzzTtOcBgYoCKmPpHHEBiM6LIGv3EnKLjtw.119.woff2" as="font" crossorigin="anonymous"/>
<link rel="preload" href="https://fonts.gstatic.com/s/longcang/v5/LYjAdGP8kkgoTec8zkRgqHAtXN-dRp6ohF_hzzTtOcBgYoCKmPpHHEBiM6LIGv3EnKLjtw.118.woff2" as="font" crossorigin="anonymous"/>
<link rel="preload" href="https://fonts.gstatic.com/s/longcang/v5/LYjAdGP8kkgoTec8zkRgqHAtXN-dRp6ohF_hzzTtOcBgYoCKmPpHHEBiM6LIGv3EnKLjtw.116.woff2" as="font" crossorigin="anonymous"/>
2. Предварительная выборка
Сценарий: первой странице не нужен такой файл шрифта, следующей странице нужен: первая страница будет загружена заранее с самым низким приоритетом Самый низкий
加入prefetch:
<link rel="prefetch" href="https://fonts.gstatic.com/s/longcang/v5/LYjAdGP8kkgoTec8zkRgqHAtXN-dRp6ohF_hzzTtOcBgYoCKmPpHHEBiM6LIGv3EnKLjtw.113.woff2" as="font"/>
<link rel="prefetch" href="https://fonts.gstatic.com/s/longcang/v5/LYjAdGP8kkgoTec8zkRgqHAtXN-dRp6ohF_hzzTtOcBgYoCKmPpHHEBiM6LIGv3EnKLjtw.118.woff2" as="font"/>
<link rel="prefetch" href="https://fonts.gstatic.com/s/longcang/v5/LYjAdGP8kkgoTec8zkRgqHAtXN-dRp6ohF_hzzTtOcBgYoCKmPpHHEBiM6LIGv3EnKLjtw.117.woff2" as="font"/>
нужная страница, изprefetch cache
Принимать
webpack также поддерживает эти два свойства:webpackPrefetch и webpackPreload
3. Ленивая загрузка
рисунок
机械图片
渐进式图片(类似高斯模糊)
Этот формат необходимо указать при публикации Miss UI.
响应式图片
Основной режим:<img src="./img/index.jpg" sizes="100vw" srcset="./img/dog.jpg 800w, ./img/index.jpg 1200w"/>
Отложенная загрузка маршрута
Реализуется функцией + импорт
const Page404 = () => import(/* webpackChunkName: "error" */'@views/errorPage/404');
10. ssr && реакция-щелчок
- Рендеринг SSR на стороне сервера, vue использует nuxt.js, react использует next.js
- react-snap может использовать Puppeteer для рендеринга сначала одной страницы, затем сохранять DOM и отправлять его клиенту
11. Оптимизация опыта
загрузка белого экрана
loading.htmlВам нужно забрать его самостоятельно, есть другой способ, используйтеwebpack
плагинHtmlWebpackPlugin
Вставьте загрузочный ресурс на страницу
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Loading</title>
<style>
body {
margin: 0;
}
#loadding {
position: fixed;
top: 0;
bottom: 0;
display: flex;
width: 100%;
align-items: center;
justify-content: center;
}
#loadding > span {
display: inline-block;
width: 8px;
height: 100%;
margin-right: 5px;
border-radius: 4px;
-webkit-animation: load 1.04s ease infinite;
animation: load 1.04s ease infinite;
}
@keyframes load {
0%,
100% {
height: 40px;
background: #98beff;
}
50% {
height: 60px;
margin-top: -20px;
background: #3e7fee;
}
}
</style>
</head>
<body>
<div id="loadding">
<span></span>
<span style="animation-delay: 0.13s"></span>
<span style="animation-delay: 0.26s"></span>
<span style="animation-delay: 0.39s"></span>
<span style="animation-delay: 0.52s"></span>
</div>
</body>
<script>
window.addEventListener("DOMContentLoaded", () => {
const $loadding = document.getElementById("loadding");
if (!$loadding) {
return;
}
$loadding.style.display = "none";
$loadding.parentNode.removeChild($loadding);
});
</script>
</html>
Небольшое объявление о приеме на работу
-
微医集团
больничная группа поддержки - Координаты: Ханчжоу, Чжэцзян
- Социальный рекрутинг 3 года + или 21 стажировка
- Электронная почта резюме:wujj@wedoctor.com
Больше оптимизаций производительности, следите за обновлениями~
Долго учился + организовывал такие Братья и сестры проходя мимо ставьте пожалуйста лайк👍, а если есть вопросы то можете оставить сообщение для обмена 😝
Справочная статья:
- Онлайн-видео мистера Макса определенного курса [Ссылка нарушает правила, ищите сами]
- 35 военных правил Yahoo для оптимизации производительности интерфейса
- практика webpack — использование webpack-bundle-analyzer
- nginx включает gzip
- Сжатые файлы gzip и конфигурация веб-пакета Compression-webpack-plugin
- Три плагина сжатия JS, обычно используемые webpack
- Решение каркасного экрана, которое можно реализовать только с помощью css
- Использование кэширования HTTP: Etag, Last-Modified и Cache-Control
- webpackPrefetch и webpackPreload