ホームページ >ウェブフロントエンド >jsチュートリアル >Webpack 学習チュートリアルのフロントエンド パフォーマンス最適化の概要

Webpack 学習チュートリアルのフロントエンド パフォーマンス最適化の概要

小云云
小云云オリジナル
2017-12-06 11:32:202255ブラウズ

Webpack は最近最も人気のあるモジュールローダーおよびパッケージ化ツールで、JS (JSX を含む)、Coffee、スタイル (less/sass を含む)、画像などのさまざまなリソースをモジュールとして使用および処理できます。この記事は主に、Webpack 学習チュートリアルのフロントエンド パフォーマンスの最適化に関する関連情報を要約して紹介します。

上図のようにJSリソースを導入しましたが、今ではあまり見られなくなったと思います。近年、Web フロントエンド開発の分野は標準化された開発に向けて進化しています。これは次の 2 つの点に反映されています:

1. MVC R&D アーキテクチャ。多くの利点 (明確なロジック、プログラムはデータとパフォーマンスの分離、強力な可読性を重視しており、問題の回避とトラブルシューティングに役立ちます...)

2. 無限の構築ツールがあります。多くの利点 (チームのコラボレーションとエンジニアリングの運用と保守の改善、些細で反復的な作業の手動処理の回避)

  • モジュラー開発

  • フロントエンドのパフォーマンス最適化理論の実装、コード圧縮、マージ、キャッシュ制御、パブリックコードの抽出待ってください

  • その他には、たとえば、ES 6 または CoffeeScript を使用してソース コードを記述し、ブラウザでサポートされる ES5 をビルドすることもできます

まだプロジェクトがあれば、フロントエンドはとても楽しいですフロントエンドとバックエンドを分離しないと、本当に保守的すぎます。

主流のビルド ツール

市場には、Grunt、Gulp、browserify などを含む多くのビルド ツールがあります。これらと WebPack はすべてパッケージ化ツールです。ただし、WebPack には次のような特徴もあります:

Grunt と比較して、WebPack には豊富なプラグイン セットがあるだけでなく、読み込み (ローダー) システムも備えています。 ES6、CommonJS、AMD など、Grunt や Gulp にはない複数の標準化された読み込み方法をサポートしています。

コード難読化の観点から見ると、WebPack はさらに極端です

コードは (ファイルではなく) 処理単位に断片化され、ファイルの断片化がより柔軟になります。

追記:これは単純な比較であり、どちらが良いか悪いかは関係ありません。実際、ツールはニーズを満たすことができます。ツールの使用方法の背後にあるのは、フロントエンドのパフォーマンスの最適化を理解することです。

はじめに

最近、いくつかのプラグインを使用した後、最初の画面の読み込みパフォーマンスを最適化するために、オンラインになる前と後の速度が2倍になったことをここで簡単に共有します。最適化前後の最初の画面のレンダリング比較画像。

合計ダウンロード時間が 3800 ミリ秒から 1600 ミリ秒に短縮されていることがわかります。

webpack を使用するときは、通常、独自のソース コードをサードパーティのライブラリ コードから分離するために複数のエントリ ファイルを選択します。これは以前のコードです、


entry: {
 entry: './src/main.js',
 vendor: ['vue', 'vue-router', 'vuex', 'element-ui','echarts']
},
output: {
 path: config.build.assetsRoot,
 filename: utils.assetsPath('js/[name].[chunkhash].js'),
 chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
}


echartsは非常に大きいので、パッケージ化されたvendor.jsは約1.2MB(gzip圧縮後)、echartsはホームページでは使用されないので、後で外部を使用しますCDN 経由でサードパーティ ライブラリを導入します。 以下は最適化されたコードです

​​



これは最適化前後の比較です。

次に、HTML に移動して、スクリプト タグの形式で外部で cdn を引用する必要があります。その後、対応するファイルにインポートできます。その利点は、多くの vue ファイルで何度参照しても、すべてのトランクにパッケージ化されないことです (ここでの「トランク」とは、オンデマンドでロードされることを指します)。詳細は後で説明します)。これは、webpack-bundle-analyzer プラグインを使用して示される効果です。

entry: {
 entry: './src/main.js',
 vendor: ['vue', 'vue-router', 'vuex', 'element-ui']
 },
 // 这里的output为base中的output,不是生产的output
 output: {
 path: config.build.assetsRoot,
 filename: '[name].js',
 libraryTarget: "umd",
 publicPath: process.env.NODE_ENV === 'production' ?
  config.build.assetsPublicPath : config.dev.assetsPublicPath
 },
 externals: {
 echarts: 'echarts',
 _: 'lodash'
 },



echartsやlodashのようなライブラリは、外部なし、および外部を使用した後ではすべてのjsに表示されないことがわかります(10,000回インポートしたとしても、彼はそれをパックさえしません)一度、それはすごいです~~)。

外部についてさらに 2 つのポイント -

1. 外部のキーはインポートで使用されます

2. 外部の値はウィンドウの下で呼び出されます



それでは、話を戻します。出力がトランクではなくトランクハッシュを使用する理由について。これは永続的なキャッシュのためです。 2 つの違いについて簡単に説明します -

tru​​nk: 各ビルド後のバージョンは、ビルド後のすべてのファイルのハッシュ値が同じであることを意味します。たとえば、1 つのファイルのみを変更した場合、すべてのファイルのハッシュが同じになります。最終的には変更され、すべてのファイルがキャッシュされるため、キャッシュは無意味になります。

trunkhash:根据每个文件生成不同的hash值,当文件变化时hash会改变且只会改变相应的文件

然后我们肯定是要用到CommonsChunkPlugin,这个插件是用来抽取公共代码的,基本上99%的配置都是长这样子或者类似这样子用两个不同的commonschunkPlugin,但这从某方面来说并没有实现真正意义上的持久化缓存,这个一会我会通过webpack打包原理来详细解释其中的原因。。。。。。


new webpack.optimize.CommonsChunkPlugin({
 names: ['vendor','manifest']
})


在没用这个插件之前,我们的main.js和vendor.js会是这样子。。。

大家会看到我们这两个文件会有公共的部分,比如vue和element-ui,所以我们要抽取公共代码到vendor中,所以我们可以先这样配置


new webpack.optimize.CommonsChunkPlugin({
 name: 'vendor',
}),


但这样的话虽然可以提取公共代码,但我们会把runtime(webpack运行时的代码,一会在打包原理中会再次提到)也放到vendor中,这里面会维护一个trunk的文件列表,类似于这样,就是说我们改任意的代码,这个table里面的hash会变,所以vendor的hash也会变

,所以这没有实现真正的持久化缓存。这个hash table是按需缓存的打包出来的trunk包,一般都是通过require.ensure(就是vue-router中配置的page对应页面,按需加载)


所以我们就把name改为names,就是上面那个配置。因为使用这个插件,我们会把公共代码抽到第一个name中,把runtime放到最后一个name中,也就是我们所谓的“manifest”文件。

并且这个文件会比较小,通常都是2kb左右,所以build后会生成一个script标签,但这样的话就多了一个http请求,所以我们可以用另外一个插件(InlineManifestWebpackPlugin)将manifest.js内联进去。就会长这样子

再回到我们的CommonsChunkPlugin,现在我们随便改任何已存在的文件,vendor.js的hash都不会变,是的,貌似这就实现了持久化缓存。但是当我们新增一个模块,并且在入口文件中import一下,我们的vendor就会跟main一起变。很奇怪对吧,我们明明已经做了自己的源码跟第三方库分离,为什么vendor还会变(到现在应该没有任何一篇博客对此进行详细的说明)。下面我就详细的给大家解释下我的看法,如果大家发现有不对的地方还请指正。

再解释为什么之前,我们先简单了解下webpack的打包规则。

