当在浏览器地址栏输入url后都发生了什么
wwwwwww从url到页面
DNS解析
DNS(Domain Name System)域名系统
只讨论浏览器范围内的,DNS就是域名解析为IP的服务,有了IP才能向对应HTML的服务器发请求
名词解释
- 根服务器:
.,最顶级的域名服务器,记录了顶级域名的服务器地址 - 顶级域名服务器:保存着顶级域名的服务器,
.top .org - 二级域名服务器:一般申请的域名都为二级域名,二级域名服务器保存着三次域名缓存,通过分发系统分发
- 权威服务器:DNS服务器有多个的情况下,比如在一个范围内有多个顶级域名服务器,其中一台记录其他顶级域名服务器的记录,这一台就是这个区域的权威服务器
解析过程
先在本地的Host文件查询有无DNS记录。如果没有,使用递归查询的方式,去找上游的服务器,上游服务器会进行多次的迭代查询,把查询到的信息返回给客户端
递归查询
客户端发起一个DNS解析请求,若本地DNS服务器若不能为客户端直接解析域名,则域名服务器会代替客户端(下级服务器)向域名系统中的各分支的上下级服务器进行递归查询,直到有服务器响应回答了该请求后,将该请求结果返回客户端迭代查询
客户端(下级服务器)发起一个DNS解析请求后,若上级DNS服务器并不能直接提供该DNS的解析结果,则该上级DNS服务器会告知客户端(下级服务器)另一个可能查询到该DNS解析结果的DNS服务器IP,客户端(下级服务器)再次向这个DNS服务器发起解析请求,如此类推,直到查询到对应的结果为止
TCP三次握手,建立连接
拿到服务器IP了,就准备建立TCP连接,及建立连接后通信
解析HTML
字节序列解析出DOM、CSSOM的过程
转换到字符
从服务器拿回的数据包解包,都是UTF-8字节序列,需要转换成字符。
字节序列使用UTF-8编解码规则。请求头部的Content-Type属性可以确定请求的文件类型及编码规则,HTML文件中的<meta>标签也可以指定
构建DOM
字符分词,转换为Tokens
Tokens:一种标记,标记开始标签、结束标签、自闭合标签、元素内容等HTML中的元素状态机:可以处于不同的状态,并根据输入条件执行相应的动作来改变状态
<div>Foo</div> |
作为解码后的字符串,输入状态机,状态机会依次按照字符来分词,转换成不同类型的Token
创建Node节点,构建DOM树
- 现在开始处理
Token,分类Token后,Token中表示HTML开始标签的标记通过浏览器内部方法会创建对应的元素,之后会先入一个栈 - 创建的这个元素的属性,父节点,子节点的关系通过内部方法的临时变量来指定,子节点创建之后再赋值,父节点的子节点属性为一个引用
- 碰到闭合标签的标记,会一直
pop栈中的元素,直到遇到起始标签
PS.如果遇到自定义的标签,则会默认使用<span>标签代替
处理了所有Token后会触发DOMContentLoaded事件,这个事件标致着HTML完成解析
预加载js、css
<script>和<link>标签,都有一些属性,可以支持异步的加载
js请求、加载
<script>有两个属性,async和defer,区别如下图
图中还有type=module的情况,作为补充
区别在于执行这个下载的js脚本的时机,看阻不阻塞HTML的解析。现在的React、Vue应用多为引入一个js,框架打包好的js文件里会调用各种DOM API去创建页面的元素
css请求、加载
<link>标签可以设置一个属性值,rel="preload",prefetch苹果的Safari不支持preload要求浏览器不阻塞页面解析,但要异步下载资源。只管下载,同时要指定属性as,来表明下载的资源,比如样式表as="style"。也可以下载js脚本
布局、绘制
css解析
style标签中的样式,还有下载的样式,都会解析为CSS Tokens,和上面的HTML Token差不多
CSSOM、合成渲染树
计算出一颗和DOM树类似的节点树,这棵树的每个节点包含了Node节点的样式。之后会和DOM树合成渲染树,渲染树会根据CSS设置一些节点的可见(display: none)的节点不会出现在渲染树中
Layout节点布局计算
上面计算好的render树中的每一个节点要计算出Layout节点,这个节点包括了Node节点的所有应用在上面的布局信息
最终生成一颗Layout树,之后还要计算元素的布局信息,盒子大小位置,定位的位置,滚动区域的大小和位置以及计算层叠关系
绘制
根据每个元素的css属性,会去生成对应的绘制指令,指令集创建一个顺序列表,浏览器严格按照列表去绘制样式
之后浏览器会考虑是否分层,分层的层叠关系正是层叠上下文的关系,不同层经由光栅化(GPU参与)后会再次合成到一起供浏览器显示
重绘与回流
回流
改变了元素的布局信息,宽高窄胖上下左右,字体粗细大小排版分词等都会触发回流
为浏览器要重新计算节点布局信息,重新排列页面元素的显示
重绘
元素颜色、背景色、阴影、外边距等不影响元素布局的属性的改变,会触发浏览器重绘
PS. 根据上面的浏览器渲染的步骤可知,布局计算后面一定有绘制步骤,所以回流必定重绘
虚研社按钮网页解析的过程
这里有一些浏览器拓展的js加载,不去理会

首先解析样式表,和最初的HTML元素形成渲染树,布局,绘制(解析样式表这个部分后有很细小的两个紫色块,那个就是布局和绘制的过程)
因为没什么元素,所以很短很窄
这里是浏览器编译虚研社按钮js,后面的函数调用是react创建dom等操作,以及最后还有微任务的执行

还有支持按钮部分有很多webp的头像图片,才开始下载,之后加载。触发回流

这里是加载了一个svg的loading图标,懒加载虚研社按钮音声数据,如果用户没下滑到下面,就不发送音声信息的request,且触发了DOMContentLoaded事件
至此完成了虚研社按钮主站的显示






