みなさん、こんにちは。毎週GetMoreを使用すると、さらに強くなります。
最近、他の人が残したプロジェクトコードを整理しているのですが、まとまりがなく、最適化が必要なところがたくさんあります。この機会に、参考のために独自の最適化エクスペリエンスを整理してください。インターネット上にはパッケージング性能の最適化に関する記事もたくさんありますが、プロジェクトごとに実際の状況は異なり、直接移動して使用するほど簡単ではありません。始めましょう。
プロジェクトの環境を紹介します。
- @2.6.11を表示
- view / cli @ 5.0.4
- webpack @ 4.46.0
プロジェクトのランニングスコア
最適化されていない灯台パネル
最適化されていないwebpack-bundle-analyzerパネル
1開発中のパッケージング速度の最適化
より良い開発を可能にするために、hard-source-webpack-plugin
このプラグインが追加されました。これhard-source-webpack-plugin
は、モジュールの中間キャッシュステップを提供するwebpackのプラグインです。結果を確認するには、このプラグインを使用してwebpackを2回実行する必要があります。最初のビルドには通常の時間がかかります。2番目のビルドは大幅に高速になります(約90%高速なビルド)。
2コード圧縮を有効にする
terser-webpack-plugin
プラグインを使用する
config.plugins.push(
new TerserPlugin({
cache: true,
parallel: true,
sourceMap: true,
terserOptions: {
compress: {
warnings: false,
drop_console: true,
drop_debugger: true,
pure_funcs: ['console.log']
}
}
})
)
3パケット分析ツール
プラグインを使用して、webpack-bundle-analyzer
vue.config.jsの下configureWebpack
の構成アイテムに次のコードを追加します
// 增加包分析工具, 运行analyz命令
if (process.env.npm_config_report) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
config.plugins.push(new BundleAnalyzerPlugin())
}
package.jsonに追加します
"scripts": {
...
"analyz": "NODE_ENV=production npm_config_report=true npm run build"
}
3.1モーメント言語パッケージを最適化し、configureWebpack
それに次の構成を追加します
config.plugins.push(new webpack.IgnorePlugin(/^./locale$/, /moment$/))
3.2 echartsのworld.jsonデータパッケージを削除し、china.jsonのみを導入します
3.3分析Webページの一部のパッケージが非常に大きく見える場合、または一部の未使用のリソースも出力にパッケージ化されている場合は、対象を絞った最適化が必要です
4ツリーシャーキングの最適化
// vue.config.js 下的 configureWebpack
config.optimization = {
usedExports: true,
}
package.jsonに追加します
"sideEffects": [
"*.css",
"*.vue"
]
注:これら2つの構成svg-sprite-loader
は競合し、svg-iconが失われる原因になります
5 depcheckは、未使用のnpmパッケージを削除します
5.1depcheckをインストールする
npm install -g depcheck
5.2現在のプロジェクトのルートディレクトリに移動し、depcheck
コマンドを実行します
Unused dependencies
* node-sass
...
Unused devDependencies
...
Missing dependencies
...
Unused dependencies
プロジェクト内のパッケージの依存関係に従って、処理中のパッケージに焦点を当てます
6vue-cliプロジェクトのElementUIスタイルが失われました
css: {
// 是否使用css分离插件 ExtractTextPlugin
extract: true,
// 开启 CSS source maps?
sourceMap: false,
// css预设器配置项
loaderOptions: {},
// 启用 CSS modules for all css
requireModuleExtension: true
},
7svg-sprite-loadersvgスプライトイメージ
chainWebpack
次の構成をvue.config.jsに追加し、vue-cliプロジェクトでsvg-iconを使用します
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/assets/icons'))
.end()
config.module
.rule('icons')
.test(/.svg$/)
.include.add(resolve('src/assets/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
8最初の画面では使用できないindex.htmlで導入された静的スクリプトリソースを動的ロードに変更し、非同期ローダーを自分で作成します
sessionStorage.setItem('AsyncLoadScriptMap', '[]')
// 异步加载js文件的集合
const AsyncLoadJS = {
getMap: function() {
const map = sessionStorage.getItem('AsyncLoadJSMap');
if(!map) return []
return JSON.parse(map)
},
setItem: function(key) {
let map = sessionStorage.getItem('AsyncLoadJSMap') || '[]';
map = JSON.parse(map);
if(map.includes(key)) return;
map.push(key);
sessionStorage.setItem('AsyncLoadJSMap', JSON.stringify(map))
}
}
// 异步加载js文件
export function loadScript(url) {
return new Promise((resolve, reject) => {
if (AsyncLoadJS.getMap().includes(url)) {
resolve();
return true;
}
let script = document.createElement('script');
script.type = 'text/javascript';
script.charset = 'utf-8';
script.async = true;
script.src = url;
script.onerror = reject;
script.onload = function () {
AsyncLoadJS.setItem(url)
resolve();
}
document.head.appendChild(script);
})
}
9ホームページで使用されていない依存関係は、main.jsの対応するモジュールに削除され、app.jsのメインモジュールのファイルサイズが縮小されます。
10 gzipをオンにして、compression-webpack-plugin
プラグインを使用します
new CompressionWebpackPlugin({
algorithm: 'gzip',
test: /.(js|css)$/,
filename: '[path].gz[query]', // asset -> filename
threshold: 1024 * 10, // 达到10kb的静态文件进行压缩 按字节计算
minRatio: 0.8, // 只有压缩率比这个值小的资源才会被处理
deleteOriginalAssets: false // 是否删除压缩的源文件
})
サーバーは応答を構成する必要があり、サーバーの下に次の構成を配置し、nginx
サービスを再起動することを忘れないでください。応答ヘッダーが表示さContent-Encoding: gzip
れ、構成は成功します。
#是否启动gzip压缩,on代表启动,off代表开启
gzip on;
#需要压缩的常见静态资源
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
#由于nginx的压缩发生在浏览器端而微软的ie6很坑爹,会导致压缩后图片看不见所以该选项是禁止ie6发生压缩
gzip_disable "MSIE [1-6].";
#如果文件大于1k就启动压缩
gzip_min_length 1k;
#以16k为单位,按照原始数据的大小以4倍的方式申请内存空间,一般此项不要修改
gzip_buffers 4 16k;
#压缩的等级,数字选择范围是1-9,数字越小压缩的速度越快,消耗cpu就越大
gzip_comp_level 2;
#如果有已经压缩的(.gz)或者提供静态文件服务,可以设置为on。如果不是这样,最好设置为off,因为这会造成额外的i/o开销。
gzip_static on;
11 LightHouseパネルのパフォーマンス最適化のヒントに従って、対応するリソースを最適化します
- 比較的大きな画像はwebpを使用します
- 画像要素には明示的な幅と高さはありません
- 静的リソースキャッシュを有効にする
- ..。
この程度の最適化が達成された後、大部分が改善されました。現在のLighthouse
実行ポイントは次のとおりです。
すべての静的リソースのキャッシュを有効にしなかったため、実行スコアが十分に高くありません。キャッシュを有効にすると、実行スコアは約90になると思います。最適化されたwebpack-bundle-analyzerパネルを見てみましょう。
さて、とりあえずこのレベルに最適化しましょう。最適化できる点はまだいくつかありますが、今はそれほど大きな影響はありません。大きな問題は解決されています。お役に立てば幸いです。次号でお会いしましょう!