На работе я работал над инструментом BI в компании, чтобы предоставить бизнес-персоналу отчеты о визуализации данных, а конфигураторы отчетов могут создавать отчеты с помощью простых операций перетаскивания. Благодаря постоянному совершенствованию системы и продвижению эксплуатации и обслуживания у нас появляется все больше и больше пользователей. В это время отражаются все аспекты пользовательского опыта. Мы также остановили функциональную итерацию продукта и оптимизировали всю систему, чтобы улучшить взаимодействие с пользователем. Ниже приводится краткое изложение моей оптимизации интерфейсных проектов.
Оптимизация упаковки Webpack
используется в проектеWebpack
Версия 3.x, а оптимизированное решение по-прежнему основано на версии Webpack 3.x.Vue
Леса оптимизированы. Планируется обновление до 4.x. . .
Обобщил один раз передПрименение Webpack 2.x в проекте Vue2.x,упомянулWebpack
Некоторые схемы оптимизации проекта, ниже в качестве дополнения.
Включить сжатие
Я попытался включить gzip, и прямая выгода все еще относительно велика. Ниже приведен результат упаковки в реальном проекте.
-
Parsed
js, 1,38 млн.
-
Gizpped
js — 421,46 КБ
Благодаря анализу данных объем упаковки сократился на **70,28%**.
Чтобы открыть метод, измените файл конфигурации в скаффолдинге:/config/index.js
// 生产模式
build: {
productionGzip: true // 开启Gzip压缩
}
При этом серверnginx
Добавить элемент конфигурации
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 6;
gzip_types application/javascript text/plain application/x-javascript text/css application/xml text/javascript application/json;
gzip_vary on;
перезагружатьnginx
После обновления страницы вChrome develop tools
серединаNetwork
Посмотреть веб-ссылку
Request Headers
появляться вAccept-Encoding: gzip
От имени клиента можно понятьgzip
кодирование сжатия
Response Headers
появляться вContent-Encoding
От имени сервера укажитеgzip
Кодирование для сжатия данных
Эта пара ключевых слов заголовка запроса отображается вместе, указывая на то, что конфигурация выполнена успешно.
Использование плагина предварительной загрузки
💡 Используйте
Resource Hints
серединаpreloadиprefetchдля повышения производительности приложений.
оpreload
иprefetch
<link rel="preload">
Это подсказка ресурса, которая используется для указания ресурсов, которые будут использоваться вскоре после загрузки страницы, поэтому в процессе загрузки страницы мы хотим выполнить предварительную загрузку как можно скорее, прежде чем браузер начнет отображать основное тело.
<link rel="prefetch">
Это подсказка ресурса, которая говорит браузеру использовать время простоя для получения контента, который пользователь может посетить в будущем после загрузки страницы.
Настроить предварительную загрузку в Webpack
preload-webpack-plugin
даhtml-webpack-plugin
Расширение плагина, поэтому его нужно использовать вместе.
например конфигурацияpreload
:
plugins: [
new HtmlWebpackPlugin(),
new PreloadWebpackPlugin({
rel: 'preload',
as(entry) {
if (/\.css$/.test(entry)) return 'style';
if (/\.woff$/.test(entry)) return 'font';
if (/\.png$/.test(entry)) return 'image';
return 'script';
},
include: ['app']
})
]
Последняя инъекция в html:
<link rel="preload" as="script" href="app.31132ae6680e598f8879.js">
Настроить предварительную выборку в Webpack
prefetch
Совместимость с ВьюОтложенная загрузка маршрутаРазделение кода лучше
Поскольку маршрутизация не используется в инструменте визуализации этого проекта, конфигурация отсутствует.prefetch
.
оптимизировать пакет
В настоящее время в проекте обычно используются библиотеки классов инструментов: lodash, moment, element-ui.Для этих часто используемых библиотек классов вы можете использоватьDllpluginРазделите зависимости в статический репозиторий. Обычно эта версия пакета зависимостей не изменяется.
Однако, как и у lodash и moment, есть и другие способы уменьшить размер упаковки.
-
нагрузка по требованию
element-ui
, см. официальную документацию -
нагрузка по требованию
lodash
Как правило, когда мы используем lodash, мы не будем использовать все его функции. Можно использовать несколько.В настоящее время вы можете импортировать lodash по запросу, а не в полном объеме. Установив два плагина ниже:
npm i babel-plugin-lodash lodash-webpack-plugin -D
настроить.babelrc
документ
"plugins": [
"lodash"
]
- использовать
dayjs
заменятьmoment
, API в основном такой же, после использования вы обнаружите, что можно использовать большинство сценариев, а упаковка только7KB.
Обновите HTTP2
Компонентов в инструменте визуализации становится все больше и больше, и результирующий интерфейс данных запроса страницы постепенно увеличивается, а накладные расходы постепенно увеличиваются. Одностраничный запрос интерфейса данных варьируется от десятков до сотен.
Если вы продолжаете использовать HTTP1.x, все понимают ограничения протокола HTTP1.x.Большинство современных браузеров поддерживают максимальное количество 6 запросов от хоста одновременно, то есть если эти 6 интерфейсных запросов не возвращают результатов вpending
Если он находится в состоянии, страница не сможет постоянно обновлять данные, поэтому пользовательский опыт будет очень плохим. Мультиплексирование HTTP2 решает эту проблему, мы обновляем сервер доHTTP2
Увеличивает пропускную способность соединения запросов браузера и значительно повышает производительность приложений.
Введение в HTTP2
Http2.0 может сделать наши приложения быстрее, проще и крепче --- «Окончательное руководство по веб-характеристикам»
Целью HTTP 2.0 является сокращение задержки за счет поддержки мультиплексирования запросов и ответов, минимизация накладных расходов протокола за счет сжатия полей заголовков HTTP и добавление поддержки приоритезации запросов и принудительной отправки на стороне сервера.
Ядром улучшений производительности HTTP 2.0 является новый二进制分帧层
, который определяет, как HTTP-сообщения инкапсулируются и передаются между клиентом и сервером.
HTTP 2.0 сокращает базовую единицу связи по протоколу HTTP до кадров, которые соответствуют сообщениям в логических потоках. Соответственно, многие потоки могут параллельно обмениваться сообщениями по одному и тому же TCP-соединению.
HTTP 2.0二进制分帧
Этот механизм решает проблему блокировки очереди в HTTP 1.x, а также устраняет необходимость в нескольких соединениях для параллельной обработки и отправки запросов и ответов. Результатом являются более быстрые приложения, более простая разработка и более низкие затраты на развертывание.
Оптимизация HTTP2
-
域名分区
Антипаттерн в HTTP 2.0, поскольку множественные соединения сводят на нет эффективность сжатия заголовков и приоритизации запросов в новом протоколе. - Удалите ненужную упаковку ресурсов, такую как создание изображений спрайтов, поддержите HTTP 2.0, и многие небольшие ресурсы могут быть отправлены параллельно, что приведет к снижению эффективности ресурсов упаковки.
- Используйте кэширование на стороне клиента для ресурсов приложения
- Разверните HTTP 2.0 и разверните протокол TLS (безопасность транспортного уровня), который является HTTPS.
Использовать HTTP-кеш
Кэшируйте ресурсы приложения, чтобы избежать отправки одного и того же контента при каждом запросе. После того, как браузер загрузит статические ресурсы, он использует кеш для сохранения загруженных ресурсов, чтобы локальная копия напрямую использовалась при следующей загрузке веб-страницы. Запросы ресурсов и время ожидания сокращаются.
Cache-Control
Общие поля заголовка заголовка HTTP-запроса, просто укажите явное время кэширования. можно настроить вnginx
в файле конфигурации.
location ~ .*\.(js|css|ttf|svg|ico){
add_header Cache-Control max-age=86400;
}
Страница загружается в первый раз
загрузить снова
проверка кеша
Вы можете видеть, что после добавления кеша,Status Code
200 ОК (из кеша памяти), а время кеша:max-age=86400
Компоненты пакетного рендеринга Vue
В бизнес-сценариях, когда приложения становятся все более и более сложными, загрузка страницы может потребовать отрисовки слишком большого количества компонентов.Существует две стратегии для отрисовки нескольких компонентов:
- Обход всех компонентов и визуализация компонентов, когда каждый запрос интерфейса возвращает данные
- Запрашивать все интерфейсы и пакетно отображать компоненты, когда возвращаются все данные
Практикой установлено, что последний рендерится быстрее, а второй исключает время на рендеринг компонента после каждого запроса к интерфейсу, т.к. многократный рендеринг компонента будет приносить дополнительныеScripting
накладные расходы, как в Vuecomputed
илиwatch
; В то же время, в сочетании с мультиплексированием HTTP2, запросы для нескольких интерфейсов также будут отвечать быстро.
Образец кода:
// 批量更新组件方法
batchUpdateComponent({ dispatch }, promises) {
// 请求所有接口
return Promise.all(promises.map(p => p.catch(() => undefined)))
.catch(err => {
console.log(err)
})
.then(res => {
// 一次性渲染组件
res && dispatch('updateComponent', res)
})
}
💡 Если обратный вызов catch промиса возвращает неопределенное значение, то сбой промиса будет считаться успешным. использовать
ES2018
предложениеPromise.finally
Асинхронные компоненты Vue
Объем бизнес-кода приложения в проекте постоянно увеличивается, и написано много бизнес-компонентов, ведь в определенных сценариях не все компоненты нужно рендерить, например, визуализация имеет режим редактирования и режим предварительного просмотра. Необходимо использовать режим редактированияCode Mirror
написать немногоSQL
заявление, вам не нужно использовать его в режиме предварительного просмотра.
Компоненты импортируются нормально:
import CustomSql from '@/components/CustomSql'
export default {
components: {
CustomSql
}
}
Компоненты вводятся асинхронно:
// ES6 结合 Webpack
export default {
components: {
CustomSql: () => import('./CustomSql')
}
}
Маршрутизация ленивой загрузки в Vue заключается в использованииАсинхронные компонентыи
Webpack
изразделение кодаосуществленный.
SVG-оптимизация
По мере увеличения количества компонентов в проекте значки компонентов также становятся более многочисленными. Большинство иконок в формате svg, мы можем использоватьSVG Sprite
Управление технологиями SVG Icon.
Технология спрайтов SVG
так называемыйSVG Sprite
Аналогично в CSSSprite
Технологии. Объедините значки вместе, чтобы определенные значки отображались именно тогда, когда они фактически отображаются.
SVG Sprite
Технические передовые практики:
- использовать
symbol
Значки интеграции элементов - использовать
use
элементы для использования значков
Пример использования:
<svg>
<!-- symbol definition NEVER draw -->
<symbol id="sym01" viewBox="0 0 150 110">
<circle cx="50" cy="50" r="40" stroke-width="8" stroke="red" fill="red"/>
<circle cx="90" cy="60" r="40" stroke-width="8" stroke="green" fill="white"/>
</symbol>
<!-- actual drawing by "use" element -->
<use xlink:href="#sym01"
x="0" y="0" width="100" height="50"/>
<use xlink:href="#sym01"
x="0" y="50" width="75" height="38"/>
<use xlink:href="#sym01"
x="0" y="100" width="50" height="25"/>
</svg>
Компонентный SvgIcon
на основеVue
Инкапсулированные компоненты SVG ICON
// @/components/SvgIcon.vue
<template>
<svg :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
return 'svg-icon ' + this.className
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
Автоматическое введение SVG
Динамически импортировать все значки в src/assets/icons
// @/plugins/svgicon.js
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'
Vue.component('svg-icon', SvgIcon)
const requireAll = requireContext => requireContext.keys().map(requireContext)
const svgIcons = require.context('./components', false, /\.svg$/)
requireAll(svgIcons)
Упаковка спрайтов SVG
мы можем использоватьsvg-sprite-loader
этот плагин для созданияSVG Sprite
, введите значок svg с помощью компонентов.
на основеWebpack 3.x
Метод настройки следующий:
// 通过 exclude/include 来区分哪些属于svg icon,哪些属于image
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
exclude: [resolve('src/assets/icons')],
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include: [resolve('src/assets/icons')],
options: {
symbolId: 'icon-[name]'
}
}
Суммировать
Ключевые моменты этой оптимизации производительности:
Сторона веб-пакета:
- Включите Gzip, прямая выгода относительно велика
- Используйте плагин предварительной загрузки, чтобы предварительно объявить ресурсы, которые будут использоваться.
- Максимально оптимизируйте пакет, загружайте его по требованию и уменьшайте размер пакета.
Сеть:
- Лучше всего обновить сервер до HTTP2 в сочетании с HTTPS.
- При использовании стратегии кэширования HTTP наилучшая производительностьне спрашивай
Vue практические аспекты:
- Время рендеринга компонентов, рекомендуется пакетный рендеринг после того, как будут возвращены все запросы интерфейса
- Напишите компоненты, которые обычно не используются в определенных сценариях, как асинхронные компоненты.
С точки зрения ресурсов:
- Когда в проекте используется больше SVG, вы можете использовать технологию «SVG Sprite» для управления
Наконец
В начале проекта, из-за плотного графика, мы спешили перебирать функции, цель была доставить полностью функциональное приложение, когда количество пользователей увеличилось, мы должны остановиться и подумать, как улучшить производительность. приложения. Даже если функции приложения завершены, а взаимодействие с пользователем очень плохое, стоит ли об этом задумываться Оптимизация производительности — это то, что нужно делать постоянно.
Я хотел бы позаимствовать из The Definitive Guide to Web Performance,Ilya GrigorikУпоминается: «💡Мы заботимся не только о предоставлении полезных приложений, наша цель — обеспечить наилучшую производительность!», чтобы обобщить практику оптимизации производительности и напомнить себе, что при работе над точка проекта.
Ссылаться на
Полное руководство по веб-производительности
- Resource Hints
- W3C Resource Hints
- Preload: What Is It Good For?
- Getting Ready For HTTP2
- Алгоритм сжатия HTTP 2.0
- Promise.all for Rejections and Resolves
- Введение в технологию SVG Sprite
оригинальный🚀 Помните об оптимизации производительности интерфейса