本文会从三大部分来总结前端性能优化方面
一:数据方面
数据,也可以说是前端优化方面比较重要的一块内容。页面与用户的交互响应,往往伴随着数据交互,处理,以及ajax的异步请求等内容。所以,我们也可以来聊聊这一块的知识。首先是对于图片数据的处理:
1 图片加载处理:1
2
3图片预加载
图片懒加载
首屏加载时进度条的显示
1)图片预加载」,预加载的寓意就是提前加载内容。而图片的预加载往往会被用在图片资源比较大,即时加载时会导致很长的等待过程时,才会被使用的。常见场景:图片漫画展示时。往往会预加载一张到两张的图片。
2)「图片懒加载」,懒加载或许你是第一次听说,但是,这种方式在开发中会被经常使用。首先,我们需要明白一个道理:往往只有看到的资源是必须的,其他资源是可以随着用户的滚动,随即显示的。所以,特别是对于图片资源特别多的网站来说,做好图片的懒加载是可以大大提升网页的载入速度的。
详细可见本博客的懒加载和预加载代码示例部分 skr~
3)「首屏进度条的显示」:往往对于首屏优化后的数据量并不满意的话,同时也不能进一步缩短首屏包的长度了,就可以使用进度条的方式,来提醒用户进行等待。
2 异步请求的优化:1
2
3使用正常的json数据格式进行交互
部分常用数据的缓存
数据埋点和统计
1)「JSON交互」,JSON的数据格式轻巧,结构简单,往往可以大大优化前后端的数据通信。
2)「常用数据的缓存」,可以将一些用户的基本信息等常用的信息做一个缓存,这样可以保证ajax请求的减少。同时,HTML5新增的storage的内容,也不用怕cookie暴露,引起的信息泄漏问题。
3)「数据埋点和统计」,对于资深的程序员来说,比较了解。而且目前的大部分公司也会做这方面的处理。有心的小伙伴可以自行查阅。
3 javascript多线程处理方式
最后,还有就是大量数据的运算。对于javascript语言来说,本身的单线程就限制了它并不能计算大量的数据,往往会造成页面的卡顿。而可能业务中有些复杂的UI需要去运行大量的运算,所以,webWorker的使用是至关重要的。
二:网络方面
web应用,总是会有一部分的时间浪费在网络连接和资源下载方面。往往建立一次网络连接是需要时间成本的。而且浏览器同一时间所发送的网络请求数是有限的。
1 减少http请求
在YUI35规则中也有提到,主要是优化js、css和图片资源三个方面,因为html是没有办法避免的。因此,我们可以做一下的几项操作:1
2
3
4合并js文件
合并css文件
雪碧图的使用(css sprite)
使用base64表示简单的图片
上述四个方法,前面两者我们可以使用webpack之类的打包工具进行打包;雪碧图的话,也有专门的制作工具;图片的编码是使用base64的,所以,对于一些简单的图片,例如空白图等,可以使用base64直接写入html中。
2 减小资源体积1
2
3
4gzip压缩
js混淆
css压缩
图片压缩
1)gzip压缩主要是针对html文件来说的,它可以将html中重复的部分进行一个打包,多次复用的过程。
2)js的混淆可以有简单的压缩(将空白字符删除)、丑化(丑化的方法,就是将一些变量缩小)、或者可以使用php对js进行混淆加密。
3)css压缩,就是进行简单的压缩。
4)图片的压缩,主要也是减小体积,在不影响观感的前提下,尽量压缩图片,使用png等图片格式,减少矢量图、高清图等的使用。这样子的做法不仅可以加快网页显示,也能减少流量的损耗。
3 缓存1
2
3DNS缓存
CDN部署与缓存
http缓存
由于浏览器会在DNS解析步骤中消耗一定的时间,所以,对于一些高访问量网站来说,做好DNS的缓存工作,就会一定程度上提升网站效率。CDN缓存,CDN作为静态资源文件的分发网络,本身就已经提升了,网站静态资源的获取速度,加快网站的加载速度,同时也给静态资源做好缓存工作,有效的利用已缓存的静态资源,加快获取速度。http缓存,也是给资源设定缓存时间,防止在有效的缓存时间内对资源进行重复的下载,从而提升整体网页的加载速度。
4 移动端优化1
2
3使用长cache,减少重定向
首屏优化,保证首屏加载数据小于14kb
不滥用web字体
「使用长cache」,可以使得移动端的部分资源设定长期缓存,这样可以保证资源不用向服务器发送请求,来比较资源是否更新,从而避免304的情况。304重定向,在PC端或许并不会影响网页的加载速度,但是,在移动端网络不稳定的前提下,多一次请求,就多了一部分加载时间。「首屏优化」,对于移动端来说是至关重要的。2s时间是用户的最佳体验,一旦超出这个时间,将会导致用户的流失。所以,针对移动端的网络情况,不可能在这么短时间内加载完成所有的网页资源,所以我们必须保证首屏中的内容被优先显示出来,而且基于TCP的慢启动和拥塞控制,第一个14kb的数据是非常重要的,所以需要保证首部加载数据能够小于14kb。「不滥用web字体」,web字体的好处就是,可以代替某些图片资源,但是,在移动端过多的web字体的使用,会导致页面资源加载的繁重,所以,慎用web字体
三 渲染和DOM操作方面
1 优化网页渲染:
1 | css的文件放在头部,js文件放在尾部或者异步 |
1)css文件放在「头部加载」,可以保证解析DOM的同时,解析css文件。因为,CSS(外链或内联)会阻塞整个DOM的渲染,然而DOM解析会正常进行,所以将css文件放在头部进行解析,可以加快网页的构建速度。假设将其放在尾部,那时DOM树几乎构建,这时就得等到CSSOM树构建完成,才能够继续下面的步骤。
2)「js放在尾部」:js文件不同,将js文件放在尾部或者异步加载的原因是JS(外链或内联)会阻塞后续DOM的解析,后续DOM的渲染也将被阻塞,而且一旦js中遇到DOM元素的操作,很可能会影响。
3)「避免使用内联样式」,可以有效的减少html的体积,一般考虑内联样式的时候,往往是样式本身体积比较小,往往加载网络资源的时间会大于它的时候。
2 DOM操作优化:1
2
3
4
5
6
7
8避免在document上直接进行频繁的DOM操作
使用classname代替大量的内联样式修改
对于复杂的UI元素,设置position为absolute或fixed
尽量使用css动画
使用requestAnimationFrame代替setInterval操作
适当使用canvas
尽量减少css表达式的使用
使用事件代理
前面三个操作,其实都是希望『减少回流和重绘』。其实,进行一次DOM操作的代价是非常之大的,以前可以通过网页操作是否卡顿来进行判断,但是,现代浏览器的进步已经大大减少了这方面的影响。但是,我们还是需要清楚,如何去减少回流和重绘的问题。因为这里不想细说这方面的知识,想要了解的话,可以看这篇文章——回流与重绘:CSS性能让JavaScript变慢?。这可是张鑫旭大大的一篇文章呦(^.^)。「尽量使用css动画」,是因为本身css动画比较简单,而且相较于js的复杂动画,浏览器本身对其进行了优化,使用上面不会出现卡顿等问题。「使用requestAnimationFrame代替setInterval操作」,相信大家都有所耳闻,setInterval定时器会有一定的延时,对于变动性高的动画来说,会出现卡顿现象。而requestAnimationFrame正好解决的整个问题。「适当使用canvas」,不得不说canvas是前端的一个进步,出现了它之后,前端界面的复杂性也随之提升了。一些难以完成的动画,都可以使用canvas进行辅助完成。但是,canvas使用频繁的话,会加重浏览器渲染的压力,同时导致性能的下降。所以,适当时候使用canvas是一个不错的建议。「尽量减少css表达式的使用」,这个在YUI规则中也被提到过,往往css的表达式在设计之初都是美好的,但在使用过程中,由于其频繁触发的特性,会拖累网页的性能,出现卡顿。因此在使用过程中尽量减少css表达式的使用,可以改换成js进行操作。「使用事件代理」:往往对于具备冒泡性质的事件来说,使用事件代理不失为一种好的方法。举个例子:一段列表都需要设定点击事件,这时如果你给列表中的每一项设定监听,往往会导致整体的性能下降,但是如果你给整个列表设置一个事件,然后通过点击定位目标来触发相应的操作,往往性能就会得到改善。
3 操作细节注意:1
2
3
4
5
6
7避免图片或者frame使用空src
在css属性为0时,去掉单位
禁止图像缩放
正确的css前缀的使用
移除空的css规则
对于css中可继承的属性,如font-size,尽量使用继承,少一点设置
缩短css选择器,多使用伪元素等帮助定位
4 移动端优化:1
2
3
4
5长列表滚动优化
函数防抖和函数节流
使用touchstart、touchend代替click
HTML的viewport设置
开启GPU渲染加速
1)长列表滚动问题,是移动端需要面对的,IOS尽量使用局部滚动,android尽量使用全局滚动。同时,需要给body添加上-webkit-overflow-scrolling: touch来优化移动段的滚动。如果有兴趣的同学,可以去了解一下ios和android滚动操作上的区别以及优化。
2)「防抖和节流」,设计到滚动等会被频繁触发的DOM事件,需要做好防抖和节流的工作。它们都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。
3)「touchstart、touchend代替click」,也是移动端比较常用的操作。click在移动端会有300ms延时,这应该是一个常识呗。(不知道的小伙伴该收藏一下呦)。这种方法会影响用户的体验。所以做优化时,最简单的方法就是使用touchstart或者touchend代替click。因为它们事件执行顺序是touchstart->touchmove->touchend->click。或者,使用fastclick或者zepto的tap事件代替click事件。
4)「HTML的viewport设置」,可以防止页面的缩放,来优化性能。
5)「开启GPU渲染加速」,小伙伴们一定听过CPU吧,但是这里的GPU不能和CPU混为一谈呦。GPU的全名是Graphics Processing Unit,是一种硬件加速方式。一般的css渲染,浏览器的渲染引擎都不会使用到它。但是,在3D渲染时,计算量较大,繁重,浏览器会开启显卡的硬件加速来帮助完成这些操作。所以,我们这里可以使用css中的translateZ设定,来欺骗浏览器,让其帮忙开启GPU加速,加快渲染进程。
参考资料:前端性能优化常用总结