浏览器部分探索

1. 浏览器现在的普及情况

使用上选择最多的是chrome浏览器,第二是safari以及Firfox。谷歌浏览器超过了六成。下边的这个图是来自 https://gs.statcounter.com/ 的统计。

在这里插入图片描述

浏览器内核

上边说到的三种使用最多的浏览器中,chrome之前使用的是webkit,后来更换为了Blink。safari使用的是webkit(自家的),firfox使用的是Gecko,是Mozilla自己开发的内核。IE使用的是Trident内核(微软的).


2. 浏览器的结构

用户界面: 使用浏览器的时候在页面中呈现出来的东西

浏览器引擎:工具人,用来将用户和浏览器的呈现引擎进行关联的部分

呈现引擎:最主要干活儿的,用来解析HTML以及CSS

网络: 工具人,用来和服务端进行交互的部分

用户界面后端: 绘制基本的窗口小部件,比如组合框和窗口。

JavaScript 解释器: 解析和执行 JavaScript 代码。

数据存储: 浏览器需要在硬盘上保存各种数据


3. 浏览器包含的进程

浏览器是多进程的,浏览器的渲染进程是多线程的;

1> browser进程(一个进程):浏览器的主进程,主要是用来控制界面展示,页面的管理、渲染进程中的内容绘制到用户界面上。
2>浏览器渲染进程(浏览器内核)(Render进程,内部是多线程的):默认每个Tab页面一个进程,互不影响。主要作用为:页面渲染,脚本执行,事件处理等
3> GPU进程(一个进程):用于3D绘制等
4> 第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建

几个进程中最重要的就是浏览器渲染进程,也就是内核进程,内核进程中又会存在多个线程。

  • GUI渲染线程

负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
当界面需要重绘或由于某种操作引发回流时,该线程就会执行。
注意,GUI渲染线程与JS引擎线程是互斥的,当JS引擎执行时GUI线程会被挂起(相当于冻结了),GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。

  • JS引擎线程

也称为JS内核,负责处理JavaScript脚本程序。(例如V8引擎)。
JS引擎线程负责解析JavaScript脚本,运行代码。
JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页(render进程)中无论什么时候都只有一个JS线程在运行JS程序。
同样注意,GUI渲染线程与JS引擎线程是互斥的,所以如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞。(卡顿,无法进行操作的情况)

  • 事件触发线程

归属于浏览器而不是JS引擎,用来控制事件循环(可以理解成JS引擎自己都忙不过来,需要浏览器另开线程协助)。
当JS引擎执行代码块如setTimeout时(也可来自浏览器内核的其它线程,如鼠标点击,AJAX异步请求等),会将对应任务添加到事件线程中。
当对应的事件符合触发条件被触发时,该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。
注意,由于JS的单线程关系,所以这些待处理队列中的事件都得排队等待JS引擎处理(当JS引擎空闲时才会去执行)。

  • 定时触发器线程

传说中的setTimeout和setInterval所在的线程
浏览器定时计数器并不是由JavaScript引擎计数的,(因为JavaScript引擎是单线程的,如果处于阻塞线程状态就会影响计时的准确)
因此通过单独线程来计时并触发定时(计时完毕后,添加到事件队列中,等待JS引擎空闲后执行)
注意,W3C在HTML标准中规定,规定要求setTimeout中低于4ms的时间间隔算为4ms。(也就是说setTimeout最小执行时间为4ms)

  • 异步http请求线程

在XMLHttpRequest在连接后是通过浏览器新型一个线程请求
将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件队列中,再由JavaScript引擎执行


4. 从用户输入到页面可操作整体过程

1> 用户在地址栏输入后,先判断用户输入的是URL还是查询
2> 控制tab页显示正在加载中的页面,同时进行网络请求。(此处进行网络请求的时候是多线程的方式进行处理)

网络线程开始解析域名进行DNS查询,发起TCP三次握手
建立TCP连接,然后发起HTTP请求
服务器响应HTTP请求,浏览器获得HTML代码

3> 浏览器开始解析HTML代码(GUI渲染线程,单线程进行处理)

整个解析经过: 源码 —经过解析—> 解析树 —经过翻译—> 机器代码 (其中涉及到一些编译原理的东西)

HTML解析是有对应的对应的算法 https://html.spec.whatwg.org/multipage/syntax.html#html-parser
浏览器在处理HTML的时候是有对应的容错机制的,这个是没有对应规范的,是浏览器发展多年的产物。
在构建dom树的过程中,如果遇到了样式表或者js文件,这个时候会进行下载对应文件
如果在构建的过程中遇到了 <script>标签,这个时候就会停止解析,等待js解析程序解析js代码执行完成后再继续。
HTML解析之后的树称为dom树(dom tree)

