Heim >Web-Frontend >js-Tutorial >Detaillierte Erläuterung der Beispiele für die Konstruktion und Verpackungsoptimierung von React und Webpack

Detaillierte Erläuterung der Beispiele für die Konstruktion und Verpackungsoptimierung von React und Webpack

小云云
小云云Original
2018-01-24 09:57:191802Durchsuche

Dieser Artikel führt hauptsächlich eine kurze Diskussion über die Konstruktion und Verpackungsoptimierung von React + Webpack ein. Der Herausgeber findet ihn recht gut, daher werde ich ihn jetzt mit Ihnen teilen und als Referenz verwenden. Folgen wir dem Herausgeber und schauen wir uns das an. Ich hoffe, es kann allen helfen.

Verwenden Sie babel-react-optimize, um den React-Code zu optimieren

Überprüfen Sie nicht verwendete Bibliotheken und entfernen Sie Importverweise

Verpacken Sie die verwendeten Klassen nach Bedarf. Bibliotheken, z B. Lodash, Echart usw.

Lodash kann mit babel-plugin-lodash optimiert werden.

Es ist zu beachten, dass

das Plugin babel-plugin-transform-react-remove-prop-types in babel-react-optimize verwendet. Normalerweise ist es völlig in Ordnung, wenn Sie in Ihrem Code nicht auf die PropTypes der Komponente verweisen. Die Verwendung dieses Plugins kann zu Problemen führen, wenn Ihre Komponente es verwendet.

Einzelheiten finden Sie unter:

https://github.com/oliviertassinari/babel-plugin-transform-react-remove-prop-types#is-it-safe

Webpack-Build und Paketoptimierung

Die Probleme beim Webpack-Build und -Paket konzentrieren sich hauptsächlich auf die folgenden zwei Aspekte:

  1. Die Webpack-Build-Geschwindigkeit ist langsam

  2. Die Dateigröße nach der Webpack-Verpackung ist zu groß

Die Webpack-Erstellungsgeschwindigkeit ist langsam

Sie können Webpack.DDLPlugin und HappyPack verwenden, um die Build-Geschwindigkeit zu verbessern. Einzelheiten finden Sie in der Dokumentation von Xiaoming zum DMP DDLPlugin. Der Originaltext lautet wie folgt:

Webpack.DLLPlugin

Beim Hinzufügen einer webpack.dll.config.js
wird hauptsächlich ein DllPlugin-Plug-in verwendet, um einige Ressourcen von Drittanbietern unabhängig zu verpacken Fügen Sie sie in eine manifest.json-Konfigurationsdatei ein,

, damit diese Ressourcen von Drittanbietern nach der Aktualisierung in der Komponente nicht neu erstellt werden,

  1. und konfigurieren Sie die DLL /vendors unabhängig gleichzeitig .js-Datei, bereitgestellt für webpack.dll.config.js

  2. Paket.json ändern

Hinzufügen: „dll“ in Skripten: „webpack --config webpack.dll.config.js --progress --colors“, .

Nach dem Ausführen von npm run dll werden zwei Dateien Vendor-manifest.json und Vendor.dll.js im DLL-Verzeichnis erstellt.

Konfigurieren Sie die Datei webpack.dev.config.js Fügen Sie ein DllReferencePlugin-Plug-in hinzu und geben Sie die Datei „vendor-manifest.json“ an


new webpack.DllReferencePlugin({
 context: join(__dirname, 'src'),
 manifest: require('./dll/vendor-manifest.json')
})

html ändern


<% if(htmlWebpackPlugin.options.NODE_ENV ===&#39;development&#39;){ %>
 <script src="dll/vendor.dll.js"></script>
<% } %>

Beachten Sie, dass der Parameter NODE_ENV im htmlWebpackPlugin-Plugin konfiguriert werden muss

Happypack

Verbessern Sie die Wiederherstellungseffizienz durch Multithreading. Caching usw. https://github.com/amireh/happypack