webpack一个entry对应一个bundle,这个bundle包括入口文件和其依赖的模块。其他按需加载的则打包成其他的bundle。还有一个比较重要的文件时manifest,它是最先加载的,负责打包其他的bundle并按需加载和执行。

manifest是一个自执行函数,熟悉angular的同学看第一行应该很了解,因为anguar1.3版本的源码中启动就是angular.bootstrap,对,这里也是一样。里面的modules变量就是对应模块函数,它是webpack处理的基本单位,就是说对应打包前的一个文件

这是js源文件,

这是打包后的文件,

所有的模块函数索引都是连续的(每个js文件生成一个trunkid!!!!!),像这种 /* 4 */ 对应的就是js文件,他通过打包就变成了一个个trunkid,仔细看会看到咱们打包前js文件里的export和require依赖都会统一转换成webpack模块。咱们说的webpackJsonp就是除manifest之外打包其他的文件的函数体。

简单说下main吧,这个图的trunkid是连续的,为了在一张图上显示,我截掉了trunk3-7.

これには 3 つのパラメータがあります。1 つ目は現在のファイルの true 識別子であり、2 つ目はパッケージ化されたすべてのファイルのモジュール関数です。すぐに実行するtrunkidモジュール関数。

わかりました、紹介はこれで十分です。

それでは、戻って、いわゆる commonschunkPlugin が変更された理由を見てみましょう。先ほども言いましたが、trunkid は js の数と同じくらい存在します。

そのため、新しい js を追加してメインの入り口に導入すると、webpack がそれを再度パッケージ化し、メイン ファイルにもう 1 つのモジュール関数が追加されます。先ほど述べたように、trunkid は順番に増加し、繰り返されません。したがって、対応するベンダーの ID は +1 になります。これは、ハッシュを変更する非常に微妙な変更です。

注意してください。どちらのベンダーも 10272 行あります。唯一の違いは、ここで jquery を自己実行したいため、このファイルには self である jquery のみが含まれていることです。 -実行中。trunkid+1 というモジュール関数が必要なので、ハッシュが変更されます。実際、これはこのプラグインの重要性を示しています。私はパブリック ライブラリを抽出したいだけですが、Webpack パッケージ化メカニズムにより、異なるファイルが生成されます。 、つまり、これは軟膏のハエです。通常、main.js を不用意に変更することはないので、別の観点から見ると、これは永続的なキャッシュの実装であることを思い出してください。しかし、ベンダーのハッシュを変更しないでおきたい場合はどうすればよいでしょうか?

はい、vue-cli をよく知っている方であれば、これは vue-cli の公式デモです。なぜそれが可能なのかについては、後ほど説明します (実際にはできません)。書きません)。

最後に、とても便利なもの、CDN をご紹介します。現在の要求は、画像を CDN に送信し、js をオンラインにできるようにすることです。ただし、これが完了すると、すべての出力が CDN を通過し、その後、すべての ajax リクエストが通過することになるというのが公式の説明です。クロスドメインになります。

当初の私の解決策は、ソースファイルを 1 つずつ置き換えることでした。これでは時間がかかります。さらに重要なのは、将来イメージを置き換えるときに、cdn イメージにもハッシュ値が含まれることです。それに応じてハッシュ。彼が自動的にハッシュを取得できるようにする方法はありますか?

はい、js がオンライン パスにアクセスし、静的リソースが cdn を使用できるように、url ローダーで cdn を個別に設定する必要があります。この 2 つは相互に影響しません。

ちょっと注意してください、url-loader は js 内の背景を検出できないため、js で参照するアドレスは最初に画像を外部にインポートする必要があり、その後 url-loader がそれを解析してパッケージ化します。

上記の内容は、webpack 学習チュートリアルのフロントエンド パフォーマンスの最適化の概要です。皆様のお役に立てれば幸いです。

関連する推奨事項:

Webpackのサーバー側コードのパッケージ化

CSSを処理するWebpackの例の詳細な紹介

Webpackの設定ファイルの詳細な説明

以上がWebpack 学習チュートリアルのフロントエンド パフォーマンス最適化の概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。