今天要写的是一篇关于浏览器底层工作原理的技术科普文,作为一个前端爱好者,在平时的日常工作中,最常打交道的莫过于浏览器了。不过,大多数人并不知道,在我们打开浏览器并浏览一个网页时,浏览器底层具体进行了什么工作。今天我将带领大家,逐步剖析我们在使用浏览器访问网页的过程中,浏览器究竟为我们做了些什么。

在进入正文之前,先给大家引入一个话题。相信每个人都曾迷惑于互联网一些复杂难懂的概念,什么区块链阿,O2C阿,互联网思维阿….. 不少人似乎被这些模糊的概念吓住了,怀疑自己是不是跟不上当今的互联网时代了。其实,当你仔细去了解过后,你会发现这些所谓的互联网新名词,讲的也不过是一些平常的东西。只是这些通俗易懂的道理,被人用高大上的词汇包装起来而已。为了证明一下,我特地去网上找了这张图片:

怎么样?是不是感觉自己一下子茅舍顿开、豁然开朗。其实,在互联网技术领域,也有非常多高大上的专业术语,但当你仔细去剖析这些知识点后,你会发现其实道理也不过如此。给大家讲这些,主要是为了消除大家对于互联网专业术语的恐惧,因为究其本质,这些都是我们可以理解的理论。

现在开始进入正文,即然谈到了浏览器,在这里不得不先向大家介绍一下现在市面上的主流浏览器。所谓的主流浏览器,有两个评判标准:1.有独立研发的内核 2.占有一定的市场份额。内核是浏览器最重要的部分,是浏览器的核心,也称为“渲染引擎(Rendering Engine)”。它用来解释网页语法,把内部的代码转化为用户可见的视图。浏览器内核决定了浏览器该如何显示网页内容以及页面的格式信息,不同的浏览器内核的兼容性不同,其渲染效果也各有所异。

目前市面上主要有五大主流浏览器,分别是IE火狐Firefox谷歌Chrome苹果Safari欧朋Opera它们所用的内核分别是Trident内核、Gecko内核、Blink内核、Webkit内核 和 Blink内核。

浏览器

内核

IE浏览器

Trident内核,也是俗称的IE内核

Chrome浏览器

以前是Webkit内核,现在是Blink内核,统称为Chrome内核或Chromium内核

Firefox浏览器

Gecko内核,俗称Firefox内核

Safari浏览器

Webkit内核

Opera浏览器

最初是自己的Presto内核,后来加入谷歌,从Webkit又到了Blink内核

360浏览器、猎豹浏览器

IE+Chrome双内核

搜狗、遨游、QQ浏览器

Trident(兼容模式)+Webkit(高速模式)

百度浏览器、世界之窗

IE内核

2345浏览器

IE+Chrome双内核

对于前端开发人员来说,要考虑到许多用户体验的问题,开发的项目必须兼容各大主流浏览器,因此必须要先了解各大浏览器的内核。内核研发的时间成本和技术成本都很高,我们国内目前还没有独立研发的浏览器内核,国产的浏览器,如百度浏览器、QQ浏览器、360浏览器等,都是基于国外的内核技术。就连去年引起一时轰动的首个“自主研发”的国产浏览器——红芯浏览器,也在后来承认是抄袭了谷歌浏览器的内核。

介绍完主流浏览器,就来讲解浏览器的工作过程。浏览器的工作过程主要分为两个部分:网络通信部分和页面渲染部分。

浏览器工作的第一部分:网络通信

在我们打开一个浏览器浏览一个网站时,我们首先需要在地址栏输入网站的网址,通常我们输入的都是网站名 ( 如www.baidu.com ) 。

一个完整的网址叫作统一资源定位符URL,即 http://www.baidu.com的格式 ,URL由协议名( 如http ) 和服务器名 ( 如www ) 与域名 ( 如baidu.com ) 连在一起的网站名( www.baidu.com )构成。我们也可以直接在地址栏输入网站的ip地址,如联通运营商的百度ip地址为163.177.151.109 。

当我们输入域名并按下回车键后,DNS (Domain Name System) 就会为我们解析域名(DNS也叫域名系统,是万维网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住那一长串能够被机器直接读取的IP数串)。DNS最终通过我们输入网址的主机名/服务器名 (如www.baidu.com这个网址的主机名就是www) 找到该网址唯一对应的IP地址 (这个过程叫做域名解析或主机名解析)。

