Начинать
В этой главе рассказывается об оптимизации объема упаковки. Это также самая важная глава. Я потратил много времени на поиск информации о том, как оптимизировать объем упаковки. Существуют некоторые различия между различными версиями веб-пакета, поэтому это считается шагом. много ям, поэтому эта глава будет длиннее.
Здесь я примерно написал конкретный макет страницы, который выглядит следующим образом:
Давайте еще раз взглянем на размер упаковки, там 2,75М, что уже очень много:Мы используем плагин визуализации пакетов, чтобы увидеть, что упаковано, мы выполняем:yarn add webpack-bundle-analyzer -D
Добавьте строку в плагины webpack.config.prod.js, обратите внимание, что порт можно изменить, не конфликтуйте:
new BundleAnalyzerPlugin({ analyzerPort: 8081 })
После того, как модификация будет завершена, выполните команду yarn run build, и во всплывающем окне браузера у меня будет вот так:
Хорошо видно, что на antd и react-dom приходится больше половины из них, давайте их оптимизируем ниже.1. Изменить режим
Перейдем к webpack.config.prod.js:
//mode:'development'
mode:'production' //修改成生产环境
Затем проверьте размер пакета, который мгновенно уменьшается более чем вдвое.Если он будет изменен в среде разработки, webpack автоматически оптимизирует размер пакета, например, сжатие кода и тому подобное:
2. antd загружается по требованию
Выполнить на консоли:
yarn add babel-plugin-import -D
Затем перейдите в webpack.config.common.js для настройки:
plugins:[
"@babel/plugin-transform-runtime",
['import',{
libraryName:'antd',
libraryDirectory: 'es',
style:true
}]
]
Изменить в конфигурации меньше:
{
loader:'less-loader',
options:{
javascriptEnabled: true
}
}
Затем переходим к месту, где используется компонент antd, и модифицируем его для импорта в следующем виде:
// import Col from 'antd/lib/col';
// import Row from 'antd/lib/row';
// import "antd/dist/antd.css"; //css也去掉
import {Col,Row} from 'antd'
Затем выполните команду упаковки, чтобы стать 601 КБ:
3. mini-css-extract-plugin извлекает css
Мы используем плагин mini-css-extract-plugin для отделения css от js. Выполнить на консоли:
yarn add mini-css-extract-plugin -D
Настройте в webpack.config.prod.js:
//在顶部引入
const MiniCssExtractPlugin=require('mini-css-extract-plugin');
//在plugins里添加
new MiniCssExtractPlugin({//提取css
filename:'css/main.css'
}),
Таким образом, мы можем отдельно разделить css на папку css. Затем снова упакуйте:
Мы обнаружили, что пакет js стал меньше, а css был разделен, но на самом деле css имел 223 КБ.Когда мы открыли файл css, мы обнаружили, что css не был сжат.Мы запускаем его в консоли. Первый сжимает css, а второй сжимает js. Первоначально js будет сжат в производственной среде, но использование optimise-css-assets-webpack-plugin приведет к тому, что сжатый js станет недействительным. Итак, мы нужно ввести дополнительный плагин для сжатия js:
yarn add optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin -D
Настраиваем в webpack.config.common.js:
//这个配置和module,plugins是同级的
optimization:{
minimizer:[
new UglifyJsPlugin({//压缩js
cache:true,
parallel:true,
sourceMap:true
}),
new OptimizeCSSAssetsPlugin()//压缩css
]
},
Потом идем в package, обнаруживаем, что css стал меньше:
4. DllPlugin и DllReferencePlugin
На предыдущей диаграмме упаковки мы видим, что большую часть объема пакета занимают ведро семейства React и Babel, теперь мы выносим их и помещаем в js-файл отдельно, потому что мы не будем менять эти вещи.
Создаем новый ==webpack.config.dll.js== в корневом каталоге, а затем настраиваем его внутри, т.к. DllPLugin находится под вебпаком, поэтому скачивать не нужно:
const path=require('path')
const webpack =require('webpack')
const CleanWebpackPlugin = require('clean-webpack-plugin');
//只需要使用yarn run dll一次就行
module.exports={
mode:'production',
entry:{
//这里把react方面的东西和babel放到这里
vendor:['react','react-dom','react-router-dom']
},
output:{
filename:'dll/_dll_[name].js',
path:path.resolve(__dirname,'dist'),
library:'_dll_[name]'
},
plugins:[
new webpack.DllPlugin({
name:'_dll_[name]',
path:path.resolve(__dirname,'dist/dll','mainfist.json')
}),
new CleanWebpackPlugin(['./dist/dll']),//删除dll目录下的文件
]
}
Затем перейдите к ==webpack.config.common.js== для настройки:
//在plugins下新增
new webpack.DllReferencePlugin({
manifest: path.resolve(__dirname, 'dist/dll', 'mainfist.json')
}),
Затем перейдите в package.json для настройки:
//在scripts下面新增一条这个
"dll": "webpack --config webpack.config.dll.js"
Выполнить на консоли:
yarn run dll
Мы обнаружили, что он был упакован, и нам все еще нужно перейти в public/index.html для импорта:
//在body最后新增
<script src="dll/_dll_vendor.js"></script>
Затем перейдите к выполнению сборки запуска пряжи:
Размер файла снова стал меньше.5. @babel/polyfill
Как мы видим на предыдущем рисунке, core-js занимает большую часть тома, который представляет собой библиотеку, используемую babel/polyfill. Здесь я предлагаю два метода.
1. @baebl/polyfill загружается по запросу
Мы можем использовать свойство useBuiltIns, новое в babel 7. Нам нужно настроить его следующим образом:
presets:[
[
'@babel/preset-env',
{
"targets": {
"browsers": [
"ie >=9",
"last 2 version",
"> 5%",
"not dead"
]
},
"useBuiltIns":"usage"
}
],
'@babel/preset-react'
],
Когда мы настроим это так, мы можем поставить вершину index.js
//import '@babel/polyfill' //可以去掉这一行了
Затем мы снова упаковываем и выполняем сборку запуска пряжи:
В это время размер пакета стал 132kb, но когда я использую этот метод, он может нормально отображаться под ie11, а в ie10 и ниже возникает следующая ошибка:Я еще не нашел решение, пожалуйста, дайте мне знать, если у вас есть решение, спасибо. Вы можете использовать этот метод, если вам не нужна совместимость с ie10 или ниже.2. Извлеките @baebl/polyfill
Второй метод, мы можем напрямую извлечь @babel/polyfill, как ведро семейства React. Заходим в ==webpack.config.dll.js== для настройки:
//添加@babel/polyfill
vendor:['react','react-dom','react-router-dom','@babel/polyfill']
Затем перейдите в начало index.js и добавьте:
import '@babel/polyfill'
Затем переходим к выполнению yarn run dll, и видим, что пакет вендора стал больше:
Затем мы выполняем сборку запуска пряжи: Мы обнаружили, что размер пакета аналогичен предыдущему способу, и затем мы идем в ie, чтобы увидеть:Эта ошибка возникает только при ==ie8==, ie9 и выше отображаются нормально, и совместимость очень хорошая, поэтому выбор между этими двумя методами зависит от того, должна ли ваш проект быть совместим с ie.6. динамическая загрузка реактивного маршрутизатора (ленивая загрузка реактивных компонентов)
Раньше мы загружали все компоненты на странице, поэтому компоненты, которые мы не нажали, также будут загружены, что приводит к потерям. Гораздо лучше, если мы используем динамическую загрузку, чтобы компонент, по которому щелкнули, загружался.
Выполняем в консоли:
yarn add react-loadable babel-plugin-syntax-dynamic-import -D
Как настроить в ==webpack.config.common.js==:
plugins:[
"@babel/plugin-transform-runtime",
'babel-plugin-syntax-dynamic-import',//增加这一行
['import',{
libraryName:'antd',
libraryDirectory: 'es',
style:true
}]
]
Затем переходим к месту использования маршрута и модифицируем:
import Loadable from 'react-loadable';//注意要加上这一行
// import A from '../pages/A/A'
// import B from '../pages/B/B'
//修改成这样子的写法
const A = Loadable({
loader: () => import('../pages/A/A'),
loading:()=> {
return <div>Loading...</div>
}
});
const B = Loadable({
loader: () => import('../pages/B/B'),
loading:()=> {
return <div>Loading...</div>
}
});
Затем перейдите к выполнению команды пакета, а затем проверьте:
Мы обнаружили, что размер пакета стал больше. Это потому, что я ничего не писал в проекте сейчас, поэтому после введения плагина пакет станет больше. После написания большего количества компонентов эта динамическая загрузка может уменьшить много объема.Мы можем посмотреть на эффект:
Вот что происходит при загрузке страницы
После нажатия на маршрут он становится таким:Вы можете видеть, что файл js загружается динамически.Объяснение объема index.js
Давайте поговорим об упакованной карте здесь. На самом деле, я написал очень мало кода под src, но в упакованной карте есть файл index.js размером почти 90 КБ. Почему это так? На самом деле это компонент, который antd загружает и упаковывает по требованию. Мы можем попробовать его. Это код компонента antd, который я сейчас использую на большей части домашней страницы:
<div>
<Header/>
<Row>
<Col xs={24} sm={24} md={6} lg={4} xl={4} xxl={4}>
<Aside/>
</Col>
<Col xs={24} sm={24} md={18} lg={20} xl={20} xxl={20}>
<div className="content">
{this.props.children}
</div>
</Col>
</Row>
</div>
Мы закомментируем все используемые нами компоненты antd, оставив только заголовок:
//import {Col,Row} from 'antd'
<div>
<Header/>
{/*<Row>*/}
{/*<Col xs={24} sm={24} md={6} lg={4} xl={4} xxl={4}>*/}
{/*<Aside/>*/}
{/*</Col>*/}
{/*<Col xs={24} sm={24} md={18} lg={20} xl={20} xxl={20}>*/}
{/*<div className="content">*/}
{/*{this.props.children}*/}
{/*</div>*/}
{/*</Col>*/}
{/*</Row>*/}
</div>
Затем переходим к упаковке:
Теперь пакет под src стал очень маленьким.7. splitChunks
Затем мы отделяем сторонние библиотеки, такие как antd, от основного пакета.
Мы настраиваем его в оптимизации в ==webpack.config.common.js==, на том же уровне, что и ==minimizer==, где мы писали js и css сжатие раньше:
splitChunks:{
cacheGroups:{
vendors:{//node_modules里的代码
test:/[\\/]node_modules[\\/]/,
chunks: "initial",
name:'vendors', //chunks name
priority:10, //优先级
enforce:true
}
}
}
Затем перейдите к выполнению команды упаковки:
Мы можем обнаружить, что js и css из antd были извлечены, имена чанков — это поставщики, а основной — это код, который мы написали сами, и на самом деле мы написали очень мало.Хотя компоненты antd относительно велики, они будут упакованы только один раз, и когда сервер настроен с помощью gzip, объем может быть уменьшен более чем на треть, что все еще приемлемо.
конец
Наконец, мы оптимизировали размер основного пакета с 2,75 МБ до примерно 5 КБ, но на самом деле мы разделили большой пакет на несколько маленьких пакетов и извлекли общий код.
На самом деле есть еще один метод оптимизации с использованием внешних ресурсов, а затем с использованием CDN для импорта, но я уже использовал здесь DllPlugin, поэтому я не буду использовать этот метод, оба метода можно использовать разумно.
В этой главе написано слишком много всего, и это немного сложно, но это должно быть достаточно подробно, но я думаю, что оптимизация объема упаковки веб-пакета - это нечто большее.Если у вас есть другие методы, которые можно оптимизировать, также сообщите мне сейчас, спасибо.
адрес гитхаба:GitHub.com/hope-Zhou/Web…
(ps: если в статье есть ошибки, укажите на них в комментариях, спасибо)