【JavaScript系列】认识浏览器

随笔3周前发布 林书亚
4 0 0
一、浏览器的工作原理
   1.1  域名与IP地址
   1.2  入口文件index.html

二、认识浏览器内核
   2.1  什么是浏览器内核
   2.2  常见的浏览器内核

三、浏览器渲染整体过程
   3.1  HTML的解析过程
   3.2  解析生成CSS规则
   3.3  构建RenderTree
        3.3.1  注意事项
   3.4 布局和绘制的过程
   3.5 回流和重绘的问题
       3.5.1  回流的解析
       3.5.2  重绘的解析
       3.5.3  页面性能优化
   3.6  composite合成

原创 coderwhy

该系列文章连载于公众号coderwhy和掘金XiaoYu2002中

对该系列知识感兴趣和想要一起交流的可以添加wx:coderwhy666,拉你进群一起成长进步
课程对照进度:JavaScript高级系列3-4集(coderwhy)

脉络探索

在本章节中,我们会学习一个网页URL从输入到浏览器中,到显示经历过怎么样的解析过程呢?
    该问题是面试中的经典题目,也是考验我们对浏览器中的渲染过程是否有足够的理解
    所以我们会先简要讲解在这个过程中发生了什么,然后针对其每一个细节进行深入的探讨
并介绍在输入网页在输入URL中,输入IP或者域名都有哪些区别
    什么是IP,什么又是域名?
    浏览器是如何从IP和域名中拿到页面数据(静态资源)的?

一、浏览器的工作原理

大家有没有深入思考过:JavaScript代码,在浏览器中是如何被执行的?

(1)在浏览器中访问任何页面,都需要输入一个地址。这个地址(URL)可以是一个域名,也可以是一个IP地址

(2)如果是域名的话,就会经过DNS的一个解析(将域名解析为IP地址)

(3)当输入这个URL并回车后,就会去下载 HTML 文件 当用户在浏览器中输入网址时,浏览器会向服务器发送请求,请求下载网站的 HTML 文件,通常是一个叫做index.html的入口文件

(4)解析 HTML 文件 下载完成后,浏览器开始解析 HTML 文件,并构建 DOM 树。在解析过程中,如果遇到外部链接的 CSS 或 JavaScript 文件,浏览器会发起新的请求来下载这些文件

(5)下载 CSS 文件 当浏览器遇到 link 元素时,会发起新的请求来下载该元素的 href 属性指向的 CSS 文件。下载完成后,浏览器会将 CSS 文件解析成 CSSOM 树,并将其与 DOM 树合并,构建出渲染树

(6)下载 JavaScript 文件 当浏览器遇到 script 元素时,会发起新的请求来下载该元素的 src 属性指向的 JavaScript 文件。下载完成后,浏览器会解析 JavaScript 代码,并执行其中的命令。在执行过程中,如果代码需要操作 DOM 或 CSSOM 树,浏览器会进行相应的操作

流程大体分六步,可对照着表2-1的流程图进行理解

【JavaScript系列】认识浏览器

【图2-1】在浏览器中输入URL发生了什么

我想大家在这个理解过程中,如果是初学者的话,应该会有几个疑惑
    什么是域名?什么是IP地址?DNS为什么能将域名转化为IP地址?IP地址和服务器地址有什么关系?
坦白的说,这些内容放在刚开始的时候,可能会有点超纲了,偏向于服务端的内容,但没有关系。在这里会都进行解答

1.1 域名与IP地址

IP地址其实就是服务器地址,他们的关系就如同周树人和鲁迅一样,其实是同一个人。想要探索这一系列的问题,我们是需要接触到云平台的,这些平台有阿里云、华为云、腾讯云等等,主要的作用就是提供服务器的
而服务器就相当于一台电脑,我们的电脑也可以当服务器使用,但我们电脑没办法一直不关。云服务器厂商的可以,所以我们一般都从云平台租服务器,而不是把自己电脑当服务器用。
而这个云要怎么理解❓
我们也许可以用一个更简单的方式来讲解,不知道大家有没有玩过原神,这一款游戏所占据的电脑存储空间是比较大的,大概需要70-80GB左右,这对于电脑、手机不是很好的同学来说,压力还是有的

所以这款游戏提供了一种玩法,也就是云原神,这里的云和我们要理解的云平台是一个意思,指远程服务器通过网络提供各种服务的技术。米哈游把原神放到了服务器上,用户在娱乐的时候,使用云原神就相当于连上了远端的服务器。

此时的游戏主体在服务器,而不是玩家的电脑或者手机上了。如图2-2,存储空间压力从71GB暴跌到404MB,大概降低了99.5%的空间压力,带来的优势不可谓不明显,就是消耗的流量比较夸张,这部分的流量就是消耗在的联系服务器上

不过云平台的真正作用是云计算,这是一个更广泛的专业词汇,超纲太多,我们这里就跳过。只需要暂时记住,云原神只是云计算的一种运用方式

在我们讲述的这个案例中,云如同真实世界中的云朵一样,距离我们很遥远,但看起来很美好,这是其中所表达出来的寓意。而远程服务器所表达出来的效果也契合于此

【JavaScript系列】认识浏览器

【图2-2】 云游戏与普通游戏占据内存对比

而我们的网站访问,也是一样的,从浏览器访问到位于服务器上的页面,而我要怎么知道服务器在哪?依靠的就是IP地址,而IP地址就是服务器地址
那服务器究竟长什么样子的?我们不妨就来开一个服务器先看看?有一个基础印象也很不错

图2-3所展示的是腾讯云,这里我将IP和地域标注了出来。大家可以看到,在IP的前面还有一个(公)字,这是说明这是一个公域IP,意味着这是在整个互联网上唯一的,可以直接访问的地址。没有两个设备可以拥有相同的公域IP地址

而地址也是在选择服务器所最常注意的内容之一,距离我们位置越近的服务器,访问的速度就越快,距离越远则反之。所以在买之前,我们一定要确认清楚,主要是自用还是给用户用。自用就选择离自己近的服务器,用户用就选择距离用户近的

【JavaScript系列】认识浏览器

【图2-3】 云厂商对应的服务器操纵界面

而既然有公域IP,自然就有私域IP

私域IP地址是在局部网络内部使用,不可直接从外部网络访问的地址。这些地址只在私有网络中唯一,不同的私有网络可以使用相同的私域IP

常用于家庭、学校、企业内部网络中的设备,如个人电脑、局部网络内的服务器

就拿我(XiaoYu)的学校的举例,刚好能够连着域名的概念一起普及

如图2-4,我们能够看到,私域IP被标注了校内地址,也就是只能在学校访问,学校范围形成的一个局部网络,在其他地方是无法访问的,这就是私域IP地址

而校外地址,怎么是一个域名,而不是公域IP?因为IP往往比较难记,都是一堆数字(无规律),不符合人类的记忆习惯,所以延伸出来了域名的概念

域名是互联网上用来识别计算机或网络的一个易于记忆的地址。通常,它代替复杂的数字IP地址,我们可以通过易于理解的单词和短语来访问网站。可以理解为起了一个别名的意思
而DNS解析就是把好记的域名和这个难记的公域IP绑定在了一起,我们一旦访问了域名,DNS就会进行解析,给我们进行指路,让我们能够找到这个公域IP上,相当于也就找到了服务器了

【JavaScript系列】认识浏览器

【图2-4】 私域IP与公域域名比对

而域名通常都是xxxx.com,xxxx.cn等等,这个后缀区分出了不同的域名等级,越高级的域名越贵
而com后缀是域名是顶级域名,也是最贵的,次之就是cn后缀的域名,在往后还有各种奇怪后缀的域名,但除非你访问一些奇奇怪怪的网站或者个人博客,不然一般的域名后缀都是前面两种情况

比如掘金就是juejin.cn,是仅次于com顶级域名的存在。而像鼎鼎大名的京东,百度,谷歌等等。他们的域名分别是jd.com,baidu.com,google.com,都属于最贵的域名,并且在域名后缀前面的单词越短,大致上就代表着越贵(越好记忆),像京东的域名,一年上千万是要有的

