webapp性能优化
本文中提到的app前端采用的技术栈是Vue全家桶+原生js
http请求优化:
场景1:
当用户操作过快时,页面之间跳转时间缩短,在网络状态不可控的情况下,有可能造成在B页面中提示A页面的消息。
优化方案:在跳转页面的时候,对现有的且已经不需要的ajax请求进行abort操作;详细步骤如下:
1. 全局存储ajax:每次发送ajax请求时,返回一个xhr对象,然后将其存储在vuex中。vuex:commit('mutationName',xhr对象)
2. 清除上一个页面中的ajax:在全局路由守卫beforeEach
中,触发clearXhrArr
action清除所有的xhr对象,这样一来整个系统中,始终只存在与本页面相关的ajax。
ps:当某个ajax请求需要全局存在或者下一个页面依赖于前一个页面的ajax请求的时候,需要在步骤1存储xhr对象的时候设置标志位,表示该请求不应被清除。
场景2:
用户重复点击按钮,重复发送ajax请求从后台获取数据,造成服务器资源的浪费:
优化方案:序列化请求的参数组合成字符串,以该字符串为key标识一个ajax请求,并存储,当发送一个ajax请求时,首先检查该请求是否已存在,如果是,则不再重复发送。
详细步骤:
1. 定义对象存储提交的ajax;
var pendingRequests = {}
//形成一个key唯一标识一个ajax请求。
var generatePendingRequestKey = function (opts) {
var url = opts.url;
var type = opts.type;
var data = JOSN.stringify(opts.data);
var str = url + type;
if (data) {
str += data;
}
return str;
}
2 . 在ajax的ajaxBeforeSend
函数中,添加以下代码校验该请求是否已经存在;
var key = generatePendingRequestKey(settings); //settings为ajax请求的参数
if(!pendingRequests[key]){
pendingRequests[key] = xhr;
}else{
xhr.abort();
xhr.aborType = 1; //1:终止重复请求
}
3 . 在ajax的ajaxComplete
函数中,添加以下代码,删除请求完成的ajax
var key = generatePendingRequestKey(settings);//settings为ajax请求的参数
delete pendingRequests[key]; //删除对应的属性
异步加载组件:
使用webpack打包时,通过import引入的组件默认会打包在app.js中,如果所有的组件都打包在一个js文件中,那么会导致js文件过大,首屏加载速度缓慢,严重影响用户体验,因此需要引入异步模块加载;如下代码:
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')
通过这种方式引入的组件会打包在一个名为chunk名称+hash的js的文件中,这样就可以减少首屏加载时间,优化用户体验;