面试的时候,我们经常会被问从在浏览器地址栏中输入 url 到页面展现的短短几秒内浏览器究竟做了什么?那么浏览器到底做了啥?
浏览器的多进程架构
一个好的程序常常被划分为几个相互独立又彼此配合的模块,浏览器也是如此,以 Chrome 为例,它由多个进程组成,每个进程都有自己核心的职责,它们相互配合完成浏览器的整体功能,每个进程中又包含多个线程,一个进程内的多个线程也会协同工作,配合完成所在进程的职责。
具体说来,Chrome 的主要进程及其职责如下:
Browser Process: 负责包括地址栏,书签栏,前进后退按钮等部分的工作; 负责处理浏览器的一些不可见的底层操作,比如网络请求和文件访问;
Renderer Process: 负责一个 tab 内关于网页呈现的所有事情
Plugin Process: 负责控制一个网页用到的所有插件,如 flash
GPU Process 负责处理 GPU 相关的任务
我们知道浏览器 Tab 外的工作主要由 Browser Process 掌控,
Browser Process 又对这些工作进一步划分,使用不同线程进行处理:
UI thread : 控制浏览器上的按钮及输入框;
network thread: 处理网络请求,从网上获取数据;
storage thread: 控制文件等的访问;
当我们输入url,浏览器开始工作
所以 network thread 会执行 DNS 查询,随后为请求建立 TCP 连接。
在上述过程再细化为
- 浏览器搜索自己的 DNS 缓存。
- 在浏览器缓存中没找到,就在操作系统缓存中查找,这一步中也会查找本机的 hosts 看看有没有对应的域名映射。(所谓的改hosts的原理!!!)
- 在系统中也没有的话,就到你的路由器来查找,因为路由器一般也会有自己的 DNS 缓存。
- 若没有,则操作系统将域名发送至 本地域名服务器——递归查询方式,本地域名服务器 查询自己的 DNS缓存,查找成功则返回结果,否则,采用迭代查询方式。本地域名服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。
- 本地域名服务器 将得到的 IP 地址返回给操作系统,同时自己也将 IP 地址缓存起来。
- 操作系统将 IP 地址返回给浏览器,同时自己也将 IP 地址缓存起来,以备下次别的用户查询时,可以直接返回结果,加快网络访问。
至此,浏览器已经得到了域名对应的 IP 地址。开始建立 TCP 连接,进行三次握手
三次握手的步骤:(抽象派)
客户端:hello,你是server么?
服务端:hello,我是server,你是client么
客户端:yes,我是client
经过一系列检查和数据请求,确认数据以及渲染进程都可用了, Browser Process(进程) 会给 Renderer Process(进程) 发送消息,页面加载和渲染过程开始。
渲染步骤大致可以分为以下几步:
- 解析HTML,构建 DOM 树
- 解析 CSS ,生成 CSS 规则树
- 合并 DOM 树和 CSS 规则,生成 render 树
- 布局 render 树( Layout / reflow ),负责各元素尺寸、位置的计算
- 绘制 render 树( paint ),绘制页面像素信息
- 浏览器会将各层的信息发送给 GPU,GPU 会将各层合成( composite ),显示在屏幕上
构造 DOM 树
浏览器在解析html文件时, 是WebKit 中的 HTML 解释器的将网络或者本地磁盘获取的 HTML 网页和资源从字节流解释成 DOM 树结构。具体过程如下 :
在 WebKit 中这一过程如下:首先是字节流,经过解码之后是字符流,然后通过词法分析器会被解释成词语(Tokens),之后经过语法分析器构建成节点,最后这些节点被组建成一棵 DOM 树。
浏览器在解析html文件过程中,会 ”自上而下“ 加载,并在加载过程中进行解析渲染。在解析过程中,如果遇到请求外部资源时,如图片、外链的CSS、iconfont等,请求过程是异步的,并不会影响html文档进行加载,且统一交由 Browser 进程来处理,这使得资源在不同网页间的共享变得很容易。
解释 CSS
CSS 解释过程是指从 CSS 字符串 经过 CSS 解释器 处理后变成渲染引擎内部规则的表示过程。
生成样式规则之后,会进行样式规则匹配,WebKit 会为其中的一些节点(只限于可视节点)选择合适的样式信息,规则的匹配则是由 ElementRuleCollector 类来计算并获得,它根据元素的属性等,并从 DocumentRuleSets 类中获取规则集合,依次按照 ID、类别、标签等选择器信息逐次匹配获得元素的样式。
最后,WebKit 对这些规则进行排序。对于该元素需要的样式属性,WebKit 选择从高优先级规则中选取,并将样式属性值返回。
从整个网页的加载和渲染过程来看,CSS 解释和规则匹配处于 DOM 树建立之后,RenderObject 树建立之前,CSS 解释器解释后的结果会保存起来,然后 RenderObject 树基于该结果来进行规范匹配和布局计算。当网页有用户交互或者动画等动作的时候,通过 CSSDOM 等技术,JavaScript 代码同样可以非常方便地修改 CSS 代码,WebKit 此时需要重新解释样式并重复以上这一过程。
回流与重绘
当render tree中的一部分(或全部)因为元素的规模尺寸,布局,隐藏等改变而需要重新构建。这就称为回流(reflow)。每个页面至少需要一次回流,就是在页面第一次加载的时候。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并重新构造这部分渲染树,完成回流后,浏览器会重新绘制受影响的部分到屏幕中,该过程成为重绘。
当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color。则就叫称为重绘。
注意:回流必将引起重绘,而重绘不一定会引起回流。
回流何时发生:
当页面布局和几何属性改变时就需要回流。下述情况会发生浏览器回流:
1、添加或者删除可见的DOM元素;
2、元素位置改变;
3、元素尺寸改变——边距、填充、边框、宽度和高度
4、内容改变——比如文本改变或者图片大小改变而引起的计算值宽度和高度改变;
5、页面渲染初始化;
6、浏览器窗口尺寸改变——resize事件发生时;
所以绘制 render 树的过程中会发生多次回流与重绘。另外避免回流与重绘也是web优化技巧之一。
参考链接 :
图解浏览器的基本工作原理 - 知乎
https://zhuanlan.zhihu.com/p/...
面试题之从敲入 URL 到浏览器渲染完成 - 全栈修炼 - SegmentFault 思否
https://segmentfault.com/a/11...
HTTP请求过程-域名解析和TCP三次握手建立链接 - 小Cai先森 - 博客园
https://www.cnblogs.com/caijh...
页面重绘和回流以及优化-WEB前端开发
https://www.css88.com/archive...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。