URL从输入到渲染发生了什么

用户输入url从输入到渲染的过程发生了什么,是一道很常见的面试题,这里对输入到渲染流程做了个统一的整理,方便读者可以更好的理解和在面试中更好的回答这个问题

前言

在讲解url渲染流程前我们先来学习下几个重要的概念
1, 进程与线程
2, TCP IP 与 UDP
3. 页面缓存

1. 进程与线程

在讲进程与线程之前我们先来了解下单线程与多线程,线程分为单线程与多线程, 单线程是指同一时间只能执行一个任务, 多线程是指同一时间可以执行多个任务, 线程是依附于进程中的, 早期的浏览器时单进程的, 因为这么多功能模块共同依赖于一个功能模块 导致了不稳定,不流畅, 不安全等缺陷, 为了解决这一系列的缺陷,浏览器便演变为现在的多进程
多进程包含 浏览器主进程 渲染进程 插件进程 网络进程 GPU进程

浏览器进程主要负责 主要负责界面显示、用户交互、子进程管理,同时提供存储等功能。

渲染进程 主要作用是将html css js 转换为可以与用户交互的页面, 每一个tab页签都会创建一个渲染进程
GPU进程 主要用来绘制ui页面的进程
网络进程 主要用于管理http请求的进程
插件进程 主要负责插件的运行 避免插件因为崩溃导致页面无法正常运行

2. IP UDP 与 TCP

IP UDP 与 TCP 都是传输层的协议, 主要作用就是将数据包传输给目标主机和具体应用

IP协议

把数据包送达主机
IP是非常底层的协议 主要作用就是将数据包传输给主机, 当A主机向B主机发送数据时主机A上层会将数据传输给网络层, 网络层会给数据包附带上主机B的IP头信息(ip相当于一个主机地址), 当数据到达主机B网络层时, 会将IP数据包解析成IP地址和数据包传输给B主机的上层

UDP

把数据包送达应用程序
IP协议可以将信息传输给主机, 但是不能确定好是具体传输给哪个应用, 所以基于IP协议 数据包传输新增了一个端口号的功能 来解析需要传递给哪个应用, 当主机A向主机B发送数据时 主机A上层会将数据包 传输给传输层,传输层会给数据包附上端口号等信息交给网络层, 网络层最后将IP信息传递给主机B的网络层,主机B的网络层接收到数据包时会将IP头解析出来,将包含端口号的数据包传输给传输层, 传输层将端口号解析出来判断要送达给哪个应用程序,最终将数据包传输给主机B

TCP

把数据包完整的送达应用程序
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。什么是面向连接的呢, 面向连接是指在数据通信开始之前先做好两端之间的准备工作。可靠的是指TCP默认引用排序机制,将序号包含在数据包中, 可以保证将一个乱序的数据包整合成一个完整的文件,并且在发送端发送数据包一定时间内,没有收到接收端的反馈,就会触发TCP的重传机制保证了传输数据的可靠性
Tcp建立连接共分为三个阶段, 建立连接阶段, 数据包确认阶段, 断开链接阶段
首先,建立连接阶段。这个阶段是通过“三次握手”来建立客户端和服务器之间的连接。所谓三次握手,是指在建立一个 TCP 连接时,客户端和服务器总共要发送三个数据包以确认连接的建立。为什么是三次握手呢, 一次肯定不行,客户端给服务端发送数据包,不知道服务端的反馈,不知道是否要建立连接,两次也不行,客户端收到服务端确认的消息后,服务端不知道是否要进行下一步操作, 所以要进行三次握手, 其次,传输数据阶段。在该阶段,接收端需要对每个数据包进行确认操作,也就是接收端在接收到数据包之后,需要发送确认数据包给发送端。所以当发送端发送了一个数据包之后,在规定时间内没有接收到接收端反馈的确认消息,则判断为数据包丢失,并触发发送端的重发机制。同样,一个大的文件在传输过程中会被拆分成很多小的数据包,这些数据包到达接收端后,接收端会按照 TCP 头中的序号为其排序,从而保证组成完整的数据。最后,断开连接阶段。数据传输完毕之后,就要终止连接了,涉及到最后一个阶段“四次挥手”来保证双方都能断开连接。同样为什么要进行四次挥手呢, 客户端发送了 FIN 之后,服务器收到了数据包,就进入了 CLOSE-WAIT 状态。这个状态是为了让服务器端发送还未传送完毕的数据,传送完毕之后,服务器会发送数据包来关闭连接。
在这里插入图片描述直白的讲理解, 三次握手就是
小A(渣男) (客户端)向 小B(服务端)告白 , 微信给小B说我喜欢你,我们交往吧, 等待小B的回
小B看到告白信 同意与小A交往 并将信转交给小A
小A收到小B的回信后 很开心 两个人开始交往了
四次挥手就是
小A(客户端) 想 和 小 B(服务端) 分手了, 发信息给小B 说我们分手吧
小B 看到消息后回复 小A 分就分, 渣男, 等我一会 我把东西收拾好 CLOSE-WAIT
小B 收拾好东西 告诉小A 你走吧
小A收到小B的消息 头也不回的走了 两个人正式分手 CLOSED

