欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

前端性能优化

程序员文章站 2024-03-17 17:23:40
...

一、一次完整页面请求所发生的的事情

前端性能优化
过程:

1.url解析

  • 地址解析和编码
  • HSTS
  • 缓存解析
    前端性能优化

2.DNS域名解析

  • 先进行本地DNS服务器解析,递归解析:

前端性能优化

  • 如果本地解析不到,再去域名服务器解析,迭代解析:

前端性能优化

3.TCP三次握手建立连接:

前端性能优化

4. 发送HTTP请求,服务器处理请求,返回响应结果

5.TCP四次挥手断开连接

前端性能优化

5.浏览器渲染

前端性能优化

二、前端性能优化

前端性能优化主要从上述过程中的关键节点进行优化,这也叫CRP。

1.缓存优化

客户端在向服务端发起请求之前要先检查是否有缓存,如果有缓存的话,直接将缓存渲染到页面,如果没有的话再发起请求。
(1)缓存位置

  • Service Worker:浏览器独立线程进行缓存
  • Memory Cache : 内存缓存
  • Disk Cache:硬盘缓存
  • Push Cache:推送缓存(HTTP/2中的)

一般情况下文存储在浏览器缓存中,数据存储在本地。

  • 打开网页,地址栏输入地址: 查找 disk cache 中是否有匹配,如有则使用,如没有则发送网络请求。
  • 普通刷新 (F5):因为 TAB 并没有关闭,因此 memory cache 是可用的,会被优先使用(如果匹配的话),其次才是 disk
    cache。
  • 强制刷新 (Ctrl + F5):浏览器不使用缓存,因此发送的请求头部均带有 Cache-control:
    no-cache(为了兼容,还带了 Pragma: no-cache),服务器直接返回 200 和最新内容。

(2)硬盘与内存

  • 硬盘读取速度慢,存储内容多;
  • 内存读取速度快,存储内容少。

(3)浏览器缓存
浏览器缓存分为强缓存协商缓存
强缓存在服务器中配置,协商缓存自己配置

强缓存 Expires / Cache-Control

浏览器对于强缓存的处理:根据第一次请求资源时返回的响应头来确定的
前端性能优化

  • Expires:缓存过期时间,用来指定资源到期的时间(HTTP/1)
  • Cache-Control:cache-control:max-age=2592000第一次拿到资源后的2592000秒内(30天),再次发送请求,读取缓存中的信息(HTTP/1.1)
  • 两者同时存在的话,Cache-Control优先级高于Expires
    前端性能优化

协商缓存 Last-Modified / ETag

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

协商缓存生效,返回304和Not Modified
前端性能优化
协商缓存失效,返回200和请求结果
前端性能优化
Last-Modified和If-Modified-Since

  • 第一次访问资源,服务器返回资源的同时,响应头中设置 Last-Modified(服务器上的最后修改时间),浏览器接收后,缓存文件和响应头;
  • 下一次请求这个资源,浏览器检测到有
    Last-Modified,于是添加If-Modified-Since请求头,值就是Last-Modified中的值;
  • 服务器再次收到这个资源请求,会根据 If-Modified-Since
    中的值与服务器中这个资源的最后修改时间对比,如果没有变化,返回304和空的响应体,直接从缓存读取,如果If-Modified-Since的时间小于服务器中这个资源的最后修改时间,说明文件有更新,于是返回新的资源文件和200;
  • 但是Last-Modified 只能以秒计时,如果在不可感知的时间内修改完成文件,那么服务端会认为资源还是命中了,不会返回正确的资源;

ETag和If-None-Match

  • Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成;下一次加载资源向服务器发送请求时,会将上一次返回的Etag值放到请求头If-None-Match里,服务器只需要比较客户端传来的If-None-Match跟自己服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了。如果服务器发现ETag匹配不上,那么直接以常规GET 200回包形式将新的资源(当然也包括了新的ETag)发给客户端;如果ETag是一致的,则直接返回304知会客户端直接使用本地缓存即可。

2.DNS方面的优化

每一次DNS解析时间预计在20~120毫秒

减少DNS请求

即减少要请求的服务器,这个很难实现,因为目前我们都在将资源放在不同的服务器上,然后客户端从不同服务器上拉取资源。

前端性能优化
如上图,我们利用反向代理服务器,将用户请求转发的服务器集群,这样做有这样几个好处:

  • 网站安全的作用,来自互联网的访问请求必须经过代理服务器,相当于web服务器和可能的网络攻击之间建立了一个屏障。
  • 可以通过配置缓存功能加速web请求。当用户第一次访问静态内容的时候,静态内容就被缓存在反向代理服务器上,这样当其他用户访问该静态内容的时候,就可以直接从反向代理服务器返回,加速web请求响应速度,减轻web服务器负载压力。事实上,有些网站会把动态内容也缓存在代理服务器上,比如*及某些博客论坛网站,把热门词条、帖子、博客缓存在反向代理服务器上加速用户访问速度,当这些动态内容有变化时,通过内部通知机制通知反向代理缓存失效,反向代理会重新加载最新的动态内容再次缓存起来。
  • 此外,反向代理也可以实现负载均衡的功能,而通过负载均衡构建的应用集群可以提高系统总体处理能力,进而改善网站高并发情况下的性能。

(2)DNS预解析(DNS Prefetch)

link发送的是异步请求,因此在解析HTML代码的同时,就可以进行异步DNS解析,当用到后面的域名时,就已经解析好了,可以直接用,而不用等待。

<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//static.360buyimg.com"/>
<link rel="dns-prefetch" href="//misc.360buyimg.com"/>
<link rel="dns-prefetch" href="//img10.360buyimg.com"/>
<link rel="dns-prefetch" href="//d.3.cn"/>
<link rel="dns-prefetch" href="//d.jd.com"/>

3.HTTP时的优化

减少HTTP请求次数和请求资源大小

  • 资源合并压缩
  • 字体图标
  • Base64
  • GZIP(一般的文件能压缩60%多)
  • 图片懒加载
  • 数据延迟分批加载
  • CDN资源
    CDN(content distribute network,内容分发网络)的本质仍然是一个缓存,而且将数据缓存在离用户最近的地方,使用户以最快速度获取数据,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。即所谓网络访问第一跳,反向代理,如下图:
    前端性能优化

4.浏览器渲染优化

(1)浏览器渲染过程

构建DOM树、CSSOM树、渲染树
1> DOM树
字符编码—>字符集—>令牌—>Nodes节点—>DOM
前端性能优化

2> CSSOM树
前端性能优化

3>Render Tree 渲染树
前端性能优化
总结步骤:

  • 处理 HTML 标记,构建 DOM 树
  • 处理 CSS 标记,构建 CSSOM 树
  • 将 DOM 树和 CSSOM 树融合成渲染树
  • 根据生成的渲染树,计算它们在设备视口(viewport)内的确切位置和大小,这个计算的阶段就是回流 => 布局(Layout)或重排(reflow)
  • 根据渲染树以及回流得到的几何信息,得到节点的绝对像素 => 绘制(painting)或栅格化(rasterizing)
    前端性能优化
(2)优化方案

生成DOM树时

  • 标签语义化,遵循W3C标准
  • HTML标签避免多级嵌套

生成CSSOM树时

  • CSS选择器避免深层次嵌套,多级层级从右到左渲染
.box a{}
.a{}
<div class="box">
  <a href="">a<a/>
</div>

上面代码 .a{}比.box a{}快

  • CSS预编译器,层级嵌套要慎用
  • 减少使用@import阻塞渲染的请求,link写在头部(尽早尽快地把CSS下载到客户端(充分利用HTTP多请求并发机制)),样式少时可使用style.
名称 描述
link 异步加载,发送一个HTTP请求,单独线程取处理;同时渲染DOM
@import 同步加载,若使用了@import,则要等资源全部拉回来,才能继续渲染DOM
style 在html拿回来之前就已经发送请求,因此DOM渲染过程中不发送请求,因此若样式不多,使用style最快

避免阻塞的JS加载

  • JS放在文件底部,因为script是同步加载,要先解析script里面的代码,再回来加载HTML
  • defer和async,尽量使用defer
    前端性能优化
名称 描述
defer 发请求拉东西时,不阻塞渲染,拿回来之后,要等页面渲染完成之后,再加载JS,可以有依赖(例如Jquery)
async 发请求拉东西时,不阻塞渲染,拿回来之后,要先加载js及依赖,加载完成之后再继续渲染

生成render Tree时

减少回流和重绘

回流:元素大小和位置改变
重绘:元素样式的改变
每次页面渲染,必然有一次回流与重绘;
回流一定重绘,重绘不一定回流;
前端性能优化
前端性能优化
前端性能优化
前端性能优化

相关标签: web前端

上一篇: [kmp+模板] kmp模板

下一篇: KMP算法