# 从哪些方面入手,进行前端性能优化?

主要从CRP(关键渲染路径)为主线,进行分析可优化的点。

从url输入,到浏览器渲染出页面内容的关键环节,称为关键渲染路径

URI解析 ——> DNS解析 ——> TCP三次握手建立连接发送http请求 ——> 服务端处理和响应 ——> 浏览器解析和渲染 ——> TCP四次挥手断开连接

# 1. 减少请求

减少请求又可分为两方面:

  1. 减少请求数,方法:资源合并(js、css、雪碧图)、图片转base64等;
  2. 减少请求大小,方法:1. 资源压缩,例如开启gzip(一般是由apache、tomcat等web服务器开启);2. 减少传递不必要的字段,例如静态资源无需携带cookie,可以通过多域名实现(因为同域名才会自动携带cookie)(是否还有其它不携带cookie的方法?) 但二者有时是互斥的,比如说资源合并后,导致文件过大,此时还要考虑通过webpack等构建工具进行代码拆分、异步加载模块等操作;

# 2. 利用缓存

  1. 代码版本化
  2. 浏览器本地存储
  3. http缓存

# 3. 利用CDN

CDN全称Content Delivery Network,即内容分发网络,指通过互联网与各种缓存服务器(基于IDC)相连的网络系统。CDN是用来给网站加速的。用户请求CDN资源时,利用全局负载技术,将访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。
CDN的原理就是利用全局负载技术就近请求缓存服务器上的资源,减少网络耗时。

# 4. 利用SSR(server side render,服务器端渲染)

原理时,将数据在服务端插入到html节点中,然后再返回给浏览器,从而减少ajax等数据接口的请求数。比如php语言的smarty语法。目前Vue、React都有这个技术概念。

# 5. 懒加载

  1. 交互懒加载,例如,只请求、渲染首屏资源,下拉时再加载更多资源;默认加载很小的图,点击后才会加载高清图。
  2. 延迟懒加载

# 6. 代码层面(最主要减少dom操作)

首先明确,为什么 dom 操作很耗性能?

  1. 线程切换(渲染引擎线程、js引擎线程);
  2. 重排和重绘。

如何减少dom操作?

  1. 缓存dom查询,例如,for循环遍历所有li时,先定义长度变量,再循环;
  2. 合并dom插入,先拼接dom字符串,再一次性插入父节点;
  3. 事件节流
  4. 尽早操作,例如,条件判断时,提前return;正确的时机执行代码DOMContentLoaded(dom渲染完即执行)onload(全部资源加载完才执行)

html结构简洁、css层级不要过多,原因:

  1. CSSOM匹配DOM生成渲染树,是一个相当复杂和消耗性能的过程;
  2. css是从后向前匹配的。

# Other

  1. script 标签:调整加载顺序提升渲染速度

    • async 属性。立即请求文件,但不阻塞渲染引擎,而是文件加载完毕后阻塞渲染引擎并立即执行文件内容。会在load事件之前执行,不能确保与DOMContentLoaded的执行先后顺序。适用于独立不依赖其它模块的代码,或者需要js尽早做些事情的情况,例如进入页面立马发送一个请求,此时script async可以放在head标签中。
    • defer 属性。立即请求文件,但不阻塞渲染引擎,等到解析完 HTML 之后再执行文件内容。会在DOMContentLoaded和load事件之前执行。适用于存在依赖关系的模块。
    • HTML5 标准 type 属性,对应值为“module”。让浏览器按照 ECMA Script 6 标准将文件当作模块进行解析,默认阻塞效果同 defer,也可以配合 async 在请求完成后立即执行。

  2. link 标签:通过预处理提升渲染速度

    • dns-prefetch。当 link 标签的 rel 属性值为“dns-prefetch”时,浏览器会对某个域名预先进行 DNS 解析并缓存。这样,当浏览器在请求同域名资源的时候,能省去从域名查询 IP 的过程,从而减少时间损耗。下图是淘宝网设置的 DNS 预解析。
    • preconnect。让浏览器在一个 HTTP 请求正式发给服务器前预先执行一些操作,这包括 DNS 解析、TLS 协商、TCP 握手,通过消除往返延迟来为用户节省时间。
    • prefetch/preload。两个值都是让浏览器预先下载并缓存某个资源,但不同的是,prefetch 可能会在浏览器忙时被忽略,而 preload 则是一定会被预先下载。
    • prerender。浏览器不仅会加载资源,还会解析执行页面,进行预渲染。

    注:chrome实测发现,preload、prerender并不一定有效,这是因为浏览器对该标签属性的执行,是根据实际情况判断的。

最后更新时间: 6/3/2021, 8:02:18 PM