Erstellen Sie mehrere HappyPacks für verschiedene Ressourcen in webpack.dev.config.js, z. B. 1 js, 1 weniger, und legen Sie die ID fest


new HappyPack({
 id: &#39;js&#39;,
 threadPool: happyThreadPool,
 cache: true,
 verbose: true,
 loaders: [&#39;babel-loader?babelrc&cacheDirectory=true&#39;],
}),
new HappyPack({
 id: &#39;less&#39;,
 threadPool: happyThreadPool,
 cache: true,
 verbose: true,
 loaders: [&#39;css-loader&#39;, &#39;less-loader&#39;],
})

Verwendung in module.rules für Happypack/Loader konfigurieren, ID festlegen


{
 test: /\.js$/,
 use: [
 &#39;happypack/loader?id=js&#39;
 ],
 exclude: /node_modules/
}, {
 test: /\.less$/,
 loader: extractLess.extract({
 use: [&#39;happypack/loader?id=less&#39;],
 fallback: &#39;style-loader&#39;
 })
}

Reduzieren Sie die Dateigröße nach der Webpack-Verpackung

Zuerst müssen wir unser gesamtes Paket analysieren, woraus es besteht und wie groß jede Komponente ist.

Webpack-bundle-analyzer wird hier empfohlen. Nach der Installation fügen Sie einfach das Plug-in in webpack.dev.config.js hinzu. Die Analyseergebnisse werden nach jedem Start automatisch auf der Website geöffnet, wie unten gezeigt


plugins.push( new BundleAnalyzerPlugin());

Darüber hinaus können Sie den Verpackungsprozess auch in eine JSON-Datei ausgeben


webpack --profile --json -> stats.json

Gehen Sie dann wie folgt vor zwei Websites zur Analyse

  1. Webpack/Analyse

  2. Webpack-Diagramm

Sie können es deutlich sehen Durch die obige Diagrammanalyse werden die Komponenten des gesamten bundle.js und ihre entsprechenden Größen ermittelt.

Die Lösung für das Problem der übermäßigen Größe von bundle.js lautet wie folgt:

  1. Aktivieren Sie die Komprimierung und andere Plug-Ins in der Produktionsumgebung und entfernen Sie unnötige Plug-Ins. ins

  2. Geschäftscode und Bibliotheken und öffentliche Module von Drittanbietern aufteilen

  3. Webpack aktiviert die GZIP-Komprimierung

  4. Bei Bedarf laden

Komprimierung und andere Plug-Ins in der Produktionsumgebung aktivieren und unnötige Plug-Ins entfernen

Stellen Sie sicher, dass Sie webpack starten.DefinePlugin und Webpack .optimize.UglifyJsPlugin in der Produktionsumgebung.


const plugins = [
 new webpack.DefinePlugin({
  &#39;process.env.NODE_ENV&#39;: JSON.stringify(process.env.NODE_ENV || &#39;production&#39;)
 }),
  new webpack.optimize.UglifyJsPlugin({
  compress: {
   warnings: false,
   drop_console: false //eslint-disable-line
  }
  })   
]

Teilen Sie den Geschäftscode mit Bibliotheken und öffentlichen Modulen von Drittanbietern auf

Aufgrund der hohen Häufigkeit von Geschäftscode Änderungen im Projekt, während Codeänderungen von Drittanbieterbibliotheken relativ selten sind. Wenn der Geschäftscode und die dritte Bibliothek bei jedem Build in denselben Block gepackt werden, ändert sich der Hash des gesamten Blocks, auch wenn der Geschäftscode nur eine Zeile ändert, selbst wenn sich der Code der Bibliothek eines Drittanbieters nicht ändert anders sein als beim letzten Mal. Das ist nicht das Ergebnis, das wir wollen. Was wir wollen, ist, dass wir, wenn sich der Code der Bibliothek eines Drittanbieters nicht ändert, sicherstellen müssen, dass sich der entsprechende Hash beim Erstellen nicht ändert, damit wir den Browser-Cache verwenden können, um die Seitenladeleistung besser zu verbessern und das Laden der Seite zu verkürzen Zeit.

因此可以将第三库的代码单独拆分成 vendor chunk,与业务代码分离。这样就算业务代码再怎么发生变化,只要第三方库代码没有发生变化,对应的 hash 就不变。

首先 entry 配置两个 app 和 vendor 两个chunk


entry: {
 vendor: [path.join(__dirname, &#39;dll&#39;, &#39;vendors.js&#39;)],
 app: [path.join(__dirname, &#39;src/index&#39;)]
},
output: {
 path: path.resolve(__dirname, &#39;build&#39;),
 filename: &#39;[name].[chunkhash:8].js&#39;
},

其中 vendros.js 是自己定义的哪些第三方库需要纳入 vendor 中,如下:


require(&#39;babel-polyfill&#39;);
require(&#39;classnames&#39;);
require(&#39;intl&#39;);
require(&#39;isomorphic-fetch&#39;);
require(&#39;react&#39;);
require(&#39;react-dom&#39;);
require(&#39;immutable&#39;);
require(&#39;redux&#39;);

然后通过 CommonsChunkPlugin 拆分第三库


plugins.push(
 // 拆分第三方库
 new webpack.optimize.CommonsChunkPlugin({ name: &#39;vendor&#39; }),
 // 拆分 webpack 自身代码
 new webpack.optimize.CommonsChunkPlugin({
  name: &#39;runtime&#39;,
  minChunks: Infinity
 })
);

上面的配置有两个细节需要注意

  1. 使用 chunkhash 而不用 hash

  2. 单独拆分 webpack 自身代码

使用 chunkhash 而不用 hash

先来看看这二者有何区别:

  1. hash 是 build-specific ,任何一个文件的改动都会导致编译的结果不同,适用于开发阶段

  2. chunkhash 是 chunk-specific ,是根据每个 chunk 的内容计算出的 hash,适用于生产

因此为了保证第三方库不变的情况下,对应的 vendor.js 的 hash 也要保持不变,我们再 output.filename 中采用了 chunkhash

单独拆分 webpack 自身代码

Webpack 有个已知问题:

webpack 自身的 boilerplate 和 manifest 代码可能在每次编译时都会变化。

这导致我们只是在 入口文件 改了一行代码,但编译出的 vendor 和 entry chunk 都变了,因为它们自身都包含这部分代码。

这是不合理的,因为实际上我们的第三方库的代码没变,vendor 不应该在我们业务代码变化时发生变化。

因此我们需要将 webpack 这部分代码分离抽离


new webpack.optimize.CommonsChunkPlugin({
   name: "runtime",
   minChunks: Infinity
}),

其中的 name 只要不在 entry 即可,通常使用 "runtime" 或 "manifest" 。

另外一个参数 minChunks 表示:在传入公共chunk(commons chunk) 之前所需要包含的最少数量的 chunks。数量必须大于等于2,或者少于等于 chunks的数量,传入 Infinity 会马上生成 公共chunk,但里面没有模块。

拆分公共资源

同 上面的拆分第三方库一样,拆分公共资源可以将公用的模块单独打出一个 chunk,你可以设置 minChunk 来选择是共用多少次模块才将它们抽离。配置如下:


new webpack.optimize.CommonsChunkPlugin({
 name: &#39;common&#39;,
 minChunks: 2,
}),

是否需要进行这一步优化可以自行根据项目的业务复用度来判断。

开启 gzip

使用 CompressionPlugin 插件开启 gzip 即可:


// 添加 gzip
new CompressionPlugin({
 asset: &#39;[path].gz[query]&#39;,
 algorithm: &#39;gzip&#39;,
 test: /\.(js|html)$/,
 threshold: 10240,
 minRatio: 0.8
})

大家学会了吗?赶紧动手尝试一下吧。

相关推荐:

parcel.js打包出错到选择nvm的全部过程解析

Parcel打包示例详解

webpack多入口文件页面打包详解


Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Beispiele für die Konstruktion und Verpackungsoptimierung von React und Webpack. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn