从浏览器输入 URL 到页面展示过程

更新日期: 2020-01-03阅读: 2k标签: 浏览器

引言

对于面试常问的浏览器输入 URL 到页面渲染过程发生了什么?,我想大家都或多或少能说出一二。但是,其实这个问题很有深度,而你是否回答的有深度,在很大程度上会影响到面试官对你的印象。

并且,网上各种资料都是带浅尝辄止地讲解这个过程,经常会出现今天看到这个版本,明天看到另一个版本地情况。所以,现在我们就来深入浅出一下这整个过程~


一、Chrome 多进程架构

首先,在开始讲解整个过程前,我们需要认识一下 Chrome 多进程架构。因为,从浏览器输入 URL 到页面渲染的整个过程都是由 Chrome 架构中的各个进程之间的配合完成。

Chrome 的多进程架构:

浏览器进程,它负责用户界面(地址栏、菜单等等)、子进程的管理(例如,进程间通信和数据传递)、存储等等

渲染进程,它负责将接收到的 html 文档和 JavaScript 等转化为用户界面

网络进程,它负责网络资源的请求,例如 HTTP请求、WebSocket 模块

GPU(图形处理器)进程,它负责对 UI 界面的展示

插件进程,它负责对插件的管理


二、过程详解

2.1 解析输入

发生这个过程的前提,用户在地址栏中输入了 URL,而地址栏会根据用户输入,做出如下判断:

输入的是非 URL 结构的字符串,则会用浏览器默认的搜索引擎搜索该字符串

输入的是 URL 结构字符串,则会构建完整的 URL 结构,浏览器进程会将完整的 URL 通过进程间通信,即 IPC,发送给网络进程

2.2 请求过程

在网络进程接收到 URL 后,并不是马上对指定 URL 进行请求。首先,我们需要进行 DNS 解析域名得到对应的 IP,然后通过 ARP 解析 IP 得到对应的 MAC(Media Access Control Address)地址。

域名是我们取代记忆复杂的 IP 的一种解决方案,而 IP 地址才是目标在网络中所被分配的节点。MAC 地址是对应目标网卡所在的固定地址。

1. DNS 解析

而 DNS 解析域名的过程分为以下几个步骤:

询问浏览器 DNS 缓存

询问本地操作系统 DNS 缓存(即查找本地 host 文件)

询问 ISP(Internet Service Provider)互联网服务提供商(例如电信、移动)的 DNS 服务器

询问根服务器,这个过程可以进行递归和迭代两种查找的方式,两者都是先询问顶级域名服务器查找

2. 通信过程

首先,建立 TCP 连接,即三次握手过程

客户端发送标有 SYN 的数据包,表示我将要发送请求。

服务端发送标有 SYN/ACK 的数据包,表示我已经收到通知,告知客户端发送请求。

客户端发送标有 ACK 的数据包,表示我要开始发送请求,准备被接受。

然后,利用 TCP 通道进行数据传输

服务端接收到数据包,并发送确认数据包已收到的消息到客户端,不断重复这个过程

客户端在发送一个数据包后,未接收到服务端的确定消息,则重新发送该数据包,即 TCP 的重发机制

当接收完所有的数据包后,接收端会按照 TCP 头中的需要进行排序,形成完整的数据

最后,断开 TCP 连接,即四次握手过程

客户端发送请求,申请断开连接,进入等待阶段,此时不会发送数据,但是会继续接收数据。

服务端接收请求后,告知客户端已明白,此时服务端进入等待状态,不会再接收数据,但是会继续发送数据。

客户端收到后,进入下一阶段等待。

服务端发送完剩余的数据后,告知客户端可以断开连接,此时服务端不会发送和接收数据。

客户端收到后,告知服务端我开始断开连接。

服务端收到后,开始断开连接。

而这整个过程的客户端则是网络进程。并且,在数据传输的过程还可能会发生的重定向的情况,即当网络进程接收到状态码为 3xx 的响应报文,则会根据响应报文首部字段中的 Location 字段的值进行重新向,即会重新发起请求

3. 数据处理

当网络进程接收到的响应报文状态码,进行相应的操作。例如状态码为 200 OK 时,会解析响应报文中的 Content-Type 首部字段,例如我们这个过程 Content-Type 会出现 application/javascript、text/css、text/html,即对应 Javascript 文件、CSS 文件、HTML 文件。

详细的 MIME 类型讲解可以看 MDN

2.3 创建渲染进程

当前需要渲染 HTML 时,则需要创建渲染进程,用于后期渲染 HTML。而对于渲染进程,如果是同一站点是可以共享一个渲染进程,例如 a.abc.com 和 c.abc.com 可以共享一个渲染渲染进程。否则,需要重新创建渲染进程

需要注意的是,同站指的是顶级域名二级域名相等

2.4 开始渲染

在创建完渲染进程后,网络进程会将接收到的 HTML、JavaScript 等数据传递给渲染进程。而在渲染进程接收完数据后,此时用户界面上会发生这几件事:

更新地址栏的安全状态

更新地址栏的 URL

前进后退此时 enable,显示正在加载状态

更新网页

2.5 渲染过程

大家都知道页面渲染的过程也是面试中单独会考的点,并且时常会由这个点延申出另一个问题,即如何避免回流和重绘。

渲染过程,是整个从理器输入 URL 到页面渲染过程的最后一步。而页面渲染的过程可以分为 9 个步骤:

解析 HTML 生成 dom 树

解析 CSS 生成 CSSOM

加载或执行 JavaScript

生成渲染树(Render Tree)

布局

分层

生成绘制列表

光栅化

显示

2.5.1 构建 DOM 树

由于网络进程传输给渲染进程的是 HTML 字符串,所以,渲染进程需要将 HTML 字符串转化成 DOM 树。例如:

需要注意的是这个 DOM 树不同于 Chrome-devtool 中 Element 选项卡的 DOM 树,它是存在内存中的,用于提供 JavaScript 对 DOM 的操作。

2.5.2 构建 CSSOM

构建 CSSOM 的过程,即通过解析 CSS 文件、style 标签、行内 style 等,生成 CSSOM。而这个过程会做这几件事:

规范 CSS,即将 color: blue 转化成 color: rgb() 形式,可以理解成类似 ES6 转 ES5 的过程

计算元素样式,例如 CSS 样式会继承父级的样式,如 font-size、color 之类的。


CSS Object Model 是一组允许用 JavaScript 操纵 CSS 的 api。详细 API 讲解可以看 MDN

2.5.3 加载 JavaScript

通常情况下,在构建 DOM 树或 CSSOM 的同时,如果也要加载 JavaScript,则会造成前者的构建的暂停。当然,我们可以通过 defer 或 sync 来实现异步加载 JavaScript。虽然 defer 和 sync 都可以实现异步加载 JavaScript,但是前者是在加载后,等待 CSSOM 和 DOM 树构建完后才执行 JavaScript,而后者是在异步加载完马上执行,即使用 sync 的方式仍然会造成阻塞。

而 JavaScript 执行的过程,即编译和运行 JavaScript 的过程。由于 JavaScript 是解释型的语言。所以这个过程会是这样的:

针对每句代码进行分行处理,即 Token 化

根据 Token,生成 AST(Abstract Sytanx Tree) 抽象语法树和创建上下文

解释器解析和执行 AST,生成字节码。

编译器针对需要反复执行的代码,生成对应的机器码,提高运行效率

2.5.4 生成渲染树(Render Tree)

在有了 DOM 树和 CSSOM 之后,需要将两者结合生成渲染树 Render Tree,并且这个过程会去除掉那些 display: node 的节点。此时,渲染树就具备元素和元素的样式信息。

2.5.5 布局

根据 Render Tree 渲染树,对树中每个节点进行计算,确定每个节点在页面中的宽度、高度和位置。

需要注意的是,第一次确定节点的大小和位置的过程称为布局,而第二次才被称为回流

2.5.6 分层

由于层叠上下文的存在,渲染引擎会为具备层叠上下文的元素创建对应的图层,而诸多图层的叠加就形成了我们看到的一些页面效果。例如,一些 3D 的效果、动画就是基于图层而形成的。

值得一提的是,对于内容溢出存在滚轮的情况也会进行分层

2.5.7 生成绘制列表

对于存在图层的页面部分,需要进行有序的绘制,而对于这个过程,渲染引擎会将一个个图层的绘制拆分成绘制指令,并按照图层绘制顺序形成一个绘制列表。

2.5.8 光栅化

有了绘制列表后,渲染引擎中的合成线程会根据当前视口的大小将图层进行分块处理,然后合成线程会对视口附近的图块生成位图,即光栅化。而渲染进程也维护了一个栅格化的线程池,专门用于将图块转为位图。

栅格化的过程通常会使用 GPU 加速,例如使用 wil-change、opacity,就会通过 GPU 加速显示

2.5.9 显示

当所有的图块都经过栅格化处理后,渲染引擎中的合成线程会生成绘制图块的指令,提交给浏览器进程。然后浏览器进程将页面绘制到内存中。最后将内存绘制结果显示在用户界面上。

而这个整个从生成绘制列表、光栅化、显示的过程,就是我们常说的重绘的过程


结语

整个浏览器输入 URL 到页面渲染的过程涉及到的知识点非常广,如 Chrome 多进程的架构、HTTP 通信过程、浏览器解析 JavaScript 过程、浏览器绘制页面过程以及一些计算机的基础知识等等,并且,这整个过程的分析其实和 Chrome-devtools 密切相关,所以很好的使用 Chrome-devtools 是非常重要的,后续应该会出一篇关于使用 Chrome-devtools 的指南。


链接: https://fly63.com/article/detial/8488

浏览器禁用了javascript,各种浏览器如何开启javascript的方法总汇

您的浏览器禁用了JS脚本运行,请启用该功能。怎么解除浏览器禁用js?这篇文章将总结整理各个浏览器如何开启、禁用javascript的方法总汇。

浏览器的回流与重绘 (Reflow & Repaint)

浏览器使用流式布局模型 (Flow Based Layout)。浏览器会把HTML解析成DOM,把CSS解析成CSSOM,DOM和CSSOM合并就产生了Render Tree。有了RenderTree,我们就知道了所有节点的样式,然后计算他们在页面上的大小和位置,最后把节点绘制到页面上。

IE6浏览器有哪些常见的bug,以及解决IE6常用bug的方法

IE6不支持min-height,解决办法使用css hack,ol内li的序号全为1,不递增。解决方法:为li设置样式display: list-item;定位父元素overflow: auto;,包含position: relative;子元素,子元素高于父元素时会溢出。解决办法:

css重设样式_清除浏览器的默认样式

由于不同的浏览器默认的样式也不同,所以在网页开发前设置一个公用样式,来清除各个浏览器的默认样式,已达到做的网页在各个浏览器中达到统一。

浏览器访问一个网站所经历的步骤

浏览器访问网站的步骤:Chrome搜索自身的DNS缓存、读取本地HOST文件、浏览器发起一个DNS的一个系统调用、浏览器获得域名对应的IP地址后,发起HTTP三次握手、TCP/IP连接建立起来、服务器端接受到了这个请求、浏览器根据拿到的资源对页面进行渲染

一个新式的基于文本的浏览器 Browsh

Browsh是一个纯文本浏览器,可以运行在大多数的TTY终端环境和任何浏览器。目前,终端客户端比浏览器客户端更先进。终端客户端即时更新和交付,以便于体验新的功能,例如,你可以观看视频。

浏览器内核有哪些?主流浏览器的所使用的内核介绍

一般说的浏览器内核是指浏览器最重要的核心部分,RenderingEngine,翻译成中文大概意思就是“解释引擎”,我们一般称为浏览器内核。由于不同的内核各自有一套自己的渲染网页和解释页面代码的机制,所以就会有一些问题存在。

程序员眼中的浏览器是什么样的?IE:有本事你卸了我啊

主流浏览器之争从上个世纪开就开始,已经持续了很长的时间。人们都在笑话IE,纷纷转向其它浏览器。今天,我向大家分享一下针对IE的搞笑图片,只是逗乐而已,喝杯咖啡,坐下来慢慢享受吧。

精打细算浏览器空闲时间

有时候我们希望在浏览器中执行一些低优先级的任务,比如记录统计数据、做一些耗时的数据处理等,暂且将其称为后台任务。这些任务跟动画计算、合成帧、响应用户输入等高优先级的任务共享主线程

深入浏览器事件循环的本质

浏览器的事件循环,前端再熟悉不过了,每天都会接触的东西。但我以前一直都是死记硬背:事件任务队列分为macrotask和microtask,浏览器先从macrotask取出一个任务执行,再执行microtask内的所有任务,接着又去macrotask取出一个任务执行

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!