浏览器缓存

我们常常点击一个网站 在一定时间内再次访问会感觉要比第一次访问速度要快, 其实这主要依赖于 浏览器缓存 和 DNS 缓存技术
我们首先来讲解下浏览器缓存, 当我们请求一段资源时, 浏览器会从服务端响应头返回的Cache-Control:Max-age=2000 设置过期时间, 再次请求时, 会判断有没有过期, 没有过期, 取缓存的数据, 如果过期了, 请求头会带上If-None-Match:"" 这个值,服务器拿到这个值会判断数据是否更新 如果没有更新 状态码会返回304 告诉浏览器内容没有更新 需要走缓存
在这里插入图片描述

不多废话了,接下来我们进入正文
在这里插入图片描述

输入到渲染大概包含哪几个过程

简单的说,从输入到渲染一共包含五个过程,分为用户输入过程,url请求过程,准备渲染进程,提交文档,渲染进程,下面我会说明每个过程浏览器都具体做了哪些操作

1. 用户输入过程
在这里插入图片描述

1 ,判断地址栏输的的是关键字是搜索内容还是请求的URL, 如果是搜索内容,地址栏会使用浏览器默认的搜索引擎,来合成新的带搜索关键字的URL,如果输入的内容符合URL规则,地址栏会根据规则,把这段内容加上协议
2, 当用户输入关键字并键入回车之后,这意味着当前页面即将要被替换成新的页面,不过在这个流程继续之前,浏览器还给了当前页面一次执行 beforeunload 事件的机会,询问用户是否离开当前页面, 用户点击确认, 开始第二个过程URL请求过程

2. URL 请求过程
在这里插入图片描述

  1. 构建请求
    2. 查找页面缓存
    3. 准备 IP 地址和端口,浏览器会请求 DNS 返回域名对应的 IP, 并查找DNS缓存,DNS缓存是指域名缓存, 当查找到这个域名对应的IP地址时, 会检查下是否含有缓存,一般浏览器DNS缓存是一分钟,含有缓存并且还在DNS缓存时间内,中断请求
    4. 等待 TCP 队列(同一个域名同时最多只能建立 6 个 TCP 连接)
    5. 建立 TCP 连接(三次握手)
    6. 发送 HTTP 请求(浏览器端会构建请求行、请求头等信息,并把和该域名相关的 Cookie 等数据附加到请求头中,)
    7. 返回请求
    - 返回响应行和状态码
    - 返回响应体
    8. 断开连接(四次挥手)
    - 请求头包含 Connection:Keep-Alive,TCP 连接在发送后将仍然保持打开状态,保持 TCP 连接可以省 去下次请求时需要建立连接的时间,提升资源加载速度
    9. 重定向
    响应行返回的状态码是 301, 并且需要重定向的网址正是包含在响应头的 Location 字段中,浏览器获取 Location 字段中的地址,并使用该地址重新导航
    10. 响应数据类型的处理
    - 通过 Content-Type 来识别返回数据类型的格式, 如application/octet-stream, 则告诉浏览器返回值属于字节流类型的,浏览器会按照下载类型来处理那么该请求会被提交给浏览器的下载管理器,同时该 URL 请求的导航流程就此结束,如果返回html格式,浏览器责会继续进行导航流程,开始准备渲染进程

3. 准备渲染进程

默认情况下,Chrome 会为每个页面分配一个渲染进程,也就是说,每打开一个新页面就会配套创建一个新的渲染进程。但是,域名加上协议如果和原来页面一致的话,那么会复用之前的渲染进程

