前端性能优化方案

文件压缩

图片压缩能够显著的减少资源体积,明显提升页面的加载速度。

  1. 图片压缩
    项目使用webpack编译的可以使用image-webpack-loader插件,npm地址。
    如果项目中没有配置图片压缩,需要自己手动处理的,推荐png图片缩网站tinypng

  2. 合理选择图片存储格式
    下面介绍几种常用的图片格式:

  1. jpg,不支持透明,采用有损压缩方式处理图像
    这种压缩方式的图片并不会真实记录各像素点的数据,而是利用人眼的特性对数据进行处理,去掉会被人眼忽略的细节,使用附近的颜色通过渐变或其他形式进行填充。
  2. png,支持透明。采用无损压缩方式处理图像,这种压缩方式采用一些算法来真实记录各像素点的数据(比如记录一大块相同颜色的开始位置和结束位置)。
  3. gif,支持透明,可以用来做动图。一般来说项目中已经很少用到这种格式了,大部分动画都用css3来实现了。

综上:
jpg格式适合用来保存色彩层次比较丰富的图片。
png适合保存含颜色较少、具有大块颜色相近的区域或亮度差异十分明显的较简单的图片。
但是如果图片中存在透明部分,只能使用png来做。

  1. css压缩、js压缩混淆
    压缩会删除空格、删除注释、缩短变量以达到压缩体积的目的。
    对应webpack插件:
    css压缩:optimize-css-assets-webpack-pluginnpm地址需要配合cssnano
    js压缩:uglifyjs-webpack-pluginnpm地址

  2. gzip压缩
    使用gzip压缩后资源可以在以上压缩基础上再进行压缩,使体积更小。

压缩过程:
1、请求header中添加Accept-Encoding字段,说明自己可以接受的压缩方法;
2、服务端接选取Accept-Encoding中的一种对响应数据进行压缩并在响应的Content-Encoding字段中说明数据的压缩方式;

压缩方式:

  1. 构建时压缩
    在webpack编译时使用compression-webpack-plugin压缩npm地址
  2. 服务端压缩

合并文件

合并文件是为了减少http请求次数,浏览器对于同时发起的请求数量做了限制。

  1. 图片合并(雪碧图)
    多张图标合并到一张图表上再通过backgroud-size 和 background-position 属性控制显示。

  2. 小图片转base64。
    图片转成base64后体积会大1/3,所以在一般体积超过3k的图片才会这样做。

  3. 使用字体图标
    字体图标的害处除了能够减少http请求数量外还有:

  1. 放大不失真
  2. 可以通过css属性控制颜色、大小等效果
  3. 兼容性好,使用unicode方式可以兼容到ie6+。
    当然其本身也有一定的缺点:
  4. 字体图标只能单色或者css3渐变
  5. 开发和维护成,本更高
    不过综合考虑还是推荐字体图标。
  1. 图片懒加载
    懒加载技术目前已经被广泛应用,页面加载时图片显示占位图,当图片出现在屏幕上后再将src替换为真实图片地址。

合理利用缓存

浏览器缓存策略

浏览器里的缓存策略氛围强缓存和协商缓存。
强缓存:
Expires属性内容为GMT属性的字符串(Wed, 21 Oct 1900 07:28:00 GMT),兼容性较好但可能存在服务端时间与本地时间不一致的问题。

Cache-Control为HTTP/1.1标准内的属性,内容为毫秒的数字( max-age=60),同时存在Cache-Control和Expires时,会覆盖Expires。

协商缓存:
Last-Modified 和 If-Modified-Since
相应头中的Last-Modified属性中为GMT格式的字符串,当浏览器发起请求时,会把内容以If-Modified-Since属性返回给服务端。服务端根据属性判断,如果文件没有变化,返回304和空的响应体,浏览器会直接从缓存读取。如果If-Modified-Since的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和200。

ETag 和If-None-Match
相应头中的ETag中为当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成。浏览器在下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到request header里的If-None-Match里,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag是否一致,一致则304,否则200。

减少页面的重绘重排

当DOM变化影响了节点的几何属性,浏览器需要重新计算节点的几何属性,并且页面中其他节点的可能受影响,浏览器会重新排布,这个过程称之为重排。
当元素发生了外观上的改变时,浏览器会根据节点的新属性重新绘制,这个过程称为重绘。
重排必然会触发重绘,重绘不一定会伴随着重排。

其他重发重排的情况:

  1. 调整浏览器窗口大小;
  2. 除了更改元素的几何属性会触发重排,获取元素的几何属性也会触发重排。
    现代浏览器对于重排进行了优化,多次DOM操作会合并一次操作。但是获取属性浏览器会立即进行重绘以确保用户获取的是最新状态的属性

如何最小化重绘和重排:

  1. 通过classname或者cssText修改多个样式
  2. 通过fragment批量添加DOM
  3. 对于进行复杂操作的元素,可以先将元素设置为display:none;隐藏,修改完毕之后再显示出来。这样只会触发两次重排和重绘。
  4. 对于会引起多次重排的元素,可以设置定位为absolute或fixed,使其脱离文档流。

其他

  1. 合理缓存变量以减少查找原型链和作用域链的次数、减少属性访问的次数。
  2. 不要省略分号;
  3. 避免资源404,减少重定向的次数。
  4. 避免使用with、eval、Function。
  5. 不需要与服务端交互的数据不要存放到cookie里。
  6. webpack打包优化,按需加载。
  7. 合理提取公共代码,减少冗余部分。
  8. 函数节流,限制某一个方法的频繁触发。
  9. 合理利用事件代理。
  10. CND分发资源。

你可能感兴趣的:(前端性能优化方案)