为什么要优化性能

  • 对产品、成果重要

    • 节约流量
    • 用户体验提高->转化效率提高
  • 个人成长

是一个前端可深入的方向

怎么去做优化性能

前端越来越复杂,所以在这个方向上需要有结构化知识体系来协助进行全面的思考。

一道面试题:输入URL到看到页面的过程。
这道面试题基本上是让你说一下当前B/S架构的整体流程,而性能优化,就是从整体流程中寻找优化点。所以,我们的优化首先要明确,不是前端的问题,是整体流程的问题。

而这套整体流程用简单的话来说就是 客户端->请求->服务器->响应->客户端渲染
由此可见,理论上优化要从两个方向考虑:
更快的网络传输
更快的数据处理(代码执行)

更快的网络传输

要让请求的整体流程更快,也是两点
传输时间更短
请求次数更少

CDN

缩短物理距离缩短传输时间
内容分发网路(CDN)大家都知道,白话就是全球各地都有服务器,请求时由最近的服务器响应。
他的核心能力其实是:全局负载均衡缓存系统

  • 全局负载均衡:请求时会请求到负载均衡服务器,该服务器的智能调度会去选择最佳节点响应(根据地理位置、网络运营商、负载等)
  • 缓存系统:去主服务器(存放原始数据的服务器)获取数据缓存到当前服务器

    压缩

    减少传输体积来缩短传输时间

  • 数据压缩

对服务器上的资源进行压缩,工具有 gzip(常用) 、 br 等

  • 代码的压缩

空格、长变量名、注释等(打包工具的生产版本、tree shaking)

  • 静态资源压缩

svg、字体、使用webp、缩小尺寸及分辨率

  • 头与报文

减少不必要的头、减少cookie数据量

资源合并

减少请求次数(缺陷是不利于缓存,一个图标变化全部要变)
雪碧图,svg-splict-loader

域名分片(没实际用过)

RFC2616早期标准2个, chrome 6个,safari 8个,通过多个域名来打破这个限制,短时间大量请求
利用多个二级域名同时请求来解决并发量问题
从后端方向,每个域名对应的服务器放不同的资源

合理缓存

减少请求次数

  • HTTP协议中:

image.png

  • 强缓存 :直接缓存,不用请求服务器。 两个都加上,以防止浏览器不认识其中一个

cache-control: max-age=600 // 600ms内不变
expires: // 一个时间点,时间点之前不变

  • 协商缓存 :需要通信,但大部分情况下无数据交互。

Last-Modified/If-Modified-Since : Mon, 24 Dec 2018 09:49:49 GMT 服务端把它返回回去,然后客户端下次请求时带上,服务端判断,确实是这个时间,而且没过期,就返回304
Etag/If-None-Match: 哈希值 服务端根据内容计算出来返回给客户端,然后客户端下次请求时带上,服务端判断,确实还是这个哈希,资源没变化,就返回304

  • Local Storage
  • IndexedDB

用于在客户端存储大量的结构化数据,相当于浏览器内可用的事务型数据库系统,个人没有在生产环境中用过。但在某次分享中得知阿里大佬在大数据可视化中合理的使用了这个东西。
详情可见:IndexedDB

协议升级

HTTP1.1升级到HTTP2
HTTP2更快的关键点:

  • 头部压缩(专门的HPACK压缩算法)
  • 二进制帧传输(传输快、解析快)
  • 链路复用(1.1的服务器处理数据时,Tcp链路是空的,不断开等待返回。而2.0则会在链路空闲时使用该链路)


更快的数据处理

HTML层面

  • 减少DOM层级

    DOM层级越深会增加 CSS rule Tree 和 Dom Tree 匹配构造的性能

  • 多使用伪元素

    伪元素不属于DOM节点,可以减少js查找dom遍历

    善用CSS

    能使用CSS3就不要用JS,因为css3的动画是由GPU进程单独处理的,效率高且不影响js执行进程。

JS层面

  • 减少作用域的查找和闭包
  • 避免使用==
  • 善用webWorker处理计算密集型任务,避免卡死线程

其它

构建工具

我理解构建工具本质上是对 更快的网络传输 和 更快的数据处理做的做的自动化的优化。
而我们在这个方向上做性能优化,只是借助各种花式插件或配置项,做好合理分包、代码压缩、缓存等工作。
除此之外还有引申出来的让构建速度更快的优化这里就先不提

  • splitChunks合理分包

webpack4之后CommonsChunkPlugin被更新为splitChunks,可以通过它做合理分包按需引入。
同时还可以通过 webpack-bundle-analyzer 来查看打包结果,定位性能瓶颈。

  • externals引入CDN

  • optimize-css-assets-webpack-plugin压缩css,terser-webpack-plugin、UglifyJS压缩js

  • 懒加载预加载
  • ……

检测工具

  • 控制台devtools
  • ab压力测试端口+node —prof 启动会创建log日志 之后 使用 node —prof-process ./XXXX/log > xxx.txt 生成耗时日志
  • lightouse

SSR/SSG

当前都是SPA客户端渲染,问题:
白屏时间长、HTML中无内容,SEO不友好

服务端渲染SSR:
服务端渲染出首页并返回
首屏后就类似传统SPA,由js来执行

静态站点SSG
编译阶段直接生成全部HTML,切换路由返回对应HTML