就目前而言,这些连接都没办法点进去的,这是因为缺少网络协议,也就是位于最前面的https://或者http://,带s的会更安全,但需要申请一个叫做SSL的证书,申请使用了之后,进行访问,浏览器就不会报该网站不安全。这个证书其实就相当于一个担保下保证书,其他更深的内容,我们暂时不了解,这是一整个担保链,比较复杂

例如juejin.cn => https://juejin.cn,此时加上了前缀就能够直接点击跳转去访问到内容了

而我们也来看下域名都是怎么进行设置的,这次我们进入阿里云来看

从图2-5中可以看出我的域名是cn后缀的,属于次顶级域名

同时为什么域名和服务器我要在不同的服务器进行演示呢?这是因为我要说明,这两者在哪买都是无所谓的,你在阿里云买的域名,DNS解析到在腾讯云买的服务器上,也是完全没问题的

云服务器厂商是卖东西的,不是霸王条款说既然服务器在我这买了,域名也一定要在我这里买

【JavaScript系列】认识浏览器

【图2-5】 阿里云域名设置界面

所以我们来进行一次测试:

(1)腾讯云公网IP(服务器地址):101.34.243.124

(2)阿里云公网域名:xiaoyu2002.cn

我已经提前做好了DNS解析了,所以两个地址访问的内容页面应该要是一样的

我的域名有申请SSL证书,所以浏览器访问是安全的,而不安全的情况,如图2-6所示,浏览器是如何显示的大家也可以看到

PS:大家不用访问我的这个网站,我只是拿来举例的,里面并没有东西。需要阅读该系列文章请看公众号coderwhy或者掘金XiaoYu2002

【JavaScript系列】认识浏览器

【图2-6】 https与http网络协议比对

1.2 入口文件index.html

在当下情况中,我们还会疑惑,为什么浏览器会去服务器访问index.html这个文件,而这个文件为什么又叫做入口文件。
在以后编写项目的时候,不管是Vue还是React,我们都会使用脚手架。而脚手架产生的模板,一定是有一个入口文件的,也都叫做index.html。最终打包部署到服务器的时候,部署到服务器上的资源也就是静态资源,也是以这为入口文件。
所以一开始访问到的就都是这个入口文件了。

二、认识浏览器内核

我们打包部署好的项目内容,直接打开是看不了的。
而浏览器访问却可以正常的显示内容,那在这个过程中,一大堆文件都是谁在帮助我们解析❓
要想深入理解下载的过程,我们还要先理解,一个index.html被下载下来后是如何被解析和显示在浏览器上的。
这里就需要说到一个重要的概念,也就是我们的浏览器内核,我们的解析就是由它来完成的。
经过它的解析,我们就能够看到网页,并对网页进行点击等交互操作。
浏览器内核是浏览器的一个重要组成部分。

2.1 什么是浏览器内核

浏览器内核是指浏览器中负责解析 HTML、CSS、JavaScript 等文件的核心组件,也被称为渲染引擎

我们经常会说:不同的浏览器有不同的内核组成
Gecko:早期被Netscape和Mozilla Firefox浏览器浏览器使用
Trident:微软开发,被IE4~IE11浏览器使用,但是Edge浏览器已经转向Blink
Webkit:苹果基于KHTML开发、开源的,用于Safari,Google Chrome之前也在使用
Blink:是Webkit的一个分支,Google开发,目前应用于Google Chrome、Edge、Opera等

……

事实上,我们经常说的浏览器内核指的是浏览器的排版引擎:
官方没有对引擎取一个具体的名字(因为没有官方,浏览器并不是单独由某家公司开发的),所以大家对此的叫法有很多种
排版引擎(layout engine),也称为浏览器引擎(browser engine)、页面渲染引擎(rendering engine)或样版引擎

2.2 常见的浏览器内核

如图2-7,可以看到常用的几款浏览器和对应的内核分别是谁

