从浏览器地址栏输入url到页面展示都发生了啥?
高频面试题
:从浏览器地址栏输入url到页面展示都发生了啥?
以往当我们从浏览器输入框输入https://juejin.cn/
的时候,回车,然后就会展示干货满满的文章,那么,从输入链接到展示文章的过程中究竟发生了啥,有这样的疑问的话,就接着往下看。
可以把从输入链接到展示页面的中间过程看做一个黑盒子,这个黑盒子里就是浏览器。
先看盒子里都有啥?
- 浏览器进程:主要负责界面显示、用户交互、子进程管理,同时提供存储等功能
- 渲染进程:核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下
- GPU进程:GPU 的使用初衷是为了实现 3D CSS 的效果,随后网页、Chrome 的 UI 界面都选择采用 GPU 来绘制
- 网络进程。主要负责页面的网络资源加载
- 插件进程。主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响。
进程又是啥?
一个进程
就是一个程序的运行实例。启动一个程序的时候,操作系统会为该程序创建一块内存,用来存放代码、运行中的数据和一个执行任务的主线程,我们把这样的一个运行环境叫进程。
- 进程中的任意一线程执行出错,都会导致整个进程的崩溃
- 线程之间共享进程中的数据
- 当一个进程关闭之后,操作系统会回收进程所占用的内存
- 进程之间的内容相互隔离,进程间数据通信需要(IPC)机制
线程又是啥?
线程
是进程中的实际运行单位,是不能独立存在的,它是由进程来管理和启动的。
到这里就该开始正题了,从浏览器地址栏输入url到页面展示都发生了啥?
一、处理用户输入的字符串
主要进程:浏览器进程
- 如果用户输入的符合URL规则
比如在地址栏输入
https://juejin.cn/
,地址栏为:
二、和后端建立请求通道
主要进程:网络进程
浏览器通过IPC将url
发送给网络进程,网络进程进行真实的网络请求。
首先,判断本地是否有缓存,如果有的话,直接使用本地缓存。
否则,进行DNS查询,获取当前域名对应的真实的IP地址。
拿到真实的IP地址以后,会通过三次握手和服务器进行TCP的连接。然后,构建请求信息向后端发送请求。
服务端会返回两种主要的信息:
- 状态码status:当服务器返回301(永久重定向)和302(暂时重定向)时,客户端浏览器会从Location中读取需要重定向的链接,重新进行请求流程。
- 文件类型content-type: 当服务器返回的是application/octet-stream时,客户端浏览器会进行文件的下载,请求结束;如果返回的是text/html,浏览器认为是页面资源,会进行渲染流程。
三、渲染进程接受资源
主要进程:渲染进程
首先有个问题,需要开几个渲染进程?
如果
:新打开的页面和之前的页面属于同一站点(相同的协议,相同的域名)
,那么新页面会使用之前页面的渲染进程。
否则
:会新建一个新的渲染进程,作为新打开页面的渲染进程。
当网络进程获取到响应头信息后,它会告诉浏览器进程,浏览器进程又会通过IPC通知渲染进程,渲染进程打开通道,让网络进程中的数据源源不断的传递过来,结束时告诉浏览器进程。
浏览器接到通知后,会更新浏览器界面状态,包括地址栏的URL安全锁、前进后退状态等信息。
这时,浏览器的渲染进程就拿到了网络资源
,类似于工厂的生产车间拿到了原材料
,开始网络资源的加工处理
。
四、渲染场景
1、构建DOM树
浏览器无法直接解析服务端拿到的html资源,首先需要将其转换为浏览器可识别,并且可编辑的DOM树。DOM树是用来描述html资源的结构,以document作为根节点,根据嵌套结构构建真实的树。
假设html资源为:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<h3>title</h3>
<p>phrase</p>
</div>
</body>
</html>
当在浏览器控制台输入document的时候,就获取到了当前的DOM树:
2、样式计算
(1)将样式转换成浏览器认识的结构
在日常开发过程中,浏览器的样式可以通过link
文件引入、在头部的style
标签中定义或者通过内联的style
标签写入,但是这些方式浏览器是不能直接识别或者操作的,那么,浏览器就会先将其转换成styleSheets
的形式。该形式可以通过JavaScript
中提供的方法进行获取和操作。
(2)将其中的快捷样式进行处理
我们发现其中还存在bolder、1rem和green这样的样式值。这里浏览器还需要将其进行computed
的处理,其最终的值可以在开发工具中查看:
(3)根据继承和层叠关系计算各个节点样式
DOM树是树结构,父节点上定义的样式会被子节点继承,当然子节点也可以重写该样式。
DOM树又可以通过脱离文档流的方式对其进行层叠处理。
3、布局树
会通过遍历DOM树,将其中可见的部分添加到布局树上。
4、分层
真实的页面最终会像PS的图层结构一样,是由多张图层构成的。
新图层的产生会有以下两种情况:
- 层叠上下文
- 需要裁减的部分
<style>
div {
position: relative;
font-size: 12px;
color: gray;
background-color: aqua;
}
h3 {
position: absolute;
width: 80px;
height: 200px;
border: 1px solid red;
font-weight: bolder;
font-size: 1rem;
color: green;
z-index: 1;
background-color: bisque;
}
p {
width: 100px;
height: 300px;
border: 1px solid red;
transform: translateZ(10px);
background-color: blueviolet;
}
</style>
分层结果为:
可以看出,div,h3和p通过position以及css3的新属性transform,将其分为3层。
5、图层绘制
图层的绘制是由很多拆分的过程来完成了,就好比一个复杂的图形,拆分的最后都是点,线,圆,三角形,四边形等基础图形构成的。图层的绘制,也是类似的方式拆分绘制的,可以通过Layers层中的Profiler功能模块查看。其中包含了很多图层元素绘制的指令列表:
6、栅格化操作
之前的渲染操作都在渲染主线程上执行。
接下来图层中具体内容的渲染交给合成线程。
合成线程又将图层划分为一个个的图块,如果一张很长的图层,会优先渲染离终端窗口比较近的图块,图块的绘制就交给格栅化线程。
格栅化又将图块的渲染交给GPU线程,由其加速完成,并保存到GPU的内存中。
7、显示
格栅化完成以后,合成线程会告诉浏览器。
浏览器将其内存中的图,展示到浏览器中。
至此,拿到的html、css和js资源就被展示到了用户面前。
同时,浏览器会将标签图标位置上的加载动画更换成实际的标签图标。
总结
从浏览器地址栏输入url到页面展示,主要是拿到资源,然后在浏览器这个工厂中将拿到的资源进行加工处理,最后呈现出完成的产品,也就是用户浏览到的页面。
写在最后
如文中有纰漏,请贵手留言 如对你有帮助,请点赞收藏
转载自:https://juejin.cn/post/7167673894269599752