4> 浏览器开始解析CSS代码(GUI渲染线程)

样式表解析的时候也要使用编译原理中的内容进行解析,解析完成后称为样式结构体(CSSOM)
同样,CSS也有对应的解析规范 https://www.w3.org/TR/CSS2/grammar.html

5> 处理HTML和CSS解析结果(GUI渲染线程)

dom tree 和 CSSOM tree 进行结合后的产物称为呈现树(render tree),渲染树包含多个带有样式属性的矩形,这些矩形的排列顺讯就是它们在屏幕上显示的顺序。

6> 计算布局(GUI渲染线程)

浏览器根据解析出的render tree进行绘制页面,开始进行布局,从render tree的根结点开始对每个元素的大小位置进行遍历,计算出每个元素所在屏幕的位置。这步处理之后的结果称为布局树。

7> 生成图层树(GUI渲染线程)

这个时候还需要对不同复杂的效果进行处理,生成对应的图层树。
每个布局树的节点都会有自己的图层树节点,如果一个节点没有对应的层,那它就属于父节点的图层节点,

8> 绘制指令列表

有了图层树之后,由GUI渲染的主线程进行绘制,生成绘制指令列表。
每个指令其实就是相当于一个操作。

9> 栅格化处理

栅格化处理:因为浏览器的显示部分是有限的,如果图层过大的时候,渲染进程不会将所有的图层进行显示,所以就将图层分为了一个一个的图块
将所有的图块一个一个的转化成位图。

10> 合成化与显示

当经过栅格化处理之后,合成线程会收集所有的位图信息创建合成帧,将消息传给浏览器主进程进行显示。


阻塞浏览器渲染的原因:

1> CSS阻止页面渲染

因为dom tree 和 cssom tree 结合之后才会变成render tree,所以如果cssom在构建完毕之前,并不会出现render tree。
解决办法自行搜索 link的 media属性

2> js阻止页面渲染

这个就是比较常见的问题,都知道js不能写在文档的靠上位置,根本原因是js可能会改变dom tree和cssom的构建,所以浏览器遇到script的时候会停止dom tree的渲染。
解决办法自行搜索script标签的 async 和 defer属性。

回流和重绘的部分推荐看下边俩篇文章:

https://blog.csdn.net/jnshu_it/article/details/77367282

https://blog.csdn.net/xingsilong/article/details/80624765

浏览器性能数据

浏览器的性能数据都被记载到了window.performance接口中

其中包含以下几个部分:
1> Performance.navigation(标准的接口)返回的是页面相关属性,例如重定向次数,刷新,加载信息等
2> Performance.timing (标准的接口)返回页面整个加载过程的数据,例如建立DNS解析时间,dom渲染时间等
3> Performance.memory(非标准的接口,是chrome添加的一个扩展)返回的是浏览器的内存情况

在这里插入图片描述

其中比较重要的部分是Performance.timing 这个接口,从这个接口中就可以看出页面整个过程的性能瓶颈。

DOMLoading:这是整个过程的起始时间戳,浏览器即将开始解析第一批收到的 HTML 文档字节。
DOMInteractive:表示浏览器完成对所有 HTML 的解析并且 DOM 构建完成的时间点。
DOMContentLoaded:表示 DOM 准备就绪并且没有 CSS 阻止 JavaScript 执行的时间点,这意味着现在我们可以构建渲染树了。
DOMComplete:顾名思义,所有处理完成,并且网页上的所有资源(图像等)都已下载完毕,也就是说,加载转环已停止旋转。
loadEvent:作为每个网页加载的最后一步,浏览器会触发 onload 事件,以便触发额外的应用逻辑。


参考文章:
一次完整的浏览器请求过程: https://blog.csdn.net/qq_39125445/article/details/88428626
浏览器工作原理 https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/
浏览器渲染过程及JS引擎浅析 https://www.clloz.com/programming/front-end/js/2019/04/25/how-browser-work/
浏览器渲染中发生的事 https://zhuanlan.zhihu.com/p/36700206
史上最全!图解浏览器的工作原理 https://www.infoq.cn/article/CS9-WZQlNR5h05HHDo1b
探寻浏览器渲染的秘密 https://juejin.im/post/5d77c2fce51d453b7779d5c8
浏览器渲染机制 https://segmentfault.com/a/1190000014018604

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值