Trident (三叉戟)
Trident 内核最初是由 Microsoft 开发的,用于 Internet Explorer 浏览器
后来,一些国内的浏览器厂商(如 360安全浏览器、搜狗高速浏览器、百度浏览器、UC浏览器)也采用了 Trident 内核
Gecko(壁虎)
Gecko 内核最初是由 Mozilla 开发的,用于 Firefox 浏览器
Gecko 内核的优势在于支持 HTML5、CSS3 等最新的 Web 标准,并且具有较高的性能和稳定性
Presto(急板乐曲)-> Blink (眨眼)
Presto 内核最初是由 Opera 开发的,用于 Opera 浏览器
后来,Opera 采用了 Blink 内核,Blink 内核基于 WebKit 内核进行了改进和优化,能够更快地渲染页面,并且支持更多的 HTML5、CSS3 特性
Webkit
WebKit 内核最初是由 Apple 开发的,用于 Safari 浏览器
现在,很多国内的浏览器厂商(如 360极速浏览器、搜狗高速浏览器)也采用了 WebKit 内核
除了桌面浏览器,WebKit 内核在移动设备上也得到了广泛的应用,如 iOS 和 Android 系统的浏览器
Webkit -> Blink
Blink 内核最初也是由 Google 开发的,用于 Chrome 浏览器
Blink 内核基于 WebKit 内核进行了改进和优化,并且具有更高的性能和更好的兼容性
现在,Microsoft Edge 也采用了 Blink 内核

【JavaScript系列】认识浏览器

【图2-7】常见浏览器内核

三、浏览器渲染整体过程

但是在这个执行过程中,渲染引擎在拿到一个页面后,对HTML解析的时候遇到了JavaScript标签,应该怎么办呢?

会停止解析HTML,而去加载和执行JavaScript代码

【JavaScript系列】认识浏览器

【图2-8】 渲染引擎工作流程

如图2-8所示的是渲染引擎的整个工作过程,第一次接触会觉得有点复杂,我们可以先简单了解它的过程,接下来对其进行详细的解析:

(1)解析 HTML 文件,构建 DOM(文档对象模型)树。这个树代表了页面上所有元素的节点结构。

(2)解析 CSS 文件,构建 CSSOM 树。

(3)将 DOM 树和 CSSOM 树合并成渲染树。

(4)生成布局树,计算每个元素在页面上的位置和大小。

(5)根据布局绘制渲染树,将渲染树上的元素绘制成屏幕上的像素。

(6)合成层,将多个图层合并成一个图层,以便使用 GPU 进行加速。

(7)使用 GPU 加速,对图层进行合成,形成最终的图像。

(8)如果发生重绘或回流操作,重新执行步骤 4-7。

(9)有些操作会触发重绘或回流,如改变元素的位置、大小、颜色等。这些操作会影响页面的性能和渲染速度,因此需要尽可能避免。(后续会详细讲解)

而这些词汇,是Web开发中,非常重要的词汇,我对其进行了总结,如表2-1,大家可以常看,温故而知新

【表2-1】 浏览器流程(英语词汇总结)

【JavaScript系列】认识浏览器

3.1 HTML的解析过程

HTML 解析过程,构建 DOM 树,是浏览器渲染页面的第一步。

因为默认情况下服务器会给浏览器返回index.html文件,所以解析HTML是所有步骤的开始:

【JavaScript系列】认识浏览器

【图2-9】 HTML的解析效果

HTML 解析过程通常包括以下几个步骤:

(1)获取 HTML 文件 当用户在浏览器中输入网址时,浏览器会向服务器发送请求,请求下载网站的 HTML 文件。

(2)HTML 标记识别 浏览器会将 HTML 文件解析成一个个标记(tag),如 div、p、img 等等。解析的过程中,浏览器会忽略一些不合法的标记,如没有闭合标签、属性值没有使用引号等等。

(3)DOM 树构建 浏览器会将解析后的标记转化成一个个 DOM 节点(Node),构建成一棵 DOM 树(Document Object Model)。DOM 树是一个树形结构,根节点是 document,其他节点代表 HTML 文档中的元素、属性、文本等等。

在构建 DOM 树的过程中,浏览器会按照 HTML 文档的层次结构,将文档分成一个个的块(block),如文本块、段落块、表格块等等。
每个块都会被转换成一个 DOM 节点,如图2-9所示,节点之间的关系由 HTML 标记之间的关系来确定。

3.2 解析生成CSS规则

生成 CSS 规则,是浏览器解析 HTML 文件的一部分。

