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

在这里插入图片描述
过程:

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时

减少回流和重绘

回流:元素大小和位置改变
重绘:元素样式的改变
每次页面渲染,必然有一次回流与重绘;
回流一定重绘,重绘不一定回流;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


LUYrty樱花
29 声望3 粉丝