## 从浏览器接收url到开启网络请求线程
### 进程和线程
首先明确一下进程和线程的概念 :
- 进程是cpu资源分配的最小单位(是能拥有资源和独立运行的最小单位)
- 线程是cpu调度的最小单位(线程是建立在进程的基础上的一次程序运行单位,一个进程中可以有多个线程)
### 多进程的浏览器
首先需要知道,浏览器是一个多进程的应用程序,它有一个主控进程,以及每一个tab页面都会新开一个进程(某些情况下多个tab会合并进程),除此之外,可能还包括插件进程,GPU,浏览器内核等等。
看下面一个图:
:-: ![](http://xiaoyulive.oss-cn-beijing.aliyuncs.com/%E6%88%AA%E5%9B%BE/QQ%E6%88%AA%E5%9B%BE20180316100833.png)
:-: ![](http://xiaoyulive.oss-cn-beijing.aliyuncs.com/%E6%88%AA%E5%9B%BE/QQ%E6%88%AA%E5%9B%BE20180316101008.png)
我打开了 Chrome 浏览器,在任务管理器中可以看到,实际上浏览器创建了多个进程。
#### 浏览器都包含哪些进程?
知道了浏览器是多进程后,再来看看它到底包含哪些进程:(为了简化理解,仅列举主要进程)
1. **Browser进程**:浏览器的主进程(负责协调、主控),只有一个。作用有
- 负责浏览器界面显示,与用户交互。如前进,后退等
- 负责各个页面的管理,创建和销毁其他进程
- 将Renderer进程得到的内存中的Bitmap,绘制到用户界面上
- 网络资源的管理,下载等
2. **第三方插件进程**:每种类型的插件对应一个进程,仅当使用该插件时才创建
3. **GPU进程**:最多一个,用于3D绘制等
4. **浏览器渲染进程**(浏览器内核)(Renderer进程,内部是多线程的):默认每个Tab页面一个进程(有时候会优化,如多个空白tab会合并成一个进程),互不影响。主要作用为 控制页面渲染,脚本执行,事件处理 等
可以通过 Chrome 的 更多工具 -> 任务管理器 验证 :
:-: ![](http://xiaoyulive.oss-cn-beijing.aliyuncs.com/%E6%88%AA%E5%9B%BE/QQ%E6%88%AA%E5%9B%BE20180316103315.png)
#### 浏览器多进程的优势
相比于单进程浏览器,多进程有如下优点:
- 避免单个page crash影响整个浏览器
- 避免第三方插件crash影响整个浏览器
- 多进程充分利用多核优势
- 方便使用沙盒模型隔离插件等进程,提高浏览器稳定性
简单点理解:**如果浏览器是单进程,那么某个Tab页崩溃了,就影响了整个浏览器,体验有多差;同理如果是单进程,插件崩溃了也会影响整个浏览器。**
当然,内存等资源消耗也会更大,有点空间换时间的意思。
#### 而至于多核多线程 CPU ?
在配置电脑的时候,我们经常会谈到 CPU 有多少核心,每个核心多少个线程,而浏览器同时开启如此多的进程,每个进程又开启那么多的线程,从数量上看,CPU 似乎不能负荷那么多,但实际上,CPU 是使用时间片进行分时处理,由于切分的时间间隔特别的短,作为我们普通人根本感觉不到,因此感觉到所有程序都是并行处理的,实际上,比如 4核心双线程的 CUP 同时最多只能进行 8 个工作的处理,但由于时间片切分的时间特别短,以至于我们感觉所有程序都是并行处理的。
### 多线程的浏览器内核
每一个tab页面可以看作是浏览器内核进程,然后这个进程是多线程的,它有几大类子线程
- GUI 线程
- JS 引擎线程
- 事件触发线程
- 定时器线程
- 网络请求线程
:-: ![](http://xiaoyulive.oss-cn-beijing.aliyuncs.com/imgs/browser_inner_thread.png)
可以看到,里面的JS引擎是内核进程中的一个线程,这也是为什么常说JS引擎是单线程的。
可以这样简单的理解: 浏览器每一个进程就是一个大工厂,而进程中的每一个线程就是工厂里面干活的各种工人。
#### 重点是浏览器内核(渲染进程)
重点来了,我们可以看到,上面提到了这么多的进程,那么,对于普通的前端操作来说,最终要的是什么呢?答案是**渲染进程**
可以这样理解,页面的渲染,JS的执行,事件的循环,都在这个进程内进行。接下来重点分析这个进程
**请牢记,浏览器的渲染进程是多线程的**
终于到了线程这个概念了😭,好亲切。那么接下来看看它都包含了哪些线程(列举一些主要常驻线程):
1. GUI渲染线程
- 负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
- 当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行
- 注意,**GUI渲染线程与JS引擎线程是互斥的**,当JS引擎执行时GUI线程会被挂起(相当于被冻结了),GUI更新会被保存在一个队列中**等到JS引擎空闲时**立即被执行。
2. JS引擎线程
- 也称为JS内核,负责处理Javascript脚本程序。(例如V8引擎)
- JS引擎线程负责解析Javascript脚本,运行代码。
- JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序
- 同样注意,**GUI渲染线程与JS引擎线程是互斥的**,所以如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。
3. 事件触发线程
- 归属于浏览器而不是JS引擎,用来控制事件循环(可以理解,JS引擎自己都忙不过来,需要浏览器另开线程协助)
- 当JS引擎执行代码块如setTimeOut时(也可来自浏览器内核的其他线程,如鼠标点击、AJAX异步请求等),会将对应任务添加到事件线程中
- 当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理
- 注意,由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)
4. 定时触发器线程
- 传说中的`setInterval`与`setTimeout`所在线程
- 浏览器定时计数器并不是由JavaScript引擎计数的,(因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确)
- 因此通过单独线程来计时并触发定时(计时完毕后,添加到事件队列中,等待JS引擎空闲后执行)
- 注意,W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms。
5. 异步http请求线程
- 在XMLHttpRequest在连接后是通过浏览器新开一个线程请求
- 将检测到状态变更时,如果设置有回调函数,异步线程就**产生状态变更事件**,将这个回调再放入事件队列中。再由JavaScript引擎执行。
### 解析URL
输入URL 后,浏览器会进行解析(URL的本质就是统一资源定位符)
URL一般包括几大部分:
- `protocol`,协议头,譬如有http,ftp等
- `host`,主机域名或IP地址
- `port`,端口号
- `path`,目录路径
- `query`,即查询参数
- `fragment`,即`#`后的hash值,一般用来定位到某个位置
### 网络请求都是单独的线程
每次网络请求时都需要开辟单独的线程进行,譬如如果URL解析到http协议,就会新建一个网络线程去处理资源下载
因此浏览器会根据解析出得协议,开辟一个网络线程,前往请求资源。
- Web 开发笔记
- 从输入 URL 到页面加载完成的过程中都发生了什么事情?
- 从浏览器接收url到开启网络请求线程
- 开启网络线程到发出一个完整的http请求
- 从服务器接收到请求到对应后台接收到请求
- 后台和前台的http交互
- http的缓存
- 解析页面流程
- HTML解析,构建DOM
- CSS解析,构建CSSOM
- 资源外链的下载
- CSS的可视化格式模型
- 包含块(Containing Block)
- 控制框(Controlling Box)
- BFC(Block Formatting Context)
- IFC(Inline Formatting Context)
- 其它
- JS引擎解析过程
- JS的解释阶段
- JS的预处理阶段
- JS的执行阶段
- 回收机制
- 参考资料
- JavaScript模块化编程
- AMD
- requireJS
- CommonJS
- UMD
- ES6模块
- 参考资料
- 使用 JavaScript 实现一门编程语言
- 如何使用 JavaScript 实现一门编程语言(1) —— 前言
- 如何使用 JavaScript 实现一门编程语言(2) —— 编写一个解析器
- 如何使用 JavaScript 实现一门编程语言(3) —— Input stream
- 如何使用 JavaScript 实现一门编程语言(4) —— Token stream
- 如何使用 JavaScript 实现一门编程语言(5) —— AST
- 如何使用 JavaScript 实现一门编程语言(6) —— Interpreter
- 完整代码
- 参考资料
- 前端布局概论
- 参考资料
- Windows 笔记
- 错误解决
- win10应用商店无法登录提示0x80070426解决方法
- 使用技巧
- 设置 Hyper-V 和 VMware 共存
- Powershell
- WSL