在从事前端开发过程中,浏览器作为最重要的开发环境,浏览器基础是前端开发人员必须掌握的基础知识点,它贯穿着前端的整个网络体系。对浏览器原理的了解,决定着编写前端代码性能的上限。一起学习下谷歌浏览器的架构知识。
谷歌浏览器运行时的四个主要进程
# 浏览器进程
Controls "chrome" part of the application including address bar, bookmarks, back and forward buttons. Also handles the invisible, privileged parts of a web browser such as network requests and file access
(控制地址栏、书签前进后退按钮,标签页创建/销毁、页面显示、网络请求、资源管理下载)
GUI 渲染线程
- HTML Parser 解析HTML文档,将元素转换为树结构DOM节点
- CSS Parser 解析Style数据,包括外部的CSS文件以及在HTML元素中的样式,用于创建渲染树
- Layout 为每个节点计算出在屏幕中展示的准确坐标
- Painting 遍历渲染树,调用UI Backend提供的接口绘制每个节点
JavaScript 引擎线程
- 解析Javascript脚本,运行代码 JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序
- GUI渲染线程与JS引擎线程互斥
- 由于JavaScript是可操纵DOM的,如果在修改这些元素属性同时渲染界面(即JS线程和GUI线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。为了防止渲染出现不可预期的结果,浏览器设置GUI渲染线程与JS引擎为互斥的关系,当JS引擎执行时GUI线程会被挂起,GUI更新则会被保存在一个队列中等到JS引擎线程空闲时立即被执行
定时触发器线程
- setInterval与setTimeout所在线程
- 定时计数器并不是由 JavaScript 引擎计数的(因为 JavaScript 引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确, 因此通过单独线程来计时并触发定时更为合理)
- W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms
事件触发线程
- 归属于浏览器而不是JS引擎,用来控制事件循环
- 一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待 JavaScript 引擎的处理。
- 这些事件可以是当前执行的代码块如定时任务(也可来自浏览器内核的其他线程如鼠标点击、AJAX 异步请求等),会将对应任务添加到事件线程中
- 由于 JavaScript 的单线程关系所有这些事件都得排队等待 JavaScript 引擎处理。
http 异步请求线程
- XMLHttpRequest 在连接后是通过浏览器新开一个线程请求, 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件放到 JavaScript 引擎的处理队列中等待处理
# GPU进程
Handles GPU tasks in isolation from other processes. It is separated into different process because GPUs handles requests from multiple apps and draw them in the same surface
(处理来自其他进程的GPU任务。它被分为不同的进程,因为gpu处理来自多个应用程序的请求,并将它们绘制在同一个表面上)
# 第三方插件进程
Controls any plugins used by the website, for example, flash. 控制网站使用的任何插件,每个插件对应一个进程,当插件运行时创建
# 渲染进程(浏览器内核)
Controls anything inside of the tab where a website is displayed. 控制显示网站的选项卡内的任何内容,默认每个标签页创建一个渲染引擎实例