前端性能优化经常使用总结(转)

转自:https://www.jianshu.com/p/fe32ef31deedjavascript

前言php

对于前端的性能话题,历来都没有断绝过。由于这个东西没有最好,只有更好。并且每每也是业务的繁杂程度去决定优化程度的。做为一个前端开发者,性能是咱们关注的指标。它直接影响着咱们的用户,同时也影响着产品自己。前端发展以来,优化方式,琳琅满目,有雅虎军规等。这些内容复杂繁多,每每容易被人遗忘。所以,本篇对于这些经常使用的优化方式进行总结,或许,并不全面,见谅。若是你喜欢个人文章,欢迎评论,欢迎Star~。css

原文连接:https://juejin.im/post/59e1bbc9f265da430f311fb1html

正文

前端优化层出不穷,移动端大行其道的如今,咱们能够说优化好移动端,PC端也将会更好。因此,咱们能够综合如下图片进行一些分析,如图:前端

 
优化

图中已经对前端性能作了一些归纳。但其实,我以为咱们能够将这个归纳更加精准,扼要,丰富。因此,接下来我会从三个方面就前端性能进行总结:网络方面、DOM操做及渲染方面、数据方面。java

网络方面

web应用,老是会有一部分的时间浪费在网络链接和资源下载方面。每每创建一次网络链接是须要时间成本的。并且浏览器同一时间所发送的网络请求数是有限的。因此,这个层面的优化能够从「减小请求数目」开始:android

  1. 减小http请求:在YUI35规则中也有提到,主要是优化js、css和图片资源三个方面,由于html是没有办法避免的。所以,咱们能够作一下的几项操做:webpack

    • 合并js文件
    • 合并css文件
    • 雪碧图的使用(css sprite)
    • 使用base64表示简单的图片

    上述四个方法,前面二者咱们可使用webpack之类的打包工具进行打包;雪碧图的话,也有专门的制做工具;图片的编码是使用base64的,因此,对于一些简单的图片,例如空白图等,可使用base64直接写入html中。ios

回到以前网络层面的问题,除了减小请求数量来加快网络加载速度,每每整个资源的体积也是,平时咱们会关注的方面。程序员

  1. 减少资源体积:能够经过如下几个方面进行实施:

    • gzip压缩
    • js混淆
    • css压缩
    • 图片压缩

    gzip压缩主要是针对html文件来讲的,它能够将html中重复的部分进行一个打包,屡次复用的过程。js的混淆能够有简单的压缩(将空白字符删除)、丑化(丑化的方法,就是将一些变量缩小)、或者可使用php对js进行混淆加密。css压缩,就是进行简单的压缩。图片的压缩,主要也是减少体积,在不影响观感的前提下,尽可能压缩图片,使用png等图片格式,减小矢量图、高清图等的使用。这样子的作法不只能够加快网页显示,也能减小流量的损耗。

除了以上两部分的操做以外,在网络层面咱们还须要作好缓存工做。真正的性能优化来讲,缓存是效率最高的一种,每每缩短的加载时间也是最大的。

  1. 缓存:能够经过如下几个方面来描述:

    • DNS缓存
    • CDN部署与缓存
    • http缓存

    因为浏览器会在DNS解析步骤中消耗必定的时间,因此,对于一些高访问量网站来讲,作好DNS的缓存工做,就会必定程度上提高网站效率。CDN缓存,CDN做为静态资源文件的分发网络,自己就已经提高了,网站静态资源的获取速度,加快网站的加载速度,同时也给静态资源作好缓存工做,有效的利用已缓存的静态资源,加快获取速度。http缓存,也是给资源设定缓存时间,防止在有效的缓存时间内对资源进行重复的下载,从而提高总体网页的加载速度。

其实,网络层面的优化还有不少,特别是针对于移动端页面来讲。众所周知,移动端对于网络的敏感度更加的高,除了目前的4G和WIFI以外,其余的移动端网络至关于弱网环境,在这种环境下,资源的缓存利用是至关重要的。并且,减小http的请求次数,也是相当重要的,移动端弱网环境下,对于http请求的时间也会增长。因此,咱们能够看一下咱们在移动端网络方面能够作的优化:

  1. 移动端优化:使用如下几种方式来加快移动端网络方面的优化:

    • 使用长cache,减小重定向
    • 首屏优化,保证首屏加载数据小于14kb
    • 不滥用web字体

    「使用长cache」,可使得移动端的部分资源设定长期缓存,这样能够保证资源不用向服务器发送请求,来比较资源是否更新,从而避免304的状况。304重定向,在PC端或许并不会影响网页的加载速度,可是,在移动端网络不稳定的前提下,多一次请求,就多了一部分加载时间。「首屏优化」,对于移动端来讲是相当重要的。2s时间是用户的最佳体验,一旦超出这个时间,将会致使用户的流失。因此,针对移动端的网络状况,不可能在这么短期内加载完成全部的网页资源,因此咱们必须保证首屏中的内容被优先显示出来,并且基于TCP的慢启动和拥塞控制,第一个14kb的数据是很是重要的,因此须要保证首部加载数据可以小于14kb。「不滥用web字体」,web字体的好处就是,能够代替某些图片资源,可是,在移动端过多的web字体的使用,会致使页面资源加载的繁重,因此,慎用web字体

