浏览器工作基本原理入门

155 阅读8分钟

推荐文章

How browsers work

前置信息

一道面试题叫当你把google.com打进goolgle到页面呈现中间经历了什么

进程与线程

计算机的核心是CPU,CPU同一时间只能运行一个进程,一个进程下面可以有多个线程共享进程的内存资源,被进程使用;内存空间有限且非连续(即内存空间有大有小),所以以信号量semaphore来保证进程不发生冲突,例如读写操作设置互斥锁mutex(即信号量n=1)

当启动一个应用程序时,就启动了一个进程,一个进程可以向操作系统申请其他进程帮忙干点活

链接:阮一峰有趣的图解线程与进程

浏览器工作原理粗解

常见浏览器

浏览器名称是否开源搜索引擎
IE--
ChromeWebkit
FirefoxGecko(Mozilla自制,对css处理做了很多优化)
Safari部分开源Webkit
Opera----

链接: 全球统计网站

浏览器的主要功能

主要功能:向服务器发送请求,在浏览器窗口中展示你要的网络资源。资源一般是HTML文档,也可是PDF(// 安装相关插件或扩展程序才能展示)等。资源位置由URL(统一资源标识符)指定。

浏览器的主要组件

PgPX6ZMyKSwF6kB8zIhB.png

  • 浏览器里除了顶部tab,其他部分都是User Interface

  • Browser engine是Chrome的主进程,负责调度指挥,Chrome为每一个tab页都创建Rendering engine实例,每个tab都是独立的进程;但其他大部分浏览器 rendering engine是主进程

  • rendering engine负责按照W3C标准解析和渲染HTML和CSS

  • Networking、JS Interpreter、UI Backend是底层实现,其接口是与平台无关的通用接口。

    • UI Backend负责绘制窗口小部件
    • JS Interpreter负责解析和执行JS
  • Data Persistence是持久层,将数据保存到硬盘上,如Cookie

Chrome浏览器

Chrome是使用IPC通信的多线程应用,如下图1,其中Browser Process是主进程,如下图2

v2-f04b3c3b86e76c1f63679d6a93191251_720w.jpg

v2-9256f1e2815577a7ef407c39e3239be6_720w.jpg

面试问题解答:当用户在地址栏输入内容时UI thread会判断用户输入,然后通知network thread获取相关资源同时spinner;network thread拿到资源后读取响应头,如果是HTML则通知UI thread, UI thread通知renderer process渲染(network thread会把数据给renderer process);在这个过程中,Browser process会给renderer process发送IPC消息,确认导航。一旦Browser Process收到确认渲染消息,导航过程结束(spinner结束),页面开始加载。此时地址栏会更新,history tab也会更新。以上是页面首帧渲染完成

导航的过程做了什么

导航是加载web页面的第一步,导航的第一步是寻找页面资源的位置,例如查找example.com,如果地址被访问过,就在本地缓存里;如果没有被访问过,就要进行DNS查找拿到服务器的ip地址;拿到地址后,与服务器进行TCP handshake(SYN, SYN-ACK, ACK)建立链接,尝试通信;为了在https上建立安全链接,还要进行tls协商(不是很清楚,问就是不知道);建立连接之后,浏览器就代表用户发送一个初始的http get请求,初始请求的响应所接收数据的第一个字节,通常是14kb,然后是TCP慢开始详细内容看《计算机网络》 七层网络协议之类的吧

rendering engine

rendering engine上来会从网络层请求文档内容,内容大小一般在5KB~100KB; // 所以一份文件不要写太大哦,对浏览器不友好;但也不要随意的产生文件,毕竟每份文件都是需要网络请求的,花费响应时间呢

rendering engine的主流程示例

webkit主流程

S9TJhnMX1cu1vrYuQRqM.png

Gecko主流程(我不看,不想看)

Tbif2mUJCUVyPdyXntZk.jpg

Webkit和Gecko整体流程相似,只是几个术语不同:Gecko将视觉格式化的树成为Frame tree,Webkit叫render tree;Gecko将元素的放置叫reflow(重排),Webkit叫layout(布局)等

该流程是一个渐进的过程,边翻译边绘制

解析

解析是一个迭代的过程。解析器在词法分析器里拿一个新标记(token)就去匹配语法规则,匹配到了就放入解析树对应位置,没匹配到就存储起来,直至全部匹配完成。如果此时还有标记没有匹配对应规则,则报语法错误。

解析器与自动生成解析器

写解析器很累,所以将规则传给解析器生成器让它生成解析器。常规的解析器都是与上下文无关的(通用解析器),css和js、xml可以用。但是HTML与上下文有关,因为我们对HTML很宽容,提供了很多容错处理,这就导致解析起来很困难。 // 所以语言一旦对开发者宽容,就提高了处理它的难度

当然,HTML难解析的原因不仅是因为语言本身的宽容和浏览器对常见无效HTML的包容,也有解析过程中需要反复的原因,比如脚本标记包含document.write就会添加额外标记。// 所以我们写代码的时候就非必要就不在脚本里修改节点了,累死浏览器,所以这和框架的虚拟dom有没有关系呢?待了解

HTML解析器:浏览器自定义解析器,包括标记化和树构建(节点 插入模式)
标记化

52SA8fqorIKP6h22JHUR.png

DOM树构建

image-20230104205724982.png

  • HTML解析完成后,浏览器会将文档标注为交互状态,开始解析deferred脚本。然后,文档状态设置为完成,同时触发加载事件

  • 处理脚本和样式表的顺序

    脚本同步解析,如果需要网络请求,也得等着。如果是defer,就留文档解析完了再解析。HTML5还提供异步标记,由其他线程解析和执行

    预解析(优化):在脚本执行时,其他线程解析文档的其余部分,找出需要网络加载的并加载回来

    样式表:原则上讲,样式表不会更改DOM树,所以没必要等。但js会操作样式表拿取元素,所以得等

  • render 树构建( 略) 主要在处理css,以及css和dom树得关系

布局

render tree不包含位置和大小信息,这些值要计算得到,在布局的时候使用坐标系来计算;坐标系是相对根建立的,使用左上坐标;根render器的左边是(0,0),大小是视口(浏览器窗口可见区域大小);布局是一个递归的过程,每个render都有layout方法,每个render都会调用要布局的孩子的layout

HTML采用流式布局,从左到右,从上到下,正常来说只要遍历一遍就ok了。但也有例外,比如表格的计算就需要不只一遍的遍历// 所以说,少用表格,超过三层的表格爬虫也抓不到

标记和dom树节点是一一对应的,但dom树和render可不是一一对应的。dom树根节点是document,节点由dom api + 浏览器内部属性构成

全局布局与增量布局

  • 增量布局一般是异步的

    当某个render变了,会将它和它的子代标注为dirty;webkit执行计时器,对render tree遍历并对里面的dirty render重新布局,Gecko将增量布局的reflow命令加入队列,调度程序会触发这些指令批量执行

    请求样式信息,如offsetHeight的加本会触发同步增量布局

  • 全局布局是同步的,如全局样式修改,屏幕大小变动

    优化:如果是大小调整或者大小不变位置调整,一般会读缓存,不去重新计算

布局模式

父render确定自己的宽度,然后遍历孩子,确定孩子位置,最后得到自己的高度

css框模型--针对文档树生成,根据可视化格式模型进行布局的矩形框

框的布局由框类型、框尺寸、定位方案、外部信息决定;框类型包括block、inline.inline框放在行中或者行框中,受display影响;定位包括普通定位,浮动定位和绝对定位,定位方案由postion|float设置,static&relative是普通流,absolute&fixed是绝对定位;还有分层z-index,代表框的第三个维度

image-20230104205738799.png

绘制

绘制工作主要由UI backend完成

webkit矩形存储:重绘时,webkit会将原来的矩形另存为一张位图,然后只绘制差异部分// 所以以div+css的方式编码对浏览器比较友好

事件循环

浏览器的主线程是事件循环,是个无限循环,随时待命

在浏览器看来,用户的所有手势都是输入、鼠标滚动、悬置和点击;当用户在屏幕上触发手势时,会被Browser接收,Browser process拿着坐标和事件类型给renderer process,renderer process找到事件对象并执行绑定的函数

优化: 屏幕刷新速率为60ftps,但某些事件的触发量不止这个数,出于优化Chrome合并连续的事件并延迟到下一帧渲染时执行,非连续性事件立即触发

参考文献

[1] 浏览器基本工作原理 入门-加希尔译版

[2] 浏览器工作原理 图解-知乎

[3] How browsers work

[4] 阮一峰有趣的图解线程与进程