前言
webpack之optimization.runtimeChunk有什么作用?
runtimeChunk,直观翻译是运行时的chunk文件,其作用是啥呢,通过调研了解了一波,在此记录下。
何为运行时代码?
形如import(‘abc’).then(res=>{})这种异步加载的代码,在webpack中即为运行时代码。
在VueCli工程中常见的异步加载路由即为runtime代码。
1 | { |
optimization.runtimeChunk作用验证
实践才是真理,直接上测试。不过要是有时间仔细阅读理解webpack关于optimization.runtimeChunk的源码也是可以的。
1、搭建简单的vue项目,使用vuecli新建一个只需要router的项目,脚手架默认路由配置了一个异步加载的about路由,如上图所示
2、不设置runtimeChunk时,查看打包文件,此时不需要做任何操作,因为其默认是false,直接yarn build,此时生成的主代码文件的hash值为7d50fa23。
3、接着改变about.vue文件的内容,再次build,查看打包结果,发现app文件的hash值发生了变化。
设置runtimeChunk是将包含chunks 映射关系的 list单独从 app.js里提取出来,因为每一个 chunk 的 id 基本都是基于内容 hash 出来的,所以每次改动都会影响它,如果不将它提取出来的话,等于app.js每次都会改变。缓存就失效了。设置runtimeChunk之后,webpack就会生成一个个runtime~xxx.js的文件。
然后每次更改所谓的运行时代码文件时,打包构建时app.js的hash值是不会改变的。如果每次项目更新都会更改app.js的hash值,那么用户端浏览器每次都需要重新加载变化的app.js,如果项目大切优化分包没做好的话会导致第一次加载很耗时,导致用户体验变差。现在设置了runtimeChunk,就解决了这样的问题。所以这样做的目的是避免文件的频繁变更导致浏览器缓存失效,所以其是更好的利用缓存。提升用户体验。具体关于浏览器缓存参考:https://web.dev/use-long-term-caching/
4、新建vue.config.js,配置runtimeChunk,第一次打包,然后修改about,在打包一次,查看2次打包之后app文件的hash值的变化。
1 | // vue.config.client.js |
设置了runtimeChunk配置后,就算对应页面组件内容变更了,打包的app.xxxxxxxx.js的哈希版本号不会变更。会报表抽离生成一个manifest.xxxxxxx.js的文件。
设置runtimeChunk导致的新问题
1、查看一下manifest.xxxxxxx.js文件内容:
发现文件很小,且就是加载chunk的依赖关系的文件。虽然每次构建后app的hash没有改变,但是manifest.xxxxxxx.js会变啊。每次重新构建上线后,浏览器每次都需要重新请求它,它的 http 耗时远大于它的执行时间了,所以建议不要将它单独拆包,而是将它内联到我们的 index.html 之中。
最终解决方案
SPA解决方案
对于单页面应用(SPA)可以webpack的html相关插件。这边我们使用script-ext-html-webpack-plugin来实现。(也可使用html-webpack-inline-source-plugin,其不会删除manifest.xxxxxxx.js文件。)
1 | // vue.config.js |
重新打包,查看index.html文件
1 |
|
index.html中已经没有对manifest.xxxxxxx.js的引用了,而是直接将其代码写入到了index.html中,故不会在请求文件,减少http请求。
SSR解决方案
webpack打包插件对于服务端渲染的html没有用,因为服务端的js引用关系都是根据 vue-ssr-server-bundle.json 动态注入的。所以我就没有从webpack插件入手,直接从Node服务端去调整,不动webpack打包配置。
1 | const serverBundle = require('../public/vue-ssr-server-bundle.json') |
在createRenderer之前把从vue-ssr-client-manifest.json获取到的initial文件路径中把manifest.xxxxxxx.js文件筛选出来并从initial中移除(移除后在自动注入引用link的时候就不会把manifest文件用link标签引入),并记录manifest.xxxxxxx.js的具体值,因为这个manifestPath后面我们还要用到,后面需要读取这个文件路径里面的js代码注入到渲染的html里面去。
1 | const exportManifestJsCode = () => { |
获取manifestPath里面的代码,生成script代码段。
1 | context.manifestJsCode = exportManifestJsCode() |
把生成的ManifestJsCode导出给context.manifestJsCode
1 |
|
最后在ssr的html模版对应位置用3大括号{{{manifestJsCode}}}
将manifestJsCode注入到html对应位置。
⚠️这个是对VueSSR指南手动构建项目的解决方案,Nuxt服务端渲染框架解决办法还没研究。
- 本文标题:SSR项目optimization.runtimeChunk还有哪些优化的可能
- 本文作者:Madman
- 创建时间:2022-09-21 11:45:17
- 本文链接:https://www.patpat.site/开发/前端/SSR项目optimization-runtimeChunk还有哪些优化的可能.html
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!