ホームページ > ウェブフロントエンド > jsチュートリアル > Vue パッケージ化最適化コード spliting_vue.js

Vue パッケージ化最適化コード spliting_vue.js

不言
リリース: 2018-04-10 14:45:43
オリジナル
1325 人が閲覧しました

この記事では主に Vue のパッケージ化最適化のためのコード分割の詳細な説明を紹介しますので、必要な方は参考にしてください。

http1 の時代では、一般的なパフォーマンスの最適化は http の数をマージすることです。通常、多くの js コードをマージしますが、js パッケージのサイズが特に大きい場合、パフォーマンス向上のためには少し過剰になります。そして、すべてのコードを合理的に分割し、最初の画面と非最初の画面のコードを剥がし、ビジネス コードと基本ライブラリのコードを分割し、必要なときに特定のコード部分をロードする場合は、次回必要に応じてロードします。もう一度使用すると、キャッシュから読み取れます。第 1 に、ブラウザのキャッシュを有効に活用できるため、最初の画面の読み込み速度が向上し、ユーザー エクスペリエンスが大幅に向上します。

コアアイデア

ビジネスコードと基本ライブラリの分離

これは実際には理解しやすいですが、ビジネスコードは通常頻繁に更新され、基本ライブラリは通常ゆっくりと更新されます。ブラウザのキャッシュを最大限に活用して、基本的なライブラリ コードをロードします。

オンデマンドの非同期ロード

これは主に、最初の画面にアクセスするときに、すべてのルーティング コードをロードするのではなく、最初の画面に必要なロジックをロードするだけで済みます。

実践的な戦闘

最近、vuetify を使用して内部システムを変換しました。最初は最もよく使用される webpack 構成を使用しましたが、パッケージ化すると、その効果がわかりました。あまり明らかではなく、多くの大きなパッケージが生成されました

ここで、webpack-bundle-analyzer が使用されていることがわかります。vue や vuetify などのモジュールが繰り返し使用されています。梱包された。

ここでは、最初に設定を投稿し、後で分析に使用します:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

const path = require('path')

const webpack = require('webpack')

const CleanWebpackPlugin = require('clean-webpack-plugin')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

 

const generateHtml = new HtmlWebpackPlugin({

 title: '逍遥系统',

 template: './src/index.html',

 minify: {

 removeComments: true

 }

})

 

module.exports = {

 entry: {

 vendor: ['vue', 'vue-router', 'vuetify'],

 app: './src/main.js'

 },

 output: {

 path: path.resolve(__dirname, './dist'),

 filename: '[name].[hash].js',

 chunkFilename:'[id].[name].[chunkhash].js'

 },

 resolve: {

 extensions: ['.js', '.vue'],

 alias: {

  'vue$': 'vue/dist/vue.esm.js',

  'public': path.resolve(__dirname, './public')

 }

 },

 module: {

 rules: [

  {

  test: /\.vue$/,

  loader: 'vue-loader',

  options: {

   loaders: {

   }

   // other vue-loader options go here

  }

  },

  {

  test: /\.js$/,

  loader: 'babel-loader',

  exclude: /node_modules/

  },

  {

  test: /\.(png|jpg|gif|svg)$/,

  loader: 'file-loader',

  options: {

   objectAssign: 'Object.assign'

  }

  },

  {

  test: /\.css$/,

  loader: ['style-loader', 'css-loader']

  },

  {

  test: /\.styl$/,

  loader: ['style-loader', 'css-loader', 'stylus-loader']

  }

 ]

 },

 devServer: {

 historyApiFallback: true,

 noInfo: true

 },

 performance: {

 hints: false

 },

 devtool: '#eval-source-map',

 plugins: [

  new BundleAnalyzerPlugin(),

  new CleanWebpackPlugin(['dist']),

  generateHtml,

  new webpack.optimize.CommonsChunkPlugin({

  name: 'ventor'

  }),

 ]

}

 

if (process.env.NODE_ENV === 'production') {

 module.exports.devtool = '#source-map'

 // http://vue-loader.vuejs.org/en/workflow/production.html

 module.exports.plugins = (module.exports.plugins || []).concat([

 new webpack.DefinePlugin({

  'process.env': {

  NODE_ENV: '"production"'

  }

 }),

 new webpack.optimize.UglifyJsPlugin({

  sourceMap: true,

  compress: {

  warnings: false

  }

 }),

 new webpack.LoaderOptionsPlugin({

  minimize: true

 })

 ])

}

