35

A better strategy for long term caching

 4 years ago
source link: https://www.tuicool.com/articles/hit/Jz6baya
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
YJ7zeiM.jpg!webbYfmqeU.jpg!web

A better strategy for long term caching

Recently I have moved my complex front end application from webpack 3 to webpack 4 . It was almost smooth unless I faced long term caching problem . Webpack 4 doesn’t provide out-of-the-box support for long term caching, so I had to play around to make it work.

In this article, I will be comparing my previous long term caching strategy(fixed vendor caching strategy) in webpack 3 with a modified strategy(all modules caching strategy) in webpack 4 . I could have done a comparison of these two strategies with keeping the same version of webpack, but I didn’t. Webpack version doesn’t matter for this comparison and I wanted to give you value by helping in the webpack upgrade.

Long term caching of your..ok wait.. let’s define long term caching first

Long term caching: It is to improve app loading time by keeping parts of the app on the client and avoid re-downloading them every time.

Long term caching of your app assets is very important in improving load time. In the browser world, we tell the browsers to cache files forever or with max age Cache-Control: max-age=31536000 and rename the file when it changed to force the re-download. In webpack, we specify the file hash in the name which will change with its content change.

// webpack.config.js
...
entry{
   app:'app/index.js'
},
output: {
  filename: 'static/js/[name]-[chunkhash].js'  
}
...

App dependencies(node_modules) tends to change less often than the actual app code. If we are able to move them into a separate file, the browser will be able to cache them separately and won’t re-download them each time the app code changes.

Asset    Size       Chunks       Chunk Names
  ./app.7ac6fe319.js    50kB       0  [emitted]  main
./vendor.71799aeda.js   60kB       1  [emitted]  vendor

hmm. So far I have set up the background. Beside this few keywords, I want you to remember while dealing with webpack configurations.

vendor: it’s all that’s in node_modules. But you are allowed to customize it. 

chunks:we segregate our code in files and import them into our code. That’s chunks. Dynamically imported chunks are dynamic chunks. common: common in webpack 4, optimization.splitChunks.cacheGroup, is a bundle which you configure for common modules between multiple entries.

Let’s define “normal scenario” for caching before strategy:

I am locking my long term caching scenario for the few following types of circumstances

  1. Bob visit my website daily
  2. We update our website every third day
  3. In 10 days we add/update npm package

I will use this same scenario to get the downloaded size of files from two strategies

1. Fixed vendor caching strategy

2. All modules caching strategy

Fixed vendor caching strategy:

In webpack 3, we had a fixed vendor caching strategy.

/* webpack.config.js
* webpack 3
*/ 
entry: {
    app: './app/index.js'
    vendor: ['react', 'react-dom', 'redux', 'react-router-dom']   
},
plugins: [
    new webpack.optimize.CommonsChunkPlugin({name: 'vendor'})
]

We were telling the browser which should go into the vendor.js file, which is [‘react’, ‘react-dom’, ‘redux’, ‘react-router-dom’] modules. Rest will go in the app.js This strategy has pros and cons.

M7j6Z3y.png!web1*PCcEDeRMJEcR6QIZ3xFEWQ.png
F36NbaQ.png!webUJ3Mvam.png!web

In the above screenshots, you can see the app.js bundle changed with a change in the app code(I have imported a new file) but vendor.js remains the same. Cool

Download $ize With “normal scenario” :

NRR3E3a.jpg!web
Downloaded data(kbs) in 10 days

Our app.js file hash gets updated every third day and vendor.js every 10th day.

Total download size for 10 days = 753kbs (307+103+103+103+120)

Pros:

1. We can define which few node_module should go in the vendor, which will make it less prone to change, hence better long term caching.

Cons:

1. We have to configure each time we add a new module.

2. If we don’t add, it will be added in the app bundle which will get changed with every code change.

3. We add/upgrade/remove more module(s), then vendor bundle will become more prone to change.

All modules caching strategy:

With webpack 4, we have changed our long term caching strategy to all node_mocule cache strategy . To do this, we changed our webpack config to

/* webpack.config.js
* webpack 4
*/
entry{
app: './app/index.js'
}
...
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
/* test: /[\\/]node_modules[\\/](react|react-dom|redux|react-router-dom)[\\/]/,
*/
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'initial',
},
},
},
}
plugins: [
...
/* for issue: https://github.com/webpack/webpack/issues/1315 */
new webpack.NamedModulesPlugin(),
new webpack.NamedChunksPlugin(),
new webpack.HashedModuleIdsPlugin(),
]

Note:Why did I add the above 3 plugins? Read long term caching issue with webpack .

j6zii27.png!webz2yy63m.png!web
RNFBZfR.png!webMbu6baQ.png!web

With code change app.js changed but vendor.js remain the same.

Download $ize with “normal scenario”:

q2Ebmq6.jpg!web
Downloaded data(kbs) in 10 days

Total download for 10 days = 595kb (280 + 6 + 6 + 6 + 297)

Pros: 

1. Every node_module will be bundled in vendor.js , so we don’t have to take the overhead of adding a new module into the entry(webpack 3) or adding in splitChunks.cacheGroup (webpack 4) every time we add a new module.

2. The overall download size will reduce. (I will prove this next).

Cons:

1. As we have added all the modules into the vendor bundle, chances of its cache burst have increased.

Comparison:

fixed vendor caching strategy = 736 kbs

all node_mocule cache strategy = 595 kbs

Which is 20% reduction in download size.

The End

You must have found this useful, “Press clap”.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK