spa
全称是单页面应用。 一个SPA就是一个WEB应用,它所需的资源(HTML CSS JS等),在一次请求中就加载完成,也就是不需刷新地动态加载。 用术语“单页”就是因为页面在初始化加载后就永远不会重新加载刷新。 优点 减轻服务器端的压力。 因为服务器先将一份包含了静态资源、JavsScript和模板的静荷数据(payload)发送到了客户端,之后客户端只需要获取渲染页面或视图所需要的数据即可。 payload就是起关键作用的资源 提高了页面的渲染效果。 由于移动设备的流行,可以开发提供JSON格式数据的网络服务,然后可以提供不同的客户端使用。 SPA的使用,我们可以使用一个HTTP API,一个HTTP API相比在服务端渲染一个HTML页面有诸多好处,这样就可以很方便的进行单元测试等操作,还可以被其他很多客户端程序所用。 SPA最大的好处就是大量的工作都在浏览器中完成,服务端承担更少的工作,这样就可以处理更多的请求。同时SPA需要额外的请求模版开销,我们可以通过预编译模版、缓存机制和将多个模板拼接成一个大的模板来减少请求数量。
缺点 首屏加载时间会很长。SEO不友好。 主要是因为SPA利用了hash片段实现路由,而利用hash片段不会作为HTTP请求中的一部分发送给服务器。 而SPA使用hash片段的目的是:**当片段的内容发送变化时,浏览器不会像URI发送变化时那样发起新的网络请求。**这样就可以只请求页面或视图渲染所需要的数据,而不是为每一个页面获取并解析整份文档。
webpack-bundle-analyzer
安装启用webpack-bundle-analyzer 插件 安装 npm i webpack-bundle-analyzer –D
在chainWebpack(链式配置函数里) 增加 if (process.env.NODE_ENV === 'production') { if (process.env.npm_config_report) { config .plugin('webpack-bundle-analyzer') .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin) .end(); } } 然后在package.json 配置 "report": "npm run build --report=true" 执行 npm run report 进行分析,我们可以看到总包大小为 7.56MB
以及对应的主要文件分布:
开发环境每次清缓存后,重新打开浏览器调用测试五次,取平均值。 开发环境系统,初次首屏加载时间为 12.4s。发送137个请求。 其中:chunk-vendors.xxx.js的加载时间最长达到了 8.49s。
1 降低请求数量
将所有的路由设置为异步加载。只是把各个子功能分出去,调用的时候才加载。但是并不会降低总大小。 将同步加载更改为异步加载。路由中这么写: component: () => import('../components/dynamic/secondaryMarket/secondaryMarket.vue'),
2 删除 Prefetch 和 PreLoad规则
先理解 prefetch和preload
复制代码
这段代码告诉浏览器,这段资源将会在未来某个导航或者功能要用到,但是本资源的下载顺序权重比较低。也就是说prefetch通常用于加速下一次导航,而不是本次的。 被标记为prefetch的资源,将会被浏览器在空闲时间加载。
复制代码
preload通常用于本页面要用到的关键资源,包括关键js、字体、css文件。preload将会把资源得下载顺序权重提高,使得关键数据提前下载好,优化页面打开速度。 关闭prefetch
chainWebpack: (config) => {
/* 添加分析工具*/
if (process.env.NODE_ENV === 'production') {
if (process.env.npm_config_report) {
config
.plugin('webpack-bundle-analyzer')
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
.end();
config.plugins.delete('prefetch')
}
} }
复制代码
进行测试: 开发环境首屏加载的总速度大约在 10.6s。发送102个请求。 其中:chunk-vendors.xxx.js的加载时间最长达到了 7.71s;
3 拆分大文件
Jquery.js 引用过多,暂时没有办法一次清楚 Core.js 不知道自己为什么加载了他,太大了。删掉。 Vue-cookie 采用自己封装的函数替代。 Element-ui 太大了。按需引用。 Element-ui-common.js 文件太大。
import {Dropdown,DropdownMenu,Tree,Popover, Input,Button,Dialog,Loading,Table,TableColumn,Pagination,MessageBox,Message,DatePicker,Popconfirm} from from 'element-ui';
//element-ui需要按需加载
Vue.use(Dropdown);
Vue.use(DropdownMenu);
Vue.use(Tree);
Vue.use(Popover);
Vue.use(Input);
Vue.use(Button);
Vue.use(Dialog);
Vue.use(Table);
Vue.use(Loading);
Vue.use(TableColumn);
Vue.use(Pagination);
Vue.use(DatePicker);
Vue.use(Popconfirm);
复制代码
开发环境首屏加载的总速度大约在 9.9s。发送102个请求。 其中:chunk-vendors.js的加载时间最长达到了 6.91s; 这一步的优化效果不是很理想,原因是element-ui即使拆开配置也会带上 element-ui-common.js,此文件过大。其他的其实占比不是很明显。Jquery的引用又改动代码太多,没办法很快去掉。
4 Gzip
安装并使用 compression-webpack-plugin 组件。 在webpack配置文件中新增,对超过10K的数据进行压缩。
new CompressionPlugin({
test: /\.js$|\.html$|\.css/, //匹配文件名
threshold: 10240, //对超过10k的数据进行压缩
deleteOriginalAssets: false //是否删除原文件
})
复制代码
再执行npm run build
我们发现打包后的超过10k的文件都生成了对应 .gz文件。此处需要开启ngix的 Gzip配置(目前主流的浏览器都支持)。当浏览器支持 gzip的情况下会读取.gz文件。当不支持的情况会读取原文件。
开发环境首屏加载静态资源的时间大约在 3.2s。发送102个请求。 其中:chunk-vendors.js的加载时间最长达到了 2.63s;效果显著
5 CDN
针对之前第3步优化不理想的情况下,有了第5步的优化。将引用的大组件,主要是 vue element-ui 和 echart,jquery四个大组件。转为请求CDN上的资源。而非打包进咱们的包里。 在index.html 中设置
复制代码
在webpack配置文件里设置configureWebpack设置策略
externals:{
'echarts':'echarts',
‘vue-router:'vue-router',
‘vue:'vue',
},
复制代码
开发环境首屏加载静态资源的时间大约在 1.89s。发送102个请求。 其中:chunk-vendors.js的加载时间最长达到了 0.49s;效果显著 此处测试采用的是 cdn.bootcss.com 上的资源。还测试一些其他的免费CDN节点的资源。 注意:免费CDN可能会有崩溃的风险。此处可以考虑自建或者商用CDN节点。
1 动态polyfill
polyfill的含义此处不做解释。vue-cli项目用到的最多的主要是 babel-polyfill。讲es6,7等语法转为 es5以方便一些老的浏览器来支持。动态polyfill指的是根据浏览器,载入需要的polyfill。 Polyfill.io【也可以使用的阿里的polyfill】通过尝试使用polyfill重新创建缺少的功能,可以更轻松地支持不同的浏览器,并且可以大幅度的减少构建体积。
2 现代模式
有了 Babel 我们可以兼顾所有最新的 ES6,7 语言特性,但也意味着我们需要交付转译和 polyfill 后的包以支持旧浏览器。这些转译后的包通常都比原生的 ES6,ES7 代码会更冗长,运行更慢。现如今绝大多数现代浏览器都已经支持了原生的ES6,7特性。vue-cli 其实提供一种现代模式,本质上是本质上是有条件的加载polyfill,在运行时检测他们的支持。
作者:嚣张的胖头鱼
链接:https://juejin.im/post/5e84310b51882573b627e130
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。