ログイン後にコピー

CommonChunkPlugin

ventor 入口 ここで、axios など、node_module の下にあるすべての参照モジュールがフィルタリングされていないことがわかりました。ここで app.js にパッケージ化されます

1

2

3

4

entry: {

 vendor: ['vue', 'vue-router', 'vuetify', 'axios'],

 app: './src/main.js'

 },

ログイン後にコピー

次に、ここで別の問題が発生します。この時点では、モジュールを自動的に分割する必要があるかもしれません。ここで、MinChunks を導入する必要があります。設定では、次のように mode_module で参照されるモジュールをパッケージ化して変更できます

1

2

3

4

5

6

7

8

9

10

11

12

13

entry: {

 //vendor: ['vue', 'vue-router', 'vuetify', 'axios'], //删除

 app: './src/main.js'

 }

 

new webpack.optimize.CommonsChunkPlugin({

  name: 'vendor',

  minChunks: ({ resource }) => (

   resource &&

   resource.indexOf('node_modules') >= 0 &&

   resource.match(/\.js$/)

  )

 }),

ログイン後にコピー

上記の手順の最適化後、ファイルの配布を調べて次のことを確認します。 node_module の下のモジュール すべてベンダーの下に収集されます。

ここで経験を得ることができます。つまり、プロジェクトでは、node_module の下のモジュールを具体的にパッケージ化して最適化できます。しかし、ここで注意してみると、codemirror コンポーネントは、node_module にもあるのに、パッケージ化されずに他の単一ページに繰り返しパッケージ化されるのはなぜでしょうか。実際、これは、commonChunk で name 属性を使用することは、実際には Follow のみを意味するためです。コンポーネントは非同期でロードされるため、ここではパッケージ化されません。ここで、dbmanage およびシステム ページのルーティング遅延ロードを削除し、直接導入に変更します。

1

2

3

4

// const dbmanage = () => import(/* webpackChunkName: "dbmanage" */'../views/dbmanage.vue')

// const system = () => import(/* webpackChunkName: "system" */'../views/system.vue')

import dbmanage from '../views/dbmanage.vue'

import system from '../views/system.vue'

ログイン後にコピー

この時点で、再パッケージ化すると、codemirror がパッケージ化されていることがわかります。それで問題は、これで良いのかということです。

async

上記の質問に対する答えは、明らかに「はい」、「いいえ」です。最初の画面である ventor は、この codemirror コンポーネントをロードする必要はまったくありません。変更は復元されましたが、コードミラーが同時に 2 つの単一ページにパッケージ化され、MTable や MDataTable などの一部の自己カプセル化コンポーネントも繰り返しパッケージ化されました。また、コードミラーは非常に大きいため、2 つの単一ページを同時にロードすると、パフォーマンスに大きな問題が発生します。簡単に言うと、最初の単一ページにコードミラーをロードした後、2 番目のページをロードすべきではありません。 この問題を解決するために、ここでは CommonsChunkPlugin の async と minChunks の count メソッドを使用して、2 つの非同期読み込みモジュール (つまり、import () によって生成されたチャンク) を含めて 2 回以上再利用される限り、数量を決定できます。 、それを考慮します ここでは、構成を追加します。

りー

再次打包,我们发现所有服用的组件被重新打到了 0.used-twice-app.js中了,这样各个单页面大小也有所下降,平均小了近10k左右

可是,这里我们发现vuetify.js和vuetify.css实在太庞大了,导致我们的打包的代码很大,这里,我们考虑把它提取出来,这里为了避免重复打包,需要使用external,并将vue以及vuetify的代码采用cdn读取的方式,首先修改index.html

1

2

3

4

5

6

7

8

9

//css引入

<link href=&#39;https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons&#39; rel="stylesheet" type="text/css">

<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="external nofollow" rel="stylesheet">

//js引入

<script src="https://unpkg.com/vue/dist/vue.js"></script>

<script src="https://unpkg.com/vuetify/dist/vuetify.js"></script>

 

//去掉main.js中之前对vuetifycss的引入

//import &#39;vuetify/dist/vuetify.css&#39;

ログイン後にコピー

再修改webpack配置,新增externals

1

2

3

4

externals: {

 &#39;vue&#39;:&#39;Vue&#39;,

 "vuetify":"Vuetify"

 }

