进程(Process) VS 线程(thread)
- 进程是操作系进行统资源分配的基本单位
- 线程是处理器任务调度和执行的基本单位
- 进程是线程的容器
- 线程是不能单独存在的,它是由进程来启动和管理的
- 一个进程就是一个程序的运行实例
- 线程是依附于进程的,而进程中使用多线程并行处理能提升运算效率
进程和线程的4个特点:
- 进程中任意一线程序执行出错,就会导致整个进程的崩溃
- 线程之间共享进程中的数据
- 当一个进程关闭之后,操作系统会回收进程所占用的内存
- 进程之间的内容相互隔离,互不影响
一、URL解析
在浏览器地址栏输入 url
后,浏览器会判断这个 url 的合法性
以及是否有 可用缓存
,如果判断是 url
,浏览器进程会将 url
发送给网络进程,发起 url
请求,如果不是 url
,则直接使用 搜索引擎搜索
二、浏览器缓存
发起 url
请求之前,还会尝试去命中 缓存
,首先是命中 强缓存,会依次从 service worker、内存、硬盘、push cache里读取缓存,如果有命中就不发起请求,没有命中则正常发起请求,进行 DNS域名解析
三、域名解析
进行 DNS域名解析
,如果输入的是 ip 地址
,则 可以省略这一步
,因为 DNS域名解析,就是把域名解析成 ip 地址
,找到对应的主机
域名系统(DNS):
域名系统
是互联网的一项服务,是一个将域名
和ip 地址
相互映射的分布式数据库
机器只能识别 ip地址
,但是对于使用者来说,ip 地址
是不容易被记忆的,为了能够让人们更轻松的记住网站地址,于是就有了 域名系统
,每一个域名
都有一个对应的 ip 地址
四、建立 TCP 连接
发起 HTTP 请求
,如果协议是 HTTPS
,还需要建立 TLS 连接
,发起 HTTP 请求
之前需要建立 TCP连接
,这一步就是我们常说的 三次握手 与 四次挥手,三次握手确保双方通信的可靠性之后发起 HTTP 请求
,这个时候会尝试去命中 协商缓存,如果没命中发送 HTTP 请求行
、请求头
、请求体
,等待服务端处理并响应,浏览器拿到资源后 四次挥手
断开 TCP 连接
,如果有开启 Connection: keep-alive
可保持 TCP 连接
,浏览器进入 页面渲染阶段
五、页面渲染
最后一步就是页面渲染了,这是一个很复杂的过程
1. 解析 HTML,并搭建 DOM 树
浏览器接收到 html 文件
后将其解析成 DOM 树
,这个解析从接收到 html 文件
的时候就已经开始了,并不是等到接收完成后才开始,解析的过程是 自上而下
,先解析当前节点的所有子节点,再解析兄弟节点及其子节点
2. 解析 CSS,并搭建 CSS 规则树(CSS Rules tree)
浏览器将所有的 CSS
包括其自身的样式全部解析成规则树,解析的过程中会自动去掉浏览器不能识别的样式,说个额外的,CSS Rules tree
和 CSSOM
的关系:CSSOM
是 CSS Rules tree
的一个节点,CSS Rules tree
和 CSSOM tree
是完全相等的
3. 将 HTML 和 CSS 结合,搭建 Render 树(渲染树)
将每个 HTML 节点
与其对应的 CSS 样式
结合,搭建 Render 树
4. 根据渲染树计算布局
根据已经生成好的 Render 树
,计算每个节点的颜色、尺寸及位置等信息
5. 将元素绘制到页面上
将计算好的节点绘制到页面上,这个过程可能会产生 重绘 和 回流,要尽量避免回流
重绘: 因为元素的颜色,字体等不改变尺寸及位置的样式改变而重新绘制,性能消耗较小
回流: 因为元素的尺寸或位置改变而导致的重新绘制,这种可能会导致多处元素重新绘制,性能消耗较大
注意:
- 1、
CSS
不会阻塞DOM 树
的搭建,但是会阻塞页面的渲染
,这是因为页面渲染需要先计算好节点的样式 - 2、
HTML 文件中
的外部资源会提前加载,不会等到渲染完成后再加载 - 3、
JS
会阻塞HTML
的解析,因为浏览器不知道JS 脚本
的内容,但JS
脚本有可能会操作DOM
,为了避免重复渲染,浏览器会先加载JS 脚本
- 4、
CSS
会阻塞JS
的执行,因此需要将<script>
标签放在<link>
标签之前