在解析 HTML 文件的过程中,如果遇到 CSS 的 link 元素,浏览器会下载对应的 CSS 文件。
需要注意的是,下载 CSS 文件不会影响 DOM 的解析。

下载完成后,浏览器会对 CSS 文件进行解析,解析出对应的规则树。

如【图2-10】这个树形结构称为 CSSOM(CSS Object Model,CSS 对象模型),它描述了 HTML 文档中各元素的样式和布局信息。

在 CSSOM 中,每个节点代表一个 CSS 规则,包括选择器和声明。
选择器指定了哪些元素会被应用这个规则,声明则指定了这些元素的样式属性和值。
CSSOM 树的构建过程类似于 DOM 树的构建过程,也是一个逐步解析的过程

【JavaScript系列】认识浏览器

【图2-10】 css构建CSSDOM树

3.3 构建RenderTree

当有了DOM Tree和 CSSOM Tree后,就可以两个结合来构建图2-11所示的Render Tree了
【JavaScript系列】认识浏览器

【图2-11】 构建渲染树

3.3.1 注意事项

注意一:
需要注意的是,link 元素不会阻塞 DOM 树的构建过程,但会阻塞 Render Tree 的构建过程。
这是因为 Render Tree 在构建时,需要对应的 CSSOM Tree。
注意二:
同时,需要注意的是 Render Tree 和 DOM Tree 并不是一一对应的关系。
例如,对于 display 为 none 的元素,它不会在 Render Tree 中出现。这是因为该元素被隐藏了,不会影响页面的呈现,因此也不需要在渲染树中进行渲染

3.4 布局和绘制的过程

【JavaScript系列】认识浏览器

【图2-12】 布局与绘制

如图2-12,步骤4布局的过程:

在步骤 4 中,浏览器会在渲染树(Render Tree)上运行布局(Layout)以计算每个节点的几何体
渲染树表示显示哪些节点以及其他样式,但不表示每个节点的尺寸、位置等信息。布局是确定呈现树中所有节点的宽度、高度和位置信息

如图2-12,步骤4绘制的过程:

在步骤 5 中,浏览器将每个节点绘制(Paint)到屏幕上
在绘制阶段,浏览器将布局阶段计算的每个 frame 转换为屏幕上实际的像素点
这个过程包括将元素的可见部分进行绘制,例如文本、颜色、边框、阴影、替换元素(例如 img)等等

3.5 回流和重绘的问题

这里还有两个比较重要的概念,也是会对浏览器渲染过程中引发性能问题的两个重要概念:回流和重绘

3.5.1 回流的解析

回流是浏览器为了重新渲染部分或全部文档而重新计算文档中元素的位置和几何结构的过程。它通常是因为元素的尺寸、布局、隐藏等属性发生变化引起的

理解回流reflow:(也可以称之为重排)

第一次确定节点的大小和位置,称之为布局(layout)。
之后对节点的大小、位置修改重新计算称之为回流。

也就是说回流是指浏览器必须重新计算渲染树中部分或全部元素的几何信息(位置和大小),然后重新构建渲染树的过程。

触发回流的情况有很多,常见的包括:

(1)DOM 结构的变化,比如添加、删除、移动元素等操作;

(2)改变元素的布局,比如修改元素的宽高、padding、margin、border、position、display 等属性;

(3)页面的尺寸变化,比如浏览器窗口大小的变化,或者文档视口的变化;

(4)获取元素的几何属性,比如调用 getComputedStyle() 方法获取元素的尺寸、位置等信息。

回流的代价比较高,因为它会涉及到大量的计算和页面重排,这会导致页面的性能和响应速度下降。

3.5.2 重绘的解析

重绘是当页面中元素样式的改变并不影响它在文档流中的位置时(如color、background-color、visibility等),浏览器将重新绘制这些元素的过程

理解重绘repaint:

第一次渲染内容称之为绘制(paint)。
之后重新渲染称之为重绘。

重绘是指浏览器不需要重新计算元素的几何信息,而只需要重新绘制元素的内容的过程。

触发重绘的情况有很多,常见的包括:

(1)修改元素的颜色、背景色、边框颜色、文本样式等属性;