ログイン後にコピー

再重新打包,可以看到vue相关的代码已经没有了,目前也只有used-twice-app.js比较大了,app.js缩小了近200kb。

但是新问题又来了,codemirror很大,而used-twice又是首屏需要的,这个打包在首屏肯定不是很好,这里我们要将system和dbmanage页面的codemirror组件改为异步加载,单独打包,修改如下:

1

2

3

4

5

6

// import MCode from "../component/MCode.vue"; //注释掉

 

components: {

  MDialog,

  MCode: () => import(/* webpackChunkName: "MCode" */&#39;../component/MCode.vue&#39;)

 },

ログイン後にコピー

重新打包下,可以看到 codemirror被抽离了,首屏代码进一步得到了减少,used-twice-app.js代码缩小了近150k。

做了上面这么多的优化之后,业务测的js基本都被拆到了50kb一下(忽略map文件),算是优化成功了。

总结

可能会有朋友会问,单独分拆vue和vuetify会导致请求数增加,这里我想补充下,我们的业务现在已经切换成http2了,由于多路复用,并且加上浏览器缓存,我们分拆出的请求数其实也算是控制在合理的范畴内。

这里最后贴一下优化后的webpack配置,大家一起交流学习下哈。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

const path = require('path')

const webpack = require('webpack')

const CleanWebpackPlugin = require('clean-webpack-plugin')

const HtmlWebpackPlugin = require('html-webpack-plugin')

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

 

const generateHtml = new HtmlWebpackPlugin({

 title: '逍遥系统',

 template: './src/index.html',

 minify: {

 removeComments: true

 }

})

 

module.exports = {

 entry: {

 app: './src/main.js'

 },

 output: {

 path: path.resolve(__dirname, './dist'),

 filename: '[name].[hash].js',

 chunkFilename:'[id].[name].[chunkhash].js'

 },

 resolve: {

 extensions: ['.js', '.vue'],

 alias: {

  'vue$': 'vue/dist/vue.esm.js',

  'public': path.resolve(__dirname, './public')

 }

 },

 externals: {

 &#39;vue&#39;:&#39;Vue&#39;,

 "vuetify":"Vuetify"

 },

 module: {

 rules: [

  {

  test: /\.vue$/,

  loader: 'vue-loader',

  options: {

   loaders: {

   }

   // other vue-loader options go here

  }

  },

  {

  test: /\.js$/,

  loader: 'babel-loader',

  exclude: /node_modules/

  },

  {

  test: /\.(png|jpg|gif|svg)$/,

  loader: 'file-loader',

  options: {

   objectAssign: 'Object.assign'

  }

  },

  {

  test: /\.css$/,

  loader: ['style-loader', 'css-loader']

  },

  {

  test: /\.styl$/,

  loader: ['style-loader', 'css-loader', 'stylus-loader']

  }

 ]

 },

 devServer: {

 historyApiFallback: true,

 noInfo: true

 },

 performance: {

 hints: false

 },

 devtool: '#eval-source-map',

 plugins: [

  new CleanWebpackPlugin(['dist']),

  generateHtml

 ]

}

 

if (process.env.NODE_ENV === 'production') {

 module.exports.devtool = '#source-map'

 module.exports.plugins = (module.exports.plugins || []).concat([

 new BundleAnalyzerPlugin(),

 new webpack.optimize.CommonsChunkPlugin({

  name: 'ventor',

  minChunks: ({ resource }) => (

  resource &&

  resource.indexOf('node_modules') >= 0 &&

  resource.match(/\.js$/)

  )

 }),

 

 new webpack.optimize.CommonsChunkPlugin({

  async: 'used-twice',

  minChunks: (module, count) => (

  count >= 2

  ),

 }),

 

 new webpack.DefinePlugin({

  'process.env': {

  NODE_ENV: '"production"'

  }

 }),

 new webpack.optimize.UglifyJsPlugin({

  sourceMap: true,

  compress: {

  warnings: false

  }

 }),

 new webpack.LoaderOptionsPlugin({

  minimize: true

 })

 ])

}

ログイン後にコピー

相关推荐:

vue.js中created方法的使用详解

如何修改Vue.js中scoped模式下的子组件内部标签样式

Vue中computed与methods的区别详解_vue.js

以上がVue パッケージ化最適化コード spliting_vue.jsの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート