当我们在浏览器输入网址后;浏览器都会做哪些事情才会让我们看见页面呢?
- 首先在客户端浏览器输入网址:www.baidu.com
- 客户端浏览器向服务器发送请求 HTTP REQUEST(省略很多细节步骤)
- 服务器端存储着百度官网项目的原代码
- 服务器收到请求后:服务器端把指定文中的代码返回给客户端 HTTP RESPONSE
一、进程/线程
一个进程中,会包含零到多个线程
1、进程 process
- 电脑端安装很多的应用软件,每当运行一个应用程序,都相当于开辟了一个进程
- 而对于浏览器来说,每新建一个页卡访问一个页面,都是新开辟一个进程
2、线程 thread
- 每一个进程当中可能还会同时做多件事情,如果同时做多件事情,则会开辟多个线程
二、浏览器常用线程
浏览器是“多线程”的,但是JS渲染或者页面渲染是“单线程”的
GUI 渲染线程
- 渲染和绘制页面
JS 引擎线程
- 运行和渲染JS代码
事件管控和触发线程
定时器管控和触发线程
异步 HTTP 请求线程
……
三、同步/异步
1、同步编程
- 单线程
- 一次只能处理一件事情,当前这件事情处理完,才能继续处理下一件事情
2、异步编程
同时可以进行好几件事情(一般是基于多线程并发完成的)
JS 中的异步编程,有自己一些特殊的处理方式
- 队列 Queue
- 事件循环 EventLoop
例题:
let n = 10;
setTimeout(() => {
n++;
console.log(n);
}, 0);
console.log(n);
for (let i = 0; i < 99999999; i++) {}
console.log(n);
复制代码
按步解析:
1、JS 是单线程的,所以在 “栈” 中,代码一定是按照顺序,自上而下依次执行的
2、代码执行过程中如果遇到一个异步的操作代码:
- 定时器(设置定时器的操作是同步的(立即设置),异步指的是间隔多久后执行指定的函数)
- 事件绑定(监听)
- AJAX的异步请求
- PROMISE/ASYNC/AWAIT
- ……
事件对列 EventQueue
- 3、当遇到定时器之后:浏览器默认开辟一个 事件队列 EventQueue
- 4、JS 代码执行过程中遇到的异步操作,都先放置到事件队列中
- 本题是把:(间隔浏览器最小反应事件内,执行对应的箭头函数),放到事件队列中
- 浏览器会单独开辟一个定时器线程:监听事件队列中存储的各个定时器的到达时间
- 只有 GUI 线程空闲下来,才会过来找
5、此时 GUI 渲染线程继续向下执行代码:输出 10
6、遇到循环:循环是同步的,代码中遇到死循环,会中断整个页面的循环或者中断代码的执行
7、继续执行同步代码:输出10
事件循环 EventLoop
- 8、栈内存中的同步任务代码都执行完了:
- 去事件队列中找到达时间的任务
- 把找到的已经到达执行条件的任务,放入到栈中执行(每次只拿回来一个)
- 还是 GUI 线程执行他
- 9、等 GUI 执行完,“闲下来”,在去事件队列中找其他到达时间的任务……一直到事件队列被执行完为止
- 这个循环查找的过程就是 EventLoop 事件循环
3、三种 CSS 样式的渲染区别
GUI 渲染页面时,当遇到其他请求时的两种处理方法:
让 GUI 线程自己去拿:
- 在CSS文件没有从服务器加载回来之前,下面的代码不会继续渲染
在开辟一个线程,专门去服务器加载CSS文件:
- 不用管CSS是否加载回来,GUI线程继续向下渲染
-1).在渲染过程中遇到 <link>
引入式样式 : 异步操作
- 浏览器会新开辟一个 HTTP 的请求线程,专门去服务器加载 CSS 样式内容
- 此时 GUI 线程还可以继续向下渲染(不用管 CSS 是否回来)
-2).如果遇到的是 @import
导入式样式 : 同步操作
- 不会开辟新的线程去加载 CSS ,而是当前线程去加载
- 这样只要 CSS 没有加载回来,下面的代码都不会继续渲染(阻碍页面渲染)
<link>
和@import
相比较:link
会提高页面渲染速度
-3).内嵌式
上面虽然说link
会提高页面渲染速度 ,但是当 CSS 代码较少的情况下,我们最好采用内嵌式(把CSS 和 HTML 写在一起),这样只要把 HTML 加载回来,CSS 也回来了
任何形式的HTTP请求都一定会有时间和性能的消耗
- 前提是CSS代码少;
- 代码多的情况下,如果还是和HTML放在一起,那么第一次请求HTML的速度都会变慢,也就得不偿失了;
四、浏览器渲染页面的步骤
1、生成 DOM 树
渲染了所有的 HTML 标签
转换
- 通过 HTTP 返还的首先是十六进制的编码字节数据
- 拿到字节数据后,浏览器会通过内部的机制,把数据转换成我们能看到的代码
令牌
- 按照
W3C
规范(第五代版本的规范H5)的规则,转换成我们能看懂的标签
- 按照
词法分析
- 通过转换后的标签,进行词法解析,生成
DOM
节点
- 通过转换后的标签,进行词法解析,生成
DOM构建
- 最后通过查找每个
DOM
节点之间的关系,生成DOM
树
- 最后通过查找每个
图片来源:图片摘自网络,如有侵权,联系删除
2、生成 CSSOM 树
请求回来 CSS 后,渲染完 CSS
同生成DOM
树一样的过程生成CSSOM
树
图片来源:图片摘自网络,如有侵权,联系删除
3、DOM 树 + CSSOM 树 => RENDER-TREE(渲染树)
图片来源:图片摘自网络,如有侵权,联系删除
4、 布局(Layout)或 重排/回流(reflow)
按照
RENDER-TREE
在设备的视口中进行结构和位置的相关计算=>布局(Layout)或 重排/回流(reflow)
5、绘制(painting)或 栅格化(rasterizing)
根据渲染树以及回流得到的几何信息,得到节点的绝对像素=>绘制(painting)或 栅格化(rasterizing)
思维导图
关