输入URL后浏览器的渲染过程
铅笔头课堂,有态度的前端培训
输入URL后浏览器的渲染过程
背景
作为前端开发,浏览器是与我们日常相伴的工具,以chrome为例,我们可以利用它调试页面的element节点、network网络、console输出、以及断点调试等等
可是很多时候我们面试会遇到一个问题——解释一下浏览器渲染原理。
那么本次视频,猫叔带大家一起来了解一下浏览器的渲染原理
我们从地址栏输入地址并按下回车那一刻,浏览器就已经开始了它的工作了。
缓存读取阶段
首先是缓存读取阶段
浏览器地址栏请求是GET请求,此时浏览器会根据你的url来查看本地缓存并检查这个缓存是否可用,如果可用就直接展示缓存内容,如果已经不可用了就重新向服务器请求最新内容
缓存?这是怎么回事?
在进行get请求时,服务器可以在响应的信息头中设置两个字段用于表示当前信息的缓存信息:
Expires:"Tue, 06 Dec 2022 22:02:20 GMT"
,值为一个绝对时间(当前时间+缓存时长)- HTTP1.0提供
Cache-Control:"max-age=600"
,max-age的值为秒- HTTP1.1提供
当浏览器发现响应头中带有它俩其中之一时,会进行数据的缓存操作,并在此后每一次GET请求时都对比一下这俩字段来判断当前缓存的资源是否已经过期
URL解析阶段
如果没有本地缓存或者本地缓存不可用,那么就需要去服务器请求资源
此时浏览器会将你输入的URL地址进行解析,从而得到:
- 协议——
http
或https
- 域名(IP+端口)——
www.pencil-edu.com
- 路径——
/stu-list
- 参数——
?currentPage=1&pageSize=5
然后将这些内容拼凑成一个HTTP(GET)请求报文,准备发送请求
此处请求报文大家可以自行查阅相关资料,不做深入讲解
DNS解析阶段
假如你请求的是一个域名而不是明确的IP地址的话,你的浏览器还需要经历DNS域名解析的过程。这个过程中,DNS服务会通过你的域名来获取目标服务器的真实IP地址,NDS会经历以下步骤来寻找目标服务器的IP:
- 最先从浏览器缓存寻找这个网址对应的IP
- 如果没有的话,就从你的操作系统的DNS缓存和hosts文件中寻找
- 如果还是没有的话,就去你家路由器上的DNS缓存寻找
- 如果还是没有的话,就去ISP(互联网服务提供商)供应商的缓存中寻找(电信、联通、移动、长城等宽带服务商)
- 如果以上都找不到的话,就去公共的DNS解析服务器上发起查找请求
总结一下你会发现,浏览器对域名的查找物理距离采取的是就近原则,从浏览器本身,到操作系统,再到你家客厅的路由,再到你家社区附近的电信服务供应商,最后到互联网公共DNS解析服务
TCP三次握手
随后我们来到经典的TCP三次握手阶段,浏览器与服务器之间就像好友之间打电话,需要相互确认身份后才能对话:
- 浏览器:喂?服务器大哥吗?我是浏览器
- 服务器:啊,是浏览器兄弟呀,是我,我是服务器
- 浏览器:哎呀,真是服务器大哥呀,大哥我有事儿想跟您商量一下
- 服务器:好的兄弟,你有什么事儿你说吧
上面的电话聊天最重要的是:
- 双方都需要先表明自己的身份
- 等到双方都确认了身份了以后才开始正式对话
而如果用通信过程的思维来看待他们的对话的话,会是这样:
是服务器吗大哥?
是客户端在请求对话,而我是浏览器
是客户端发出确认信息并等待服务端确认回应啊,是浏览器兄弟呀
代表服务端确认了客户端发送的信息,是我,我是服务器
是服务端也同样发出了确认信息并等待客户端确认回应哎呀,真是服务器大哥呀
,表示客户端已经确认了服务器发送的信息,加上大哥我有事儿想跟您商量一下
是客户端反馈给服务器的确认结果,服务器则回复好的兄弟,你有什么事儿你说吧
以确认建立对话连接
在TCP的通信协议中,客户端和服务端都是用报文信息来进行身份确认,而报文内容中最需要我们重视的有以下几个字段:
- 常规序号
- seq——传输序号
- 确保连接稳定性,并标记传输数据包的顺序
- 初次连接的时候,seq其实是随机生成的,这样不至于被攻击者猜测到,进而知道下一次seq值的演变
- seq初始值为一个随机值,后续seq的值等于对方响应的ack值(即对方要求从哪一个字节继续传输)
- seq——传输序号
- 确认序号
- ack——确认序号
- 告知对方已经确认收到消息,ack的值等于对方seq值加1,
- 随后将ack发送给对方,对方便知道下一次传输应该从seq+1以后的字节数据开始
- ack——确认序号
- 标志位——用于标记当前建立通信的状态
- SYN——表示发起了一个连接请求,SYN为1时,代表此时发起了一次连接请求
- ACK——表示已经收到对方发送的数据,ACK为1时,ack才被视为有效接收
我们通过以上几个字段即可简单描述TCP的三次握手过程了
由于TCP通信是全双工通信模式,即客户端与服务端都具备发送数据和接受数据的能力,这意味着:
- 客户端需要向服务端发送连接请求
- 发送标志位SYN=1,代表发起请求
- 设置seq为一个随机值
- 服务端也有需要向客户端发送连接请求
- 发送标志位SYN=1,代表发起请求
- 设置seq为一个随机值
而不论客户端还是服务端,接收到数据之后,都需要设置ACK为1来确认数据接受状态,并且将ack设置为对方的seq+1
完整的TCP握手过程如下所示:
第一次握手
- 客户端通过
SYN连接请求报文字段
和seq序号报文字段
发送连接请求- 将TCP连接报文的
SYN连接请求标志位字段
设置为1,这代表发起了一个新的连接 - 同时设置连接报文的
seq
序号字段等于一个随机值(此处用Client代替) - 再将
SYN
和seq
数据包发送给服务器 - 此时客户端状态为
SYN_SENT
,等待服务器确认
- 将TCP连接报文的
第二次握手
- 服务器收到数据包以后,对连接进行确认,并返回应答信息
- 通过
SYN连接请求标志位字段
的值为1,服务器知道了客户端发起了一个连接请求 - 服务器将
SYN连接请求字段
的值设置为1,同时设置ACK确认标志位字段
的值设置为1,用来表示服务器已经接受并确认了请求 - 服务器设置
ack序号报文字段
值为Client+1
,并设置服务端自己的seq
为一个随机值(此处用Server代替) - 服务端将
ack
、服务端的seq
、SYN=1
、ACK=1
数据包发送给客户端以确认连接,此时服务端状态进入SYN_RCVD
状态
- 通过
第三次握手
- 客户端收到确认数据包后,对数据字段进行确认,并提交确认应答信息
- 客户端总共会得到
ACK=1
、ack=Client+1
、seq=Server
、SYN=1
等字段信息 - 客户端检查服务端发送的数据是否为
ACK=1
、ack=Client+1
- 如果数据满足则将客户端数据报文的
ACK
标志位字段设置为1,ack
序号字段设置为Server+1
, - 客户端设置
ACK=1
,设置ack = Server + 1
, 并按照服务端要求设置seq = Client + 1
,
- 客户端总共会得到
- 服务端收到客户端发送的数据以后,检查字段信息,随后建立连接
- 检查
ACK
标志位是否为1,ack
序号字段是否为Server+1
- 如果字段值都正确则连接建立成功,此时客户端和服务端进入
ESTABLISHED
状态,至此三次握手完成。 - 随后,客户端和服务端就可以开始传递数据了
- 检查
上述所有随机值(Client、Server等)均为指代,并没有实际意义
HTTP请求阶段
当TCP连接建立完成后,此时客户端将发起http请求,服务器接收到请求之后会对请求进行解析并转发给服务端处理程序,而服务端处理程序往往会进行以下工作:
- 解析资源路径,比如你请求的是
http://pencil-edu.com/stu/list?currentPage=1&pageSize=5
,那么服务端程序会得到/stu/list
路径 - 根据资源路径映射到对应处理过程
- 后端同学在程序中书写了对
/stu/list
资源路径请求的处理逻辑,此时将进入这部分逻辑的处理中
- 后端同学在程序中书写了对
- 获取参数、
Content-type
文本格式等相关http请求信息,并带入程序执行计算- 获取请求参数,查询数据库等
- 有时候如果是POST请求的话,我们还需要用到请求头中的
Content-Type
,来确定当前数据传递格式是否与资源规范要求一致
- 服务端将数据返回到客户端
TCP四次挥手
等到客户端和服务端的数据传递结束后,就需要结束本次TCP连接了,而结束本次连接则需要进行TCP四次挥手阶段。
四次挥手阶段需要借助一个FIN标志位状态字段,这个字段刚好与SYN标志位字段表达的意思相反——FIN=1时标记当前为断开连接请求
完整过程为:
第一次挥手
- 客户端发送报文,请求主动关闭连接
- 客户端发送请求到服务端,并设置
FIN标志位=1
,seq
序号为一个随机值Client - 此时客户端的装状态从
ESTABLISHED
改变为FIN_WAIT1
(终止等待1)
第二次挥手
- 服务端收到数据包以后,确认设置
ACK
标志位1,代表收到数据;并设置ack确认序号
为Client+1 - 服务端自己也初始化一个
seq序号
,给定随机值为Server - 服务端将
ACK=1
,ack=Client+2
,seq=Server
发送给客户端 - 服务单状态切换为CLOSE_WAIT(关闭等待)
- 客户端收到确认消息后切换为状态为FIN_WAIT2(终止等待2)
第三次挥手
- 服务端发送报文,请求主动关闭连接
- 服务端设置
FIN标志位=1
,seq
序号为一个随机值Server_close - 并且服务端设置
ACK=1
,设置ack=Client+1
ack
其实是前面第二次挥手的时候客户端传递的,这让客户端能够确保当前连接的可靠性
- 服务端将
FIN=1
,seq=Server_close
,ACK=1
,ack=Client+1
发送到客户端 - 服务端状态切换为LAST_ACK(最后确认)阶段
第四次挥手
- 客户端收到
FIN=1
,seq=Server_close
,ACK=1
,ack=Client+1
数据包之后 - 将客户端自己的报文中
ACK
标志设置为1,并且设置序号seq = Client+1
,设置确认序号为ack=Server_close+1
- 客户端发送
ACK=1
,seq=Client+1
,ack=Server_close+1
到服务端,服务端收到客户端的报文之后将状态切换为CLOSE - 此时客户端的状态切换为TIME_WAIT状态,在等待2*MSL周期之后,切换为CLOSE
MSL代表一次消息往返(从发送到接收)所需最大时间,如果直到2*MSL周期结束,主动断开方都没有再一次接收到对方报文,则推断ack已经被对方接收成功,至此,主动断开方将结束自己的TCP连接
至此,客户端与服务端完成四次挥手,本次TCP连接断开
之所以上述过程中会多一次挥手过程,是因为TCP是全双工通信模式,客户端和服务端既可以发请求也可以接受数据,所以每一个方向都需要单独关闭;即使客户端发送了FIN,仅意味着客户端表示不再发送数据到服务端的状态;但事实上客户端仍然可以发送数据,因为服务端还保持了连接;直到服务端也发送了FIN,那么客户端将执行主动关闭,而服务端将执行被动关闭。
上述所有随机值(Client、Server等)均为指代,并没有实际意义
文档解析
构建DOM
- 客户端读取后端响应的文本流,进行词法分析,根据HTML规范,将字符流解析为HTML标签。
- 基于标签生成htmlDom节点对象
- 根据html标签的关系,构建DOM树
DOM树的构建过程是一边获取数据一边构建的,这样做可以让浏览器尽可能快的呈现视图元素
构建CSSOM
- 当DOM构建过程中遇到style标签,则同时进行style标签解析和CSSOM的解析构建
- 当DOM树构建时遇到了link标签,则会请求css文件
- 等到css文件加载完成后就开始解析css,这个过程不与DOM树构建发生冲突
- cssom树的解析构建过程依赖html的DOM树结构,毕竟只有DOM才有真正意义上的树形结构关系
构建Render Tree
将htmlDOM树和CSSOM树合并组成Render Tree,然后对Render Tree进行以下操作
- 遍历每一个Render Tree节点,将
head
,meta
等不呈现视图(不可见)的节点移除 - 如果某个节点的样式包含
display:none
,也从Render Tree移除
Layout
浏览器遍历Render Tree上的节点及节点的CSS样式信息,计算出当前节点在页面中的的位置 、大小等信息,并基于当前ViewPort视窗信息计算出节点元素位置和大小的绝对像素值
这一过程我们称为重排,所有页面第一次加载时默认都会执行重排,此后只要修改了节点的位置、大小等几何属性,都会导致一次重排过程。
Paint
当Layout阶段完成了节点样式和布局计算后,浏览器就将Render Tree中的节点以像素形式绘制渲染到浏览器中,这个过程我们称为重绘,所有页面第一次加载时默认都会执行重绘,此后只要修改了节点的背景、字体颜色等表现属性,都会导致一次重绘。
由于重绘仅仅需要经历Paint过程,所以性能开销相对重排小很多。
至此,从浏览器输入URL,到最后页面的显示的简单介绍就到这里了。
输入URL后浏览器的渲染过程相关推荐
- 从输入 URL 到浏览器接收的过程中发生了什么事情
从输入 URL 到浏览器接收的过程中发生了什么事情? 原文:http://www.codeceo.com/article/url-cpu-broswer.html 从触屏到 CPU 首先是「输入 U ...
- 前端面试系列-输入url后全过程页面渲染机制DOM生成过程
文章目录 一.当输入url后,全过程 二.页面渲染机制 三.DOM 1.什么是 DOM 2.DOM 树如何生成 HTML 解析器 3.JavaScript 是如何影响 DOM 生成的 内嵌JavaSc ...
- 【前端问题分析】从输入 URL 到浏览器接收的过程中发生了什么事情?
从触屏到 CPU 首先是「输入 URL」,大部分人的第一反应会是键盘,不过为了与时俱进,这里将介绍触摸屏设备的交互. 触摸屏一种传感器,目前大多是基于电容(Capacitive)来实现的,以前都是直接 ...
- 从输入 URL 到浏览器接收的过程中发生了什么事情?
写得很全面,有待进一步展开.. 从触屏到 CPU 首先是「输入 URL」,大部分人的第一反应会是键盘,不过为了与时俱进,这里将介绍触摸屏设备的交互. 触摸屏一种传感器,目前大多是基于电容(Capaci ...
- 在浏览器地址栏中输入URL后发生了什么
在浏览器地址栏中输入URL后发生了什么 基本流程: ①查询ip地址 ②建立tcp连接,接入服务器 ③浏览器发起http请求 ④服务器后台操作并做出http响应 ⑤网页的解析与渲染 详细步骤如下: 查询 ...
- 输入URL到浏览器显示页面的过程,搜集各方面资料总结一下
面试中经常会被问到这个问题吧,唉,我最开始被问到的时候也就能大概说一些流程.被问得多了,自己就想去找找这个问题的全面回答,于是乎搜了很多资料和网上的文章,根据那些文章写一个总结. 写得不好,或者有意见 ...
- 从浏览器输入URL到页面显示的过程
从浏览器地址栏输入url到显示页面的步骤: 目录 1.概述 浏览器根据请求的URL交给DNS域名解析器,找到真实IP,向服务器发起请求: 三次握手建立连接,服务器交给后台处理完成后返回数据,浏览器接收 ...
- 在浏览器输入URL后发生了什么?
摘录部分一:https://www.cnblogs.com/kongxy/p/4615226.html 从输入URL到浏览器显示页面发生了什么 当在浏览器地址栏输入网址,如:www.baidu.com ...
- 【重难点】【计算机网络 01】OSI 七层模型和 TCP/IP 四层模型、IP 地址分为哪几类、ping 的原理、从浏览器地址栏输入 URL 到显示网页的过程、什么是 socket
[重难点][计算机网络 01]OSI 七层模型和 TCP/IP 四层模型.IP 地址分为哪几类.ping 的原理.从浏览器地址栏输入 URL 到显示网页的过程.什么是 socket 文章目录 [重难点 ...
最新文章
- Android官方开发文档Training系列课程中文版:OpenGL绘图之应用投影与相机视图
- 苹果推出开源医学研究框架ResearchKit
- 微信小程序网络请求代码片段
- 帆软日期控件变灰_FineReport-JS脚本常见日期使用整理
- Centos7 上安装mysql遇上的问题:mysql无法正常启动
- Javaassist简介
- 一个商城的购车相关代码
- 理解ORACLE数据库字符集
- mybatis plus 新增,修改
- kali linux子远程桌面,适用于kali linux的远程桌面开启方法(从windows xp 远程登录到kali linux )...
- JavaScript应用(重点数组)
- HDOJ 1227 DP
- [Erlang 0020]网页游戏分线到不分线
- 关于右键新建Word不调用默认模板的问题
- Qt实现Windows风格无边框
- 关于一体机外卖单不打印外卖单号FAQ(适用正餐6.0.09,轻餐4.0.6.1,轻餐4.0.6.2)
- anaconda中使用pip安装pytorch(GPU)
- 阿里P9架构师终于把毕生心血而成的分布式高可用算法笔记开源了
- 文津读书沙龙:吴军杨早数学之美-文明之光
- sql server 中获取前一天日期_图解面试题:如何比较日期数据?
热门文章
- 解决服务器windows主机显示本地连接网络电缆没插好问题
- 如何在 Sony Playstation 3 安装 Fedora 9
- 使用VS 2019制作桌面程序的安装包
- OPC Tunneller——从此不用配置DCOM了!
- 新手如何进入UI设计行业?怎么提升专业技能
- Machine Learning experiment2 Multivariate Linear Regression 详解+源代码实现
- Author identity unknown | Please tell me who you are | git commit -m “first commit”
- 九年级计算机ppt,九年级信息技术 计算机的奥妙课件全国通用.ppt
- java 农历节日 转公历日期_公历农历互相转换的Java日历工具类
- 人口数据集:地级市常住人口与户籍人口、人口1%抽样调查数据两大维度指标数据