(2)修改元素的 box-shadow、text-shadow、outline 等属性;

(3)使用 CSS3 transform 和 opacity 等属性;

(4)添加、移除、修改元素的 class;

(5)使用 JavaScript 直接修改样式。

重绘的代价比较小,因为它不涉及到元素的位置和大小等计算,只需要重新绘制元素的内容即可。

回流一定会引起重绘,所以回流是一件很消耗性能的事情。
回流(Reflow)一定会引起重绘(Repaint)的原因在于它们的处理层级和影响范围。回流涉及到浏览器的布局过程,即对文档元素的尺寸、位置进行计算,这通常是因为DOM操作或样式的改变导致了布局变化。一旦元素的几何属性(如宽度、高度、位置等)发生变化,浏览器需要重新计算元素的位置和大小,然后按照新的布局绘制元素,因此回流必然引起重绘

3.5.3 页面性能优化

避免回流是提高页面性能的重要手段之一,因为它既是计算成本也是渲染成本的源头,以下是一些常用的优化方法:

(1)尽量一次性修改样式 可以使用 cssText 属性、添加 class 等方式,一次性修改元素的样式,避免多次修改引起页面的回流。比如,可以将需要修改的样式保存在一个对象中,然后一次性设置给元素,避免多次触发回流。

(2)避免频繁的操作 DOM 可以使用 DocumentFragment 或者父元素来操作 DOM,避免频繁地操作 DOM 元素,从而减少页面的回流次数。

(3)避免使用 getComputedStyle() 获取元素信息 因为 getComputedStyle() 方法会强制浏览器进行回流操作,从而影响页面的性能。如果需要获取元素的信息,可以在修改样式之前先保存到变量中,避免多次触发回流。

(4)使用 position:absolute 或者 position:fixed 属性 因为可以将元素从文档流中脱离出来,从而避免影响其他元素的位置和大小。虽然这也会引起回流,但是相对于修改文档流中的元素来说,开销较小,对页面的性能影响较小。

总之,避免回流是一项重要的优化技巧,可以帮助我们提高页面的性能和响应速度。可以采用一些常用的优化方法,减少回流的次数,从而提高页面的渲染速度和性能

3.6 composite合成

绘制的过程,可以将布局后的元素绘制到多个合成图层中,如图2-13。

这是浏览器的一种优化手段;

默认情况下,标准流中的内容都是被绘制在同一个图层(Layer)中的;

而一些特殊的属性,会创建一个新的合成层( CompositingLayer ),并且新的图层可以利用GPU来加速绘制;

因为每个合成层都是单独渲染的;

【JavaScript系列】认识浏览器

【图2-13】 合成层效果

有些属性可以触发合成层的创建,包括:

(1)3D 变换(3D Transforms):如 rotateX、rotateY、translateZ 等属性,可以创建一个新的合成层。

(2)video、canvas、iframe 等标签:这些标签会创建一个新的合成层。

(3)opacity 动画转换时:当元素透明度发生变化时,会创建一个新的合成层。

(4)position: fixed:将元素定位为固定位置时,也会创建一个新的合成层。

(5)will-change 属性:可以通过这个实验性的属性,告诉浏览器元素可能会发生哪些变化,从而预先创建合成层。

(6)动画(Animation)或过渡(Transition)设置了 opacity、transform 属性时,也会创建一个新的合成层。

需要注意的是,过度使用合成层也会带来一些问题,如占用更多的内存、增加页面的复杂度等。

因此,在使用合成层时需要谨慎,避免滥用。

后续预告

那么,JavaScript代码由谁来执行呢❓在上面的流程图中,我们并没有看到JS的部分

由JavaScript引擎执行
在下一章节中,我们会对还没看到的JS引擎作出介绍,它和浏览器内核又有哪些关系?它的运行原理是怎么样的?
    它是如何工作的,对JS代码进行执行的过程是怎么样的
在对浏览器有了一个了解之后,我想是时候去看看JS是如何参与进来的了
后续JavaScript高级知识技术会持续更新,如果喜欢我们的文章,欢迎关注、点赞、转发、评论,你们的支持是我们最大的动力

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...