在DNS进行域名解析之前,浏览器首先还会进行一系列复杂的工作。它会先搜索自身的DNS缓存,如果找不到自身的缓存,就会开始搜索操作系统的DNS缓存,如果找到了缓存并且缓存没有过期就停止搜索和解析。如果操作系统也找不到缓存,就会尝试读取位于C:\Windows\System32\drivers\etc目录下的hosts文件,查看文件里面有没有该域名对应的IP地址,如果有则解析成功。

如果hosts文件还找不到对应的条目,浏览器会向本地配置首选的运营商DNS服务器发起域名解析请求(该过程为递归请求)。如果运营商的DNS服务器也搜索不到自身所对应的DNS缓存,就会代我们的浏览器向根域的DNS发起请求(该过程为迭代请求)。根域首先会替我们解析顶级域名(.com),返回顶级域名.com的ip地址。运营商的DNS接着向顶级域名.com的ip地址发起请求,顶级域名.com再返回baidu.com域名的ip地址。于是运行商DNS服务器又会向baidu.com域名的ip地址发起请求查找www.baidu.com的ip地址,这时baidu.com域名的DNS服务器通过主机名www找到www.baidu.com的ip地址并返回给运营商的DNS服务器。运营商的DNS服务器接着 (把老子累死对你们有什么好处?) 把最终的ip地址返回给我们的Windows操作系统内核,操作系统内核又把结果返回给浏览器,于是到此浏览器终于得到了www.baidu.com这个网站名的ip地址,解析成功。

解析完URL获得对应的ip地址后,浏览器会遵循超文本传输协议http的规范(现在更多采用https协议,因为https更加安全可靠),向目标网站服务器发起请求。浏览器根据TCP/IP网络协议,利用我们所拿到的ip地址与目标网站服务器建立通信。

关于TCP协议,这里有必要仔细讲解一下。不管你是走前端还是后端,TCP协议是在多数互联网公司面试过程中逃不开的考查点。TCP是一种面向连接的传输层控制协议,在发送数据前,通信双方必须在彼此间建立一条连接,客户端和服务器端的内存里分别保存一份关于对方的信息,如ip地址、端口号等。 TCP可以看成是一种字节流,该协议提供了一种可靠的面向连接服务,采用三次握手建立一个连接,采用四次挥手来关闭一个连接。

三次握手的目的,是为了确认两台主机都具备接收和发送信息的能力,以防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。先通俗的跟大家解释一下所谓的TCP三次握手。

场景假设:

在一次秘密任务的执行过程中,水蜜桃不幸被敌方逮捕关押起来,于是上头派出了哈密瓜执行对水蜜桃的营救行动。哈密瓜潜入敌方关押水蜜桃的房间水管通道口,但是管道太窄了,哈密瓜爬不进去,不知道房间里水蜜桃现在的情况,只能通过折纸船的方式让信息流向水蜜桃房间的下水道,以便和水蜜桃进行通信。

此时的哈密瓜和水蜜桃就相当于是两台要进行通信的主机A和B,但是两台主机要进行通信,要先证明两台主机都有接收和发送信息的能力。

哈密瓜首先要确定房间里的水蜜桃是不是可以与之自由通信,于是他在纸条上写道“呼叫水蜜桃,街头暗号?(seq249)”,将笔和纸船流向水蜜桃的房间,此时哈密瓜还不确定水蜜桃能不能收到他的信息。

我们假设哈密瓜是客户端主机A,水蜜桃是服务器主机B,A需要确认B既可以收信息也可以发信息,B也要确认A既可以收信息也可以发信息之后,才会开始真正的通信。因为如果有任何一方的收或发存在问题,通信都无法成功。这第一张纸条,表示TCP三次握手的第一次握手,主要传递两个信息,一是请求建立连接,二是发出一个序列号。在实际连接中,请求建立连接用SYN=1表示,序列号用seq=n表示,其中n为一个数。第一次握手让服务器主机B知道客户端主机A可以发出消息。

过了一会儿,水蜜桃突然看到了下水道的纸条,知道同伴来救自己,水蜜桃也知道了同伴哈密瓜能给他自由写信,便拿起笔写道:“水蜜桃收到(ack 250),买了否冷?(seq99)”,然后将笔和纸条流回去,此时的水蜜桃并不知道哈密瓜能否收到他的回信。2分钟后,哈密瓜收到了水蜜桃的纸条,知道水蜜桃此时即能自由的收信,也能自由的回信。

这是第二张纸条,也就是第二次握手。我们要注意到哈密瓜发的序号是seq249,水蜜桃回复的是收到ack250。在实际情况中,这次回复一共有三条信息,一是同意建立连接(SYN = 1),二是确认收到了刚才的信息(ack = 刚才的seq + 1),三是发出自己的序列号(seq = x,其中x为一个数)。

