项目之中的性能优化
- 性能优化
-
按需加载
- 路由的懒加载模式,Home首页采用一进入页面就加载的方式导入,然后其他的则是采用路由懒加载的模式
- UI框架的按需加载方式
-
代码质量
- Eslint
-
http请求优化
- 合并压缩,就是同一个页面的相同请求,合并为一个请求
-
图片优化
- 合并和压缩,小的img可以转化为base64
- 大小
- 缓存:针对静态资源(图片、css,js)
- 更新问题件如何避免缓存:添加时间戳 xxx.js?t=11234366345
-
SSR
- 服务器端渲染,首页采用服务器端渲染较为合适,有利于seo优化!
-
服务器压缩:
- vue.config.js中配置 devServer:{ compress:true}
-
…
-
-
UEO(用户使用产品过程中的主观感受)
- 界面友好性
- 操作便捷性
- 增加用户粘性
- …
-
SEO(让页面对搜索引擎更友好)
- 语义化标签
- 关键字分布
- 热搜(原创)
- 友情链接
- …
-
安全性优化
- 加密解密
函数的节流和去抖
函数的节流
- 概念:所谓函数的截流,就是频繁去触发一个事件的时候,会一直调用这个事件处理函数,会造成性能问题,因此需要节流一波!
- 比如表单的input事件,touch事件等等!
- 作用:就是在函数内部定义一个定时器,在定时器的设置的时间段内,保证这个时间段只调用一次函数,达到节流的效果!
- 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数
一个简单的节流函数
执行思路:
- 01:第一次设置的改变值为true,也就是第一次的改变值标志为true,可以打印
- 02:当你flag为真的时候,就是打印count,并且count打印出来,并且立马把flag设置为false
- 03:定时器2秒后,才把flag恢复为true,也就是2秒后,才能再一次触发这个表单值改变事件的打印!
//需求:表单的值发送改变的时候,就计算它触发的次数,count++,并且打印出count
var ipt = document.querySelector("#ipt");
var count = 0; //表单的触发次数
var flag = true; //表单值发生改变的时候,count++,并且打印count
ipt.oninput = function () {
if (flag) {
count++;
console.log(count);
flag = false;
setTimeout(() => {
flag = true;
}, 2000);
}
}
需求:鼠标滚动的时候,每隔两秒,打印一次
执行思路:
- 01:第一次设置的滚动为true,也就是第一次的滚动标志为true,可以滚动打印
- 02:当你flag为真的时候,就是打印1,并且立马把flag设置为false
- 03:定时器2秒后,才把flag恢复为true,也就是2秒后,才能再一次触发这个滚动事件的打印!
//需求:鼠标滚动的时候,每间隔两秒,打印一次1
var flag = true; //第一次标志符为真,第一次的滚动的时候,可以打印
document.body.onscroll = function () {
//当我们第一次滚动的时候,立马打印 1 还有立马把flag设置为false
if (flag) {
console.log(1);
flag = false;
//等待定时器2秒后 执行完毕后,把flag重新设置为true
setTimeout(() => {
flag = true
}, 2000);
}
}
函数的防抖
- 概念:所谓函数的防抖,在事件触发n秒之后在执行回调函数,假如在触发这个事件,那么时间会重新被计算!
- 就是在函数内部开启的定时器,只不过的是最初需要先清除这个定时器!
- 弊端:就是这样的方式,在定时器的事件内触发事件,不会触发定时器内部的执行输出,会造成一幅卡顿的假象!
执行思路:
- 在表单事件触发的时候,先清理掉上一个定时器,假如在定时器这个时间段内一直触发这个事件
- 那么等等事件触发500毫秒后,我们才能输出count的打印值!
var count = 0;
var t = null;
document.querySelector("#ipt").oninput = function () {
clearInterval(t);
t = setTimeout(function () {
count++;
console.log(count);
}, 500)
}
函数防抖和截流的区别
- 函数的防抖:
就是在特定时间内可以触发多次,即使上一次的操作还未执行完毕(时间未到),直接清除掉后(清除定时器),然后在重新当前这一次的时间! - 函数的截流:
就是在特定时间内只能触发一次,因为触发了这一次后,直接把标志符设置为false了,只能等待定时器的时间执行完后,把标志符重新设置为true,踩在继续触发事件!
重绘和重排
重绘 Repaint
- 概念:所谓的重绘就是重新绘制图层,至于绘制是什么?绘制就是一个元素外观发生改变的时候,所触发的浏览器行为;
例如:表单中的outline,背景色等属性发生变化的时候,浏览器会根据这些新属性重新绘制图层,使元素呈现新的外观!
注意点:重绘不一定会带来重新布局,所以并不一定会触发重排! - 注意点:重绘的基本单位是图层,如果图层中的某个元素需要重绘,那么会触发整个图层的重新绘制!
- 触发重绘的属性有:
* color * background * outline-color
* border-style * background-image * outline
* border-radius * background-position * outline-style
* visibility * background-repeat * outline-width
* text-decoration * background-size * box-shadow
重排(Reflow 回流)
- 概念:渲染对象在创建完成并添加到渲染树是,并不包含位置和大小信息。计算这些值的过程称之为重排
- 注意点:重绘不一定会触发重排,比如你鼠标滑过某个元素,这个元素背景色发生变化,一定触发重绘,但是不会触发重排! 这是因为布局没有发生变化!
- 注意点2:重排一定会触发重绘!比如改变了一个元素的位置,触发重排,也一定会触发重绘! 因为布局发生变化!
- 触发重排的属性
- 盒子模型相关属性会触发重布局 定位属性及浮动也会触发重布局: 改变节点内部文字结构也会触发重布局:
* width * top * text-align
* height * bottom * overflow-y
* padding * left * font-weight
* margin * right * overflow
* display * position * font-family
* border-width * float * line-height
* border * clear * vertival-align
* min-height * white-space
重绘和重排的区别
通俗而言:外观改变的叫做重绘,位置发生变化为重排!
- 两者的影响力:
- 重排的更加影响浏览器的性能,因为这是改变的结果,不仅仅触发重排,还触发了重绘!
- 常见的重排:
- 1:当你增加、删除、修改 DOM 结点时,会导致 Reflow , Repaint。
- 2:当你移动 DOM 的位置
- 3:当你修改 CSS 样式的时候
- 4: 当你 Resize 窗口的时候(移动端没有这个问题,因为移动端的缩放没有影响布局视口)
- 5:当你修改网页的默认字体时。
- 6:获取某些属性时(width,height…)
优化方案
1.元素位置移动变换时尽量使用CSS3的transform来代替对top left等的操作
变换(transform)和透明度(opacity)的改变仅仅影响图层的组合
尽量使用transform,这个会减少重绘和重排的次数!
2.将多次改变样式属性的操作合并成一次操作
不要一条一条地修改DOM的样式,预先定义好class,然后修改DOM的className