来自有凡分享的前端性能优化
性能优化可以准确地分为:网络方面、DOM操作及渲染方面、数据方面。
网络方面
web应用,总是会有一部分的时间浪费在网络连接和资源下载方面。往往建立一次网络连接是需要时间成本的。而且浏览器同一时间所发送的网络请求数是有限的。
减少http请求:
- 合并js文件;
- 合并css文件;
- 雪碧图的使用(css sprite);
- 使用base64表示简单的图片;
减小资源体积:
- gzip压缩,将 html 中重复的部分进行一个打包,多次复用的过程;
- js混淆,简单的压缩(将空白字符删除)、丑化(丑化的方法,就是将一些变量缩小)、或者可以使用php对js进行混淆加密;
- css压缩;
- 图片压缩,使用png等图片格式,减少矢量图、高清图等的使用;
缓存:
- DNS缓存;
- CDN部署与缓存;
- http缓存;
移动端优化:
- 使用长cache,即设置较长的缓存时间,减少重定向;
- 首屏优化,保证首屏加载数据小于14kb;
- 不滥用web字体;
渲染和DOM操作方面
在网页初步加载时,获取到HTML文件之后,最初的工作是构建DOM和构建CSSOM两个树,之后将他们合并形成渲染树,最后对其进行打印。我们可以通过图片来看一下,简单的过程:
优化网页渲染:
css的文件放在头部;
保证解析DOM的同时,解析css文件。因为,CSS(外链或内联)会阻塞整个DOM的渲染,然而DOM解析会正常进行,所以将css文件放在头部进行解析,可以加快网页的构建速度
js文件放在尾部或者异步;
js(外链或内联)会阻塞后续DOM的解析,后续DOM的渲染也将被阻塞,而且一旦js中遇到DOM元素的操作,很可能会影响
尽量避免內联样式;
可以有效的减少html的体积,一般考虑内联样式的时候,往往是样式本身体积比较小,往往加载网络资源的时间会大于它的时候
DOM操作优化:
避免在document上直接进行频繁的DOM操作,使用classname代替大量的内联样式修改,对于复杂的UI元素,设置position为absolute或fixed;
希望 减少回流和重绘,进行一次DOM操作的代价是非常之大的
尽量使用css动画;
css动画本身比较简单,而且相较于js的复杂动画,浏览器本身对其进行了优化
使用requestAnimationFrame代替setInterval操作;
setInterval定时器会有一定的延时,对于变动性高的动画来说,会出现卡顿现象。而requestAnimationFrame正好解决的整个问题
适当使用canvas;
尽量减少css表达式的使用;
例子:left: expression(document.body.offsetWidth - 180”px”),css表达式频繁触发的特性,会拖累网页的性能,出现卡顿
使用事件代理;
往往对于具备冒泡性质的事件来说,使用事件代理不失为一种好的方法。举个例子:一段列表都需要设定点击事件,这时如果你给列表中的每一项设定监听,往往会导致整体的性能下降,但是如果你给整个列表设置一个事件,然后通过点击定位目标来触发相应的操作,往往性能就会得到改善
操作细节注意:
- 避免图片或者iframe使用空src;
- 在css属性为0时,去掉单位;
- 禁止图像缩放;
- 正确的css前缀的使用;
- 移除空的css规则;
- 对于css中可继承的属性,如font-size,尽量使用继承,少一点设置;
- 缩短css选择器,多使用伪元素等帮助定位;
移动端优化:
长列表滚动优化;
IOS尽量使用局部滚动,android尽量使用全局滚动。同时,需要给body添加上-webkit-overflow-scrolling: touch来优化移动段的滚动
函数防抖和函数节流;
函数防抖,当调用动作过n毫秒后,才会执行该动作,若在这n毫秒内又调用此动作则将重新计算执行时间;
函数节流,预先设定一个执行周期,当调用动作的时刻大于等于执行周期则执行该动作,然后进入下一个新周期使用touchstart、touchend代替click;
click在移动端会有300ms延时,这应该是一个常识呗
HTML的viewport设置;
可以防止页面的缩放,来优化性能
开启GPU渲染加速;
数据方面
数据,也可以说是前端优化方面比较重要的一块内容。页面与用户的交互响应,往往伴随着数据交互,处理,以及ajax的异步请求等内容。
图片加载处理:
图片预加载;
预加载的寓意就是提前加载内容。而图片的预加载往往会被用在图片资源比较大,即时加载时会导致很长的等待过程时,才会被使用的。常见场景:图片漫画展示时。往往会预加载一张到两张的图片。
图片懒加载;
常见的图片懒加载的方式就是:在最初给图片的src设置一个比较简单的图片,然后将图片的真实地址设置给自定义的属性,做一个占位,然后给图片设置监听事件,一旦图片到达视口范围,从图片的自定义属性中获取出真是地址,然后赋值给src,让其进行加载。
首屏加载时进度条的显示;
异步请求的优化:
- 使用正常的json数据格式进行交互;
部分常用数据的缓存;
可以将一些用户的基本信息等常用的信息做一个缓存,这样可以保证ajax请求的减少。同时,HTML5新增的storage的内容,也不用怕cookie暴露,引起的信息泄漏问题。
数据埋点和统计;