URL解析过程和浏览器渲染机制【面试必问、深入解析 下一次再也不怕面试官问这个问题】

步骤拆分

  • 网络-请求和响应
    • 缓存
    • DNS解析
    • 建立TCP连接(三次握手和四次挥手)
    • 服务端验证请求
    • 响应文件类型(Content-Type)
  • 浏览器-解析与渲染
    • 浏览器进程和线程
    • 构建Dom树
    • layout paint 合成显示

详细回答

一、缓存
  1. 缓存在请求资源时很大程度提高了效率,对于前端和服务端都是很好的性能优化的手段。
  2. 缓存分为强缓存和协商缓存
  3. 判断强缓存的条件是,在请求开始,浏览器会验证该请求是否具有强缓存,判定缓存的标识是请求头中的cache-control(http1.1同时存在cache-control和expires)、expires(http1.0只存在expires)字段,当两者在http1.1同时设置时,优先使用cache-control判断是否具有强缓存
  4. cache-control的值是max-age = xx;这个值代表客户端收到第一次响应成功后,该资源请求需要被缓存的时间,未超过这个时间下次请求则不发送任何请求,直接使用缓存数据
  5. 判断协商缓存的条件是请示头中的If-None-Match 和响应头中的E-tag,这两个字段成对存在,如果发出请求后两者相对于,则表示请求结果未发生任何改变,浏览器可以使用本地缓存,服务器返回状态码304
二、DNS解析
  1. DNS的解析过程是域名转换为真实IP地址的过程。
  2. 一个域名对应一个IP地址,一个IP地址可以对应多个域名。
  3. 优先从本机hosts文件中查找是否有和这个网站和IP地址映射关系,有则直接直接使用这个IP地址,完整解析。
  4. hosts文件中没有映射关系,DNS会按照固定的顺序查找缓存,步骤为浏览器本机系统路由器缓存运营商缓存根域名服务器顶级域名服务器主域名服务器
  5. 没有缓存则像DNS服务器发出请求,获取该域名对应的真实IP地址(此过程可以使用dns-prefetch进行预解析优化)
三、TCP连接
  1. http的本质就是TCP连接,此时要进行三次握手。
  2. 第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认。
  3. 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  4. 客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
  5. 该过程完成后,服务端开始像客户端传输数据。
四、服务端验证请求
  1. 服务端收到请求会对请求进行统一的验证,如安全拦截,跨域验证等。
  2. 根据请求类型做出处理,返回对应的响应白报文。
五、响应文件类型
  1. 服务端会根据Content-Type 来判断响应文件类型
  2. 文本、图片等资源浏览器会直接渲染展示到页面
  3. stream流文件,浏览器会进行下载
  4. html文档,会交给浏览器进行解析和渲染
六、浏览器的线程和进程
  1. 浏览器是多进程的,每一个窗口是一个进程。浏览器内核则是多线程的,资源下载会进行多线程下载。
  2. 浏览器内核的线程分为以下几种
    • 定时器线程
      • 负责执行异步定时器一类的函数的线程,如 setInterval,setTimeout 等。
      • 主线程依次执行代码时,遇到定时器,会将定时器交给该线程处理,当计数完毕后, 事件触发线程会将计数完毕的事件加入到任务队列的尾部,等待 JS引擎线程执行。
    • GUI线程
      • 主要负责页面的渲染,解析 HTML,CSS,构建 DOM 树,布局和绘制等。
      • 当页面需要重绘或者由于某种操作引发回流时,将执行该线程。
      • 该线程与JS 引擎线程互斥,当执行 JS 引擎线程时,GUI渲染线程会被挂起, 当前任务队列为空时,JS引擎才会去执行 GUI 渲染。
    • 网络请求进程
      • 主要负责异步请求一类的函数的线程,如 Promise,axios,ajax等,主线程依次执行代码时,遇到异步请求,会将函数交给该线程处理,当监听到状态码变更,如果有回调函数,时间触发线程会将回调函数加入到任务队列的尾部,等待 JS 引擎线程的执行。
    • Js引擎线程
      • 主要负责处理 JavaScript 脚本,执行代码。
      • 也主要负责执行准备好的待执行的事件,即定时器结束,或者异步请求成功并正确返回时,将依次进入任务 队列,等待 JS 引擎线程的执行。
      • 该线程与 GUI 渲染线程互斥,当 JS引擎线程执行 JavaScript 脚本时间过长, 将导致页面渲染的阻塞。
    • 事件触发线程
      • 主要负责将准备好的事件交给 JS 引擎线程执行,比如 setTimeout 定时器计数结束,ajax 等异步请求成功并触发回调函数,或者用户触发点击事件时,该线程会将整装待发的事件依次加入到任务队列的尾部,等待 JS 引擎线程的执行。
  3. 浏览器内核得到报文后会进行以下的步骤完成页面的渲染
    • 解析HTML得到Dom Tree
    • 解析Css 得到Css Tree
    • 合并Dom Tree和Css Tree生成Render Tree
    • layout(布局) 计算每个元素的大小和位置,将元素布局到页面正确的位置
    • paint(绘制) 绘制页面的像素信息,填充具体的样式
    • GPU将合成后的结果显示到页面
      回流和重绘
七、构建Dom树的过程

构建Dom是编码和解码的过程,主要经过一下几个环节

  • 编码: 将html原始字节内容转换为指定的编码内容
  • 令牌化: 每一个标签都是一个令牌,内部保存自己的规则,令牌记录了标签的开始和结束,这也是判断标签有没有子节点的依据
  • 生成对象:每一个令牌都会生成具有属性的对象,该对象保存该节点所携带的信息
  • 构建完成 : 形成多个对象组成的树形结构

注: CssTree的构建过程同理
DomTree和CssTree最终合并为RenderTree,此时浏览器可以进行渲染

八、layout和paint
  1. 根据渲染树中的每一个节点位置,尺寸信息,将节点渲染到执行的位置
  2. 根据渲染树中节点的样式信息,为每一个节点分配样式
九、回流和重绘
  1. 回流: 当元素的位置,大小,结构等信息发生变化时,会构建渲染树,此过程称为回流。
  2. 重绘: 当元素外观视觉发生变化时,只需要使用新的样式覆盖这个元素,此过程称为重绘。
  3. 回流必定引起重绘,重绘不一定引起回流。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值