我们仔细回想一下,在第一次传条中服务器主机B知道了客户端主机A可以发送信息,第二张纸条发出,客户端主机A接到之后,知道了服务器主机B可以接收也能发出。那么这个时候,还有一个没有证明,那就是服务器主机B还不知道客户端主机A能不能接收到自己的纸条。虽然客户端主机A接收到了纸条,但是服务器主机B并不知道。所以服务器主机B要生成一个数,让客户端主机A回复这个数加一才能确认客户端主机A也能接收到消息。这就是服务器主机B要发出序号的原因。第二次握手让客户端主机A知道了服务器主机B能接收到信息,也能发出信息。

哈密瓜于是继续写道“否冷?why?哈哈哈哈…(ack100)水蜜桃我来救你啦,想不到你也有今天啊哈哈哈(seq 250)”,将纸条流了回去,此时水蜜桃还在等待,水蜜桃并不确定哈密瓜能否正常收到自己的纸条。又过了一会,水蜜桃看到了流过来的纸条,知道哈密瓜看到了他的回信,即知道了哈密瓜也能自由的收信。

这是第三张纸条,也就是第三次握手。这次客户端主机A回复也有三条信息,一是表示现在开始发送(SYN = 0),二是成功收到了服务器主机B的信息(ack=刚才的seq + 1),三是这张纸条的序号(seq=最开始发出的序号 + 1)。第三次握手让B知道了A能接收到。

通过这个例子,相信大家应该可以理解下面的图示了,这就是TCP三次握手的本质。

三次握手之后,他们之间的通信正式建立,于是终于可以安心的给彼此发小纸条了 :

“ 哈密瓜你要怎么救我阿…. 这里好黑风好大,我好空虚好害怕 ”

”你先把品如的衣服脱了 ”

……..

通过TCP三次握手建立了TCP/IP连接后,浏览器会向服务器主机发起一个HTTP-GET方法报文请求。请求中包含访问的URL,也就是 http://www.baidu.com/ ,还有浏览器操作系统信息、编码等。

(关于Cookies:如果Cookies是首次访问,会提示服务器建立用户缓存信息。如果浏览器已存储了该域名下的Cookies,那么浏览器会把Cookies放入HTTP请求头里发给服务器。可以利用Cookies对应键值,找到相应缓存,缓存里面存放着用户名、密码和一些用户设置项。)

服务器端接收到http请求以后,便会响应和处理该http请求,处理之后给浏览器返回html文件。

以上便是浏览器访问网站时网络通信部分的大致过程,至于更为详细的网络通信内部过程,感兴趣的人可以查阅相关网络资料,在此便不再叙述。

接下来为大家介绍浏览器工作的第二部分:页面渲染

当浏览器拿到服务器返回的HTML文档时,渲染引擎(浏览器内核)首先会对HTML文档进行解析,构建DOM树。解析HTML文档的同时会解析CSS样式(内部style标签下的CSS样式或外部的CSS文件),构建CSSOM树。HTML解析构建和CSS的解析是相互独立的并不会造成冲突,因此我们通常将css样式文件放在头文件head中,让浏览器尽早解析css。

由于js可能会改变html现有结构,因此当HTML解析过程遇到script标签时,渲染引擎会先暂停对DOM树的解析,单开一个线程调用JS引擎来加载js资源。等 JavaScript 引擎运行完毕,浏览器会从中断的地方继续构建DOM树。

默认情况下javascript是同步加载的,后面的元素要等待javascript加载完毕后才能进行加载(在计算机术语中,同步加载指单独一条线程加载,而异步加载指多条线程同时加载)。对于一些意义不是很大的javascript,如果放在页面头部加载会延迟页面首绘时间,严重影响用户体验。 因此可以在首绘不需要用到js的情况下将js的加载放在HTML文档底部,或使用async、异步API或promise对象等方式实现js的异步加载,防止js阻塞HTML文档的解析。

(JS本身是单线程的,在处理一个任务的时候无法同时去处理别的任务,单凭JS是无法实现异步编程的,必须借助一些别的机制。关于浏览器异步加载机制和异步操作事件,如DOM事件、ajax请求事件等,以后会用一个篇幅单独进行说明。)

当HTML解析完成后,浏览器会将文档标注为交互状态,并开始解析那些处于“deferred”模式的脚本,即那些应在文档解析完成后才执行的脚本。然后,文档状态将设置为“完成”,开始加载执行脚本文件。

当DOM树和CSSOM树构建完毕,就开始进行渲染树(Render Tree)的构建。渲染树是由DOM树和CSSOM树合并而成,它将网罗网页上所有可见的 DOM 内容,以及每个节点的所有 CSS 样式信息。

