开发 六月 18, 2019

Vue-Cli3、multi-page多页面、i18n多语言项目打包优化

文章字数 5.9k 阅读约需 5 mins. 阅读次数 0

前言

这次主要是对打包文件 chunk-vendors文件拆包,和 chunk-common提取通用chunk 里面的多语言包进行分语言环境懒加载。
要做这这些事情,需要先了解以下内容:

i18n多语言包拆分

1.优化效果对比

首先看一下优化前后的webpack-bundle-analyzer的分析截图
优化前

从上图可以看到chunk-common.xxx.js 和chunk-vendors.xxx.js文件都特别大。700kb以上。
然而chunk-common.xxx.js文件大小主要被lang多语言包占了90%以上,然而网站加载显示的时候其实一次性加载所有语言包是没必要的。
下面看我们对多语言包进行拆分后的打包分析截图。
多语言拆包优化后

从优化后的截图看到vendors.xxx.js文件还是很大(后面我们再细讲vendors.xxx.js文件拆包优化)。再看chunk-common.xxx.js文件大小以及是160kb,这个时候它里面已经没有多语言包了。只有提取的通用代码,不过这通用代码其实我们还可以优化,让它变的更小。再看有多个多语言包的js都是按照语言分包的js。比如ar zh都是单独的语言包。在对应语言环境的时候只需要加载一种语言包就好了。拆分后的语言包js每个都小于200kb,这个状态下还有很大优化空间,我们的语言包还可以分页面以及优化语言包的key命名来减少大小。

2.多语言拆包实施

我们优化前使用vue i18n的方式都是直接

Vue.use(VueI18n)
const i18n = new VueI18n({
  locale: store.getters.currentLang,
  messages: {
    ar: {...},
    zh: {...},
    en: {...}
  }
})

这样虽然单页面切换语言可以不强制刷新页面就直接切换语言,但是带来的后果是打包资源大量被语言包占用。

所以我们看看vue-i18n的延迟加载翻译的文档

可以看到,文档最前面就说到:一次加载所有翻译文件是过度和不必要的。使用 Webpack 时,延迟加载或异步加载转换文件非常简单。
这就是我们想要的!
按照文档搞完后,调整了语言包的结构,通过在router.beforeEach里面来懒加载要切换的语言包,这样不仅语言包打包被拆分。单页面切换语言也可以达到不强制刷新页面的体验。(如果你们网站的路由里面就有多语言参数那就更好处理了)

router.beforeEach((to, from, next) => {
  const lang = to.params.lang
  loadLanguageAsync(lang).then(() => next())
})

我们可以通过检查 lang 是否实际上是否支持来改进这一点,调用 reject 这样我们就可以在 beforeEach 捕获路由转换。

弃用占用资源超大并使用价值不打的依赖库


以我们项目为例,从打包分析图看出我们的chunk-vendors.xxx.js目前占用767kb。算是单文件比较大的了,如果用户网速比较慢加载大概需要2秒左右。

我们在看看分析图chunk-vendors.xxx.js里面主要被moment和swiper.js所占据。
去看了项目里面对moment依赖库的使用,主要是用来做时间格式显示的转换。这个小功能完全不用这样的一个依赖库。在看moment里面主要是被多语言资源给占据,因为这个依赖库主要为了适配各个地区国家的时间显示格式。所有决定把moment这个依赖库uninstall。

去看了一下vue-i18n(多语言国际化依赖库)的文档发现我们用的多语言库就可以帮我们实现时间格式化 Vue I18n 日期时间本地化

然后我们就进行了代码替换,使用 vue-i18n 的 $d(Date, ‘YMD’)

然后uninstall moment依赖库后的打包分析图,chunk-vendors.xxx.js减少到502KB

依赖库拆包减少vendors.xxx.js文件大小

从上面看的我们 chunk-vendors.xxx.js 虽然moment依赖弃用后,在chunk-vendors.xxx.js 中Swiper.js就浮现,目前swiper.js是占了大头,所以枪打出头鸟,我们现在就来想办法把Swiper.js进行拆包出来。
修改vue.config.js的configureWebpack配置,配置splitChunks

module.exports = {
    configureWebpack: {
        optimization: {
            splitChunks: {
                cacheGroups: {
                    common: {
                        name: 'chunk-common',
                        minChunks: 2,
                        priority: -20,
                        chunks: 'initial',
                        reuseExistingChunk: true,
                        enforce: true // 加chunk-common的复写配置,主要是设置强制,因为发现加了下面的chunk-swiper,chunk-common就不生成了。资源会被合并到入口页面的js里面。可能是splitChunks有啥机制判断适当情况才生成chunk-common。
                    },
                    swiper: {
                        name: 'chunk-swiper',
                        test: /[\\/]node_modules[\\/]swiper[\\/]/,
                        chunks: 'initial',
                        priority: 1,
                        reuseExistingChunk: true,
                        enforce: true
                    }
                }
            }
        }
    },
}

然后在vue.config.js 的pages配置
的chunks属性加上’chunk-swiper’的引用

pages:[{
    entry: path,
    template: './src/public/index.html',
    filename: 'index.html',
    //   title: 'title',
    chunks: ['chunk-vendors', 'chunk-common', 'chunk-swiper', index]
}]

然后再执行打包,看的打包分析图,vendors.xxx.js减少到375KB🤩

总结

优化打包的方法有很多种,选择适合自己的就好了。
比如还可以把vue相关的js用cdn减少文件打包体积等
利用Webpack dllPlugin提示打包热编译速度,减少打包文件大小。
只要你想去做,意愿够强,看似很难完成的事情其实有千万中方式可以解决。

0%