背景
我们有一个微信小程序,在迭代的过程中,为了赶进度,最初里面大部分页面都是利用 web-view
组件嵌套h5站点来实现的;h5站点,就是利用的vue-cli官方那一套搭建的单页面应用;随着项目的推进,迭代的节奏开始慢下来,老生常谈的前端项目优化问题,终于被提上了日程(主要有人吐槽加载太慢了)
调研
由于h5站点是用微信小程序 web-view 组件渲染,所以曾经有一个方向是去看微信文档,去小程序社区看看,有没有解决方法,由此找到了下面几篇文章
- 安卓web-view加载页面慢,一直空白。但是苹果手机可以打开,怎么解决
- 小程序web-view打开h5 加载很慢? 顶部绿色进度条一直加载 没加载完成 跳转到小程序方法不执
- ios首次加载web-view缓慢?
分析过后,其实大部分的问题好像都和web-view组件关系不是很大,那还是回到h5站点项目的优化上吧
落地方案
直接上结论,优化的部分主要有以下几个点:
单页面应用转多页面(多入口)
项目经过几个迭代之后,很多h5站点的页面都被抛弃了,或被原生重写;那么此刻单页面应用,对于h5站点的加载速度,会有很大影响;因为那些用不上的页面js,引用的第三方库或者组件,可能会被打入 vendor.js 中,导致整理包体积过大。
- 1、去除 vue-router
- 2、生成各个入口文件的js文件 (这里是用 node 写的脚本,目的就是生成类似于 main.js 的入口文件)
- 2、配置 vue.config.js
// vue.config.js
const glob = require('glob');
const path = require('path');
// 获取所有的页面入口文件
// 本项目所有入口js文件都以 `Html.js` 结尾 且都在 views 文件夹下
const PAGE_PATH = path.resolve(__dirname, './src/views/**/*Html.js')
const pages = {};
// 利用 glob.sync 遍历文件,组成如下pages 结构
/**
* pages = {
index: 'src/views/indexHtml.js',
home: 'src/views/homeHtml.js',
cart: 'src/views/cartHtml.js',
}
*/
glob.sync(PAGE_PATH).forEach(filePath => {
var filename = filePath.replace(/(.*)src/(.*)/(.*)Html.js/,'$3');
var fileAbsolutePath = filePath.replace(/(.*)src/views/(.*).js/,'$2');
pages[filename.toLowerCase()] = `src/views/${fileAbsolutePath}.js`
})
module.exports = {
// ...code
pages
// ...code
}
复制代码
上面的 pages
项,这么配置之后,构建完成之后就会生成多个 [entry].html
文件,但是模版都是用的 public/index.html
(埋下了坑)
分析依赖 -> chunk-vendor.js 过大
项目中,我们主要用到了的第三方库有 vue
、echarts
、tim-js-sdk
、js-cookies
上面这些第三方库,默认都被构建打包到chunk-vendor.js中,所以这个js显得格外的大,并且它被各个入口的.html文件引用
于是我们把这些包单独用 script 标签,在index.html里引入,并配置 configureWebpack.externals
,从而减小 chunk-vendor.js 的体积
配置方法可以参考 外部扩展(Externals)
代码语言:javascript复制 // vue.config.js
let webpackConfig = {
// ...code
// ...code
}
if(process.env.NODE_ENV === 'production') {
webpackConfig.configureWebpack.externals = {
'vue':"Vue",
'echarts':'echarts',
// ...
}
}
module.exports = webpackConfig
复制代码
除此之外,我们还做了一件事,修改了 index.html
代码语言:javascript复制 <!DOCTYPE html>
<html lang="cn">
<head>
</head>
<body>
<noscript>
<strong>We're sorry but vue-base doesn't work properly without JavaScript enabled. Please enable it to
continue.</strong>
</noscript>
<div id="app"></div>
<% if(process.env.NODE_ENV==='production' ){ %>
<script src="<%= process.env.VUE_APP_publicPath %>/vue.runtime.min.js"></script>
<script src="<%= process.env.VUE_APP_publicPath %>/echarts.min.js"></script>
<% } %>
</body>
</html>
复制代码
!!! 可以看出,只有在生产环境中,我们才会启用 externals
配置,原因是:公司网络不好,外部js引入老是超时