渲染和DOM操做方面

首先,简单的聊一下优化渲染的重要性。在网页初步加载时,获取到HTML文件以后,最初的工做是构建DOM和构建CSSOM两个树,以后将他们合并造成渲染树,最后对其进行打印。咱们能够经过图片来看一下,简单的过程:

 
DOM渲染

这里整个过程拉出来写,具体能够再写一篇文章,恕我偷下懒,推荐一篇比较好的文章给你们吧。浏览器渲染过程与性能优化

继续咱们的话题,咱们能够如何去缩短这个过程呢?能够从如下几个操做进行优化。

  1. 优化网页渲染

    • css的文件放在头部,js文件放在尾部或者异步
    • 尽可能避免內联样式

    css文件放在「头部加载」,能够保证解析DOM的同时,解析css文件。由于,CSS(外链或内联)会阻塞整个DOM的渲染,然而DOM解析会正常进行,因此将css文件放在头部进行解析,能够加快网页的构建速度。假设将其放在尾部,那时DOM树几乎构建,这时就得等到CSSOM树构建完成,才可以继续下面的步骤。「js放在尾部」:js文件不一样,将js文件放在尾部或者异步加载的缘由是JS(外链或内联)会阻塞后续DOM的解析,后续DOM的渲染也将被阻塞,并且一旦js中遇到DOM元素的操做,极可能会影响。这方面能够推荐一篇文章——异步脚本载入提升页面性能。「避免使用内联样式」,能够有效的减小html的体积,通常考虑内联样式的时候,每每是样式自己体积比较小,每每加载网络资源的时间会大于它的时候。

除了页面渲染层面的优化,固然最重要的就是DOM操做方面的优化,这部分的优化应该是最多的,并且也是平时开发能够注意的地方。若是开发前期明白这些原理,同时付诸实践的话,就能够在后期的性能完善上面少下不少功夫。那么,接下来咱们能够来看一下具体的操做:

  1. DOM操做优化

    • 避免在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进行操做。「使用事件代理」:每每对于具有冒泡性质的事件来讲,使用事件代理不失为一种好的方法。举个例子:一段列表都须要设定点击事件,这时若是你给列表中的每一项设定监听,每每会致使总体的性能降低,可是若是你给整个列表设置一个事件,而后经过点击定位目标来触发相应的操做,每每性能就会获得改善。

DOM操做的优化,还有不少,固然也包括移动端的。这个会在以后移动端优化部分被说起,此处先卖个关子。上面咱们概述了开始渲染的时候和DOM操做的时候的一些注意事项。接下来要讲的是一些小细节的注意,这些细节可能对于页面影响不大,可是一旦堆积多了,性能也会有所影响。

  1. 操做细节注意

    • 避免图片或者frame使用空src
    • 在css属性为0时,去掉单位
    • 禁止图像缩放
    • 正确的css前缀的使用
    • 移除空的css规则
    • 对于css中可继承的属性,如font-size,尽可能使用继承,少一点设置
    • 缩短css选择器,多使用伪元素等帮助定位

    上述的一些操做细节,是平时在开发中被要求的,更能够理解为开发规范。(基本操做,坐下^_^)