4. 提交文档
在这里插入图片描述

  • 提交文档,是指浏览器进程将网络进程接收到的 HTML 数据提交给渲染进程
    1. 当浏览器接收到网络请求的响应头数据之后,便向渲染进程发起提交文档消息
    2. 渲染进程收到提交文档的消息后,会和网络进程建立数据传输的管道
    3. 等文档数据传输完成后, 渲染进程会返回确认提交的消息给浏览器进程
    4. 浏览器进程收到确认提交的消息后,会更新浏览器的界面状态,如安全状态,地址栏的URL,前进后退的历史状态,并更新页面

5. 渲染进程

在这里插入图片描述

由于渲染机制过于复杂,所以渲染模块在执行过程中会被分为很多子阶段
1, 构建DOM树
2. 因为浏览器无法直接使用HTML,所以需要转换为浏览器能够理解的结构 – DOM树
在这里插入图片描述这里需要注意的点是js会影响到dom 的加载, 例如 我们在body中插入一段js代码, 渲染进程会暂停dom树的生成,去执行js脚本,执行结束,继续构建dom树, 当渲染引擎遇到带有外链的script文件 同样会阻塞dom树生成,将script链接进行下载并执行这个js文件,执行结束继续构建dom,如果我们引用的js代码中需要操作css 渲染进程会默认下载当前css文件,并解析css,接着解析js,所以加载dom 中有js代码可能会导致页面白屏
- 导致白屏的因素是
- 1, 下载css 文件时间
- 2, 下载js文件时间
- 3, js代码阻塞
3, 样式计算
- 和HTMl一样,浏览器无法识别这些css样式,所以当渲染引擎收到css文本时,会执行一个转换操作,
- 将css转换为
styleSheets
可以在控制台打印document.styleSheets 查看具体的styleSheets 值
- 转换css样式表中的值让其标准化,如em,blue,blod
- 计算出DOM树中每个节点的具体样式, 这里涉及 css 的继承 和 选择器权重的比较 来计算最终当前节点的DOM样式
4,布局阶段
- 那么接下来就需要计算出 DOM 树中可见元素的几何位置,我们把这个计算过程叫做布局
1. 创建布局树,构建一棵只包含可见元素的布局树,遍历DOM树的节点,并把这些节点加到布局树中(不 可见的元素除外,如display:none, head标签等)
2. 布局计算, 又计算每个元素的几何坐标位置 并将这些信息保存在布局树中。
3. 分层
- 因为页面有很多复杂的效果, 如一些复杂的3D转换,页面滚动,或者使用z-index做排序等, 为了更加方便实现这些效果,渲染引擎还需要为特定的节点生成专用的图层,并生成一颗对应的图层树,可以通过Layers标签就可以查看页面分层情况
- 这些图层按照一定的顺序叠加在一起,就形成了最终的页面
形成图层的因素
1. 拥有层叠上下文属性的元素会被提升为单独的一层。
2. 需要剪裁(clip)的地方也会被创建为图层。如overflow:hidden 4. 图层绘制(将绘制图层的样式记录为绘制顺序和绘制指令的列表, 因为每个元素的背景、前景、边框都需要单独的指令去绘制, 所以在图层绘制阶段。我们同样可以从控制台打开layers 标签查看绘制列表)在这里插入图片描述
5. 栅格化操作
- 绘制列表只是用来绘制顺序和绘制指令的列表,而实际上绘制操作是由渲染引擎中的合成线程来完成的,当图层的绘制列表准备好后,主线程会把该绘制列表提交给合成线程
- 这里涉及几个概念 , 视口 图块 位图
- 视口是指我们可以看到的屏幕上的部分称为视口
- 图块 是指将图层分为 256*256 || 512 * 512的一个个小图
- 位图 是指由合成线程 根据当前视口附近的图块优先合成的图片称为位图
- 合成线程会将图层划分为图块,
- 合成线程会将生成的图片交给栅格化线程池, 由栅格化线程池根据当前视口生成位图
6. 合成和显示
所有图块被光栅化, 合成线程会生成一个绘制图块的命令, 然后将该命令提交给浏览器进程, 浏览器主进程收到这个命令,会将其页面内容绘制到内存中,最后再将内存显示在屏幕上。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值