为构建渲染树,浏览器大体上完成了下列工作:

  • 从dom树的根节点开始遍历每个可见节点
  • 对于每个可见节点,为其找到适配的css规则并应用它们
  • 发射可见节点,连同其内容和计算的样式

最终输出的渲染同时包含了屏幕上的所有可见内容及其样式信息。

(某些节点通过 CSS 移除,因此在渲染树中也会被忽略。注意 visibility: hidden 与 display: none 是不一样的。前者隐藏元素,但元素仍占据着布局空间,即将其渲染成一个空框,而后者 (display: none) 将元素从渲染树中完全移除,元素既不可见,也不是布局的组成部分。)

渲染树构建完毕之后,将会对元素进行放置。到目前为止,我们计算了哪些节点应该是可见的以及它们的计算样式,但我们尚未计算它们在设备视口内的确切位置和大小。对于元素的放置,Webkit内核 使用的术语是“布局Layout”,而 Gecko 内核称之为“重排/回流Reflow”。它是一个递归的过程,每个节点都负责自己及其子节点的布局,布局的结果是得到元素相对父节点的坐标和尺寸。渲染引擎精确地捕获每个元素在视口内的确切位置和尺寸,为每个节点提供它应该出现在屏幕上的确切坐标。

知道了哪些节点可见、它们的计算样式以及几何信息,我们可以最终将这些信息传递给最后一个阶段:将渲染树中的每个节点转换成屏幕上的实际像素,并将各个节点绘制到屏幕上,这一步通称为“绘制Painting”。

于是乎,一个网页最后就这么呈现在我们眼前了。

虽然百度的首页看起来很简单,但它的渲染却需要完成相当多的工作。如果 DOM 或 CSSOM 被修改,渲染引擎只能再执行一遍上述步骤,以确定哪些像素需要在屏幕上重新渲染。

(关于重绘Repaint和回流Reflow :当屏幕的一部分要重新粉饰,比如某个元素的背景颜色发生改变,但是元素的几何尺寸没有改变,这个时候就会进行重绘;而当元素的几何尺寸变了,我们需要重新验证并计算Render Tree,是Render Tree的一部分还是全部都发生了变化,这就是回流Reflow。Reflow 会从这个元素开始递归往下,依次重新计算所有结点的几何尺寸和位置。显然,回流Reflow要比重绘Repaint消耗的资源更多。)

      渲染树构建、布局以及绘制所需要的加载时间取决于文档大小(如HTML文档)、应用的样式(CSS)和运行文档的设备:文档越大,浏览器需要完成的工作就越多;样式越复杂,绘制所需要的时间就越长。要理解这是一个渐进的过程,现代浏览器不会等到CSSOM树和DOM树全部构建完成才开始进行绘制,为了获得更好的用户体验,渲染引擎将尝试尽快在屏幕上显示内容。在开始构建和布局渲染树之前,它会先解析和显示部分HTML内容,同时继续处理来自网络的其余内容(如加载图片资源等)。所以在低网速的环境中,我们经常观察到页面至上而下缓慢的加载出来,或者是先显示文本内容后再绘制成带有样式的页面内容。

总的来说,在我们用浏览器浏览网站页面时,差不多进行了这样一个流程:

域名解析(DNS解析) ——> 发起TCP的3次握手 ——> 建立TCP连接后发起HTTP请求 ——>服务器响应HTTP请求,向浏览器返回HTML代码 ——>浏览器解析HTML代码,并加载HTML代码中的资源(如js、css、图片等)——> 浏览器对页面进行渲染呈现给用户

以上便是浏览器的渲染原理,当我们了解了浏览器底层是如何进行解析和渲染的,我们就可以开始思考如何优化我们的代码,使浏览器对页面的解析更高效。 我们在编写HTML文档和CSS样式时,应该尽可能的采取最优化的写法,以减少Repaint、Reflow对资源的消耗,提高浏览器的解析速率。至于网页浏览的具体优化方案,本文便不再阐述,以后会进一步为大家详细讲解。此外,此号还会陆续更新一些关于Web及算法方面的知识,欢迎各位志同道合的朋友一起留言探讨。