列举完基本操做以后,咱们再来聊一下移动端在DOM操做方面的一些优化。

  1. 移动端优化

    • 长列表滚动优化
    • 函数防抖和函数节流
    • 使用touchstart、touchend代替click
    • HTML的viewport设置
    • 开启GPU渲染加速

    首先,长列表滚动问题,是移动端须要面对的,IOS尽可能使用局部滚动,android尽可能使用全局滚动。同时,须要给body添加上-webkit-overflow-scrolling: touch来优化移动段的滚动。若是有兴趣的同窗,能够去了解一下ios和android滚动操做上的区别以及优化。「防抖和节流」,设计到滚动等会被频繁触发的DOM事件,须要作好防抖和节流的工做。它们都是为了限制函数的执行频次,以优化函数触发频率太高致使的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。

    介绍:函数防抖,当调用动做过n毫秒后,才会执行该动做,若在这n毫秒内又调用此动做则将从新计算执行时间;函数节流,预先设定一个执行周期,当调用动做的时刻大于等于执行周期则执行该动做,而后进入下一个新周期。

    「touchstart、touchend代替click」,也是移动端比较经常使用的操做。click在移动端会有300ms延时,这应该是一个常识呗。(不知道的小伙伴该收藏一下呦)。这种方法会影响用户的体验。因此作优化时,最简单的方法就是使用touchstart或者touchend代替click。由于它们事件执行顺序是touchstart->touchmove->touchend->click。或者,使用fastclick或者zepto的tap事件代替click事件。「HTML的viewport设置」,能够防止页面的缩放,来优化性能。「开启GPU渲染加速」,小伙伴们必定听过CPU吧,可是这里的GPU不能和CPU混为一谈呦。GPU的全名是Graphics Processing Unit,是一种硬件加速方式。通常的css渲染,浏览器的渲染引擎都不会使用到它。可是,在3D渲染时,计算量较大,繁重,浏览器会开启显卡的硬件加速来帮助完成这些操做。因此,咱们这里可使用css中的translateZ设定,来欺骗浏览器,让其帮忙开启GPU加速,加快渲染进程。

DOM部分的优化,更多的是习惯。须要本身强制要求本身在开发过程当中去注意这些规范。因此,这部分的内容能够多关注一下,才可以慢慢了解。同时,本人对于上述几点的描述是归纳性的。并无对其进行详细的展开。所以,也要求你去细细的查阅Google呦。

数据方面

数据,也能够说是前端优化方面比较重要的一块内容。页面与用户的交互响应,每每伴随着数据交互,处理,以及ajax的异步请求等内容。因此,咱们也能够来聊聊这一块的知识。首先是对于图片数据的处理:

  1. 图片加载处理

    • 图片预加载
    • 图片懒加载
    • 首屏加载时进度条的显示

    「图片预加载」,预加载的寓意就是提早加载内容。而图片的预加载每每会被用在图片资源比较大,即时加载时会致使很长的等待过程时,才会被使用的。常见场景:图片漫画展现时。每每会预加载一张到两张的图片。「图片懒加载」,懒加载或许你是第一次据说,可是,这种方式在开发中会被常用。首先,咱们须要明白一个道理:每每只有看到的资源是必须的,其余资源是能够随着用户的滚动,随即显示的。因此,特别是对于图片资源特别多的网站来讲,作好图片的懒加载是能够大大提高网页的载入速度的。

    常见的图片懒加载的方式就是:在最初给图片的src设置一个比较简单的图片,而后将图片的真实地址设置给自定义的属性,作一个占位,而后给图片设置监听事件,一旦图片到达视口范围,从图片的自定义属性中获取出真是地址,而后赋值给src,让其进行加载。

    「首屏进度条的显示」:每每对于首屏优化后的数据量并不满意的话,同时也不能进一步缩短首屏包的长度了,就可使用进度条的方式,来提醒用户进行等待。

讲完了图片这一块数据资源的处理,每每咱们须要去优化一下异步请求这一部分的内容。由于,异步的数据获取也是前端不可分割的。这一部分咱们也能够作必定的处理:

  1. 异步请求的优化

    • 使用正常的json数据格式进行交互
    • 部分经常使用数据的缓存
    • 数据埋点和统计

    「JSON交互」,JSON的数据格式轻巧,结构简单,每每能够大大优化先后端的数据通讯。「经常使用数据的缓存」,能够将一些用户的基本信息等经常使用的信息作一个缓存,这样能够保证ajax请求的减小。同时,HTML5新增的storage的内容,也不用怕cookie暴露,引发的信息泄漏问题。「数据埋点和统计」,对于资深的程序员来讲,比较了解。并且目前的大部分公司也会作这方面的处理。有心的小伙伴能够自行查阅。

最后,还有就是大量数据的运算。对于javascript语言来讲,自己的单线程就限制了它并不能计算大量的数据,每每会形成页面的卡顿。而可能业务中有些复杂的UI须要去运行大量的运算,因此,webWorker的使用是相当重要的。或许,前端标准普及的落后,会致使你们对于这些新生事物的短暂缺失吧。

总结

本篇文章就前端性能这个话题作了一个总结。或许,并不全面,可是都是一些平时开发中会被常常用到的知识。但愿有心者可以去亲身的尝试一下这些方面的优化。本篇的概述了一下几个知识点:

  • 网络层面的优化
  • 数据层面的优化
  • DOM操做与渲染层面的优化
相关文章
相关标签/搜索