前端必经之路:浏览器底层工作原理相关推荐

  1. javascript教程系列20: 前端必读,浏览器内部工作原理(转)

    目录 一.介绍 二.渲染引擎 三.解析与DOM树构建 四.渲染树构建 五.布局 六.绘制 七.动态变化 八.渲染引擎的线程 九.CSS2可视模型 英文原文:How Browsers Work: Beh ...

  2. 前端必读:浏览器内部工作原理

    前端必读:浏览器内部工作原理 作者: Tali Garsiel  发布时间: 2012-02-09 14:32  阅读: 2133 次  原文链接   全屏阅读  [收藏]   http://kb.c ...

  3. 史上最全!图解浏览器的工作原理

    可能每一个前端工程师都想要理解浏览器的工作原理. 我们希望知道从在浏览器地址栏中输入 url 到页面展现的短短几秒内浏览器究竟做了什么: 我们希望了解平时常常听说的各种代码优化方案是究竟为什么能起到优 ...

  4. WEB HTTP:浏览器HTTP协议漫谈、请求对象Httprequest、响应对象HttpResponse、浏览器内部工作原理(待完善)

    0 系列目录 WEB请求处理 WEB请求处理一:浏览器请求发起处理 WEB请求处理二:Nginx请求反向代理 WEB请求处理三:Servlet容器请求处理 WEB请求处理四:Tomcat配置实践 WE ...

  5. 【综合篇】浏览器的工作原理:浏览器幕后揭秘

    web(给达达前端加星标,提升前端技能) 了解浏览器是如何工作的,能够让你站在更高的角度去理解前端 浏览器的发展历程的三大路线,第一是应用程序web化,第二是web应用移动化,第三是web操作系统化. ...

  6. 现代浏览器的工作原理

    英文原文:Tali Garsiel,编译:zzzaquarius 简介 浏览器可以被认为是使用最广泛的软件,本文将介绍浏览器的工 作原理,我们将看到,从你在地址栏输入google.com到你看到goo ...

  7. 【转载】现代浏览器的工作原理

    原文:http://taligarsiel.com/Projects/howbrowserswork1.htm 编译:zzzaquarius  http://blog.jobbole.com/1274 ...

  8. How browsers work -Behind the scenes of modern web browsers 浏览器到底是怎么工作的、浏览器的工作原理(完整中文翻译)

    How browsers work -Behind the scenes of modern web browsers 有空翻译一下这篇必读的文章 -浏览器到底是怎么工作的.浏览器的底层原理是啥.浏览 ...

  9. 【转】浏览器内部工作原理

    目录 一.介绍 二.渲染引擎 三.解析与DOM树构建 四.渲染树构建 五.布局 六.绘制 七.动态变化 八.渲染引擎的线程 九.CSS2可视模型 英文原文:How Browsers Work: Beh ...

最新文章

  1. matplotlib 横坐标少了一个点_比 matplotlib 效率高十倍的数据可视化神器
  2. 让div margin属性消失_为什么div里面打一个字之后就会有高度了呢?
  3. android intent.putextras,关于android:如何使用putExtra()和getExtra()来表示字符串数据
  4. vue 单文件组件中,输入template 按 tab 键不能自动补全标签的解决办法
  5. hdu2074java
  6. poj1066--Treasure Hunt(规范相交)
  7. 【贪心】POJ - 3069 Saruman's Army
  8. 一大波干货学习资源分享
  9. 《oracle大型数据库系统在AIX/unix上的实战详解》讨论45 显示某个登录用户的信息...
  10. 移动端学习笔记(黑马教程)-基础概念
  11. delphi 访问https 接口
  12. FluidSIM3.6 安装 FluidSIM4.2
  13. 删除远程桌面登录的记录(mstsc)
  14. AVX2指令集浮点乘法性能分析
  15. 微型计算机系统教案,微型计算机硬件系统教案
  16. Redis学习之del命令
  17. serv-u 用户时间显示相差8小时_调好闹钟!4月8日凌晨,将迎来今年最大满月
  18. 基于粒子群算法的微电网优化调度应用研究(三、长短期记忆网络和卷积神经网络预测模型)
  19. MySQL 安装详细步骤
  20. 不会论文管理?带你从零开始完成zotero安装,插件配置及使用

热门文章

  1. Java-并发知识体系-思维导图
  2. 瑞利分布、莱斯分布与窄带过程
  3. 两周自制脚本语言--第二天 设计程序设计语言
  4. Windows开机提示:“Windows 未能启动。原因可能是最近更改了硬件或软件。解决此问题的步骤:”
  5. 在公司没事做的时候很心虚
  6. 硅谷科技公司高福利的背后:81%员工工作不开心
  7. 如何设置HTML select下拉框的默认值?
  8. 我的一百个2019(一):再见,我亲手创办的公司!
  9. swiper3 loop 图片位置错乱问题
  10. 用指数形母函数证明一个基本的指数运算公式