web前端开发应该明白的浏览器工作原理

AI 概述
浏览器工作流程浏览器接受 url 开启网络请求线程多进程的浏览器开启网络线程发出一个完整的 http 请求DNS 查询tcp/ip 请求五层因特网协议网络通讯 HTTP 协议HTTP 协议格式HTTP Method 请求方法HTTP Status code 状态码HTTP HEAD(HTTP 头)HTTP Request BodyHTTPSHTTP2构建 DOM 树字符流如何解析成词构...
目录
文章目录隐藏
  1. 浏览器工作流程
  2. 浏览器接受 url 开启网络请求线程
  3. 开启网络线程发出一个完整的 http 请求
  4. 五层因特网协议
  5. 网络通讯 HTTP 协议
  6. 构建 DOM 树
  7. 字符流如何解析成词
  8. 构建 CSSOM
  9. 构建渲染树
  10. 布局与绘制
  11. 总结

作为前端开发,我们平常跟浏览器打交道的时间也是最多的。在前端面试中,一个较为经典的问题:在浏览器地址中输入 url 地址,敲回车,发生了什么?浏览器究竟做了什么?相信很多人脑海里都会出现个大概的轮廓,可是一到细化具体的过程就答不上来。那么,作为前端开发者,应该从哪些方面延伸来回答这个问题呢?

浏览器工作流程

对于浏览器来说,当在地址栏输入 url 地址,浏览器所做的事情就是把一个 url 变成一个在屏幕上显示的网页,大致的过程是这样的:

web 前端开发应该明白的浏览器工作原理

从 HTTP 请求回来,产生流式的数据,DOM 的构建、CSS 计算、渲染、绘制,都是尽可能的流式处理前一步的产出,不需要等待上一步完全接受才开始处理,所以我们在浏览网页的时候,才会逐步出现页面。

1.浏览器接受 url 开启一个网络请求线程

2.浏览器发出一个完整的 http 请求

3.服务器接收请求到后台接收请求

4.使用 http 请求请求页面

5.把请求回来的 html 代码解析成 DOM 树

6.CSS 的可视化格式模型解析

7.根据 CSS 属性对元素进行渲染,得到内存中的位图

8.对位图的合成

9.绘制页面

浏览器接受 url 开启网络请求线程

第一点主要涉及的是浏览器的进程、线程模型以及 JS 的运行机制:

多进程的浏览器

大多数浏览器是多进程的,有一个主控进程,以及每一个 tab 页面都会新开一个进程(某些情况下多个 tab 会合并进程)

进程可能包括主控进程,插件进程,GPU,tab 页(浏览器内核)等等。

  • Browser 进程:浏览器的主进程(负责协调、主控),只有一个
  • 第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建
  • GPU 进程:最多一个,用于 3D 绘制
  • 浏览器渲染进程(内核):默认每个 Tab 页面一个进程,互不影响,控制页面渲染,脚本执行,事件处理等(有时候会优化,如多个空白 tab 会合并成一个进程)

多线程的浏览器内核

每一个 tab 页面可以看作是浏览器内核进程,然后这个进程是多线程的,它有几大类子线程:

  • GUI 线程
  • JS 引擎线程
  • 事件触发线程
  • 定时器线程
  • 网络请求线程

开启网络线程发出一个完整的 http 请求

该部分主要包括:dns 查询、tcp/ip 请求构建、五层因特网等内容

DNS 查询

如果输入的是域名,需要进行 dns 解析成 IP,大致流程:

  • 如果浏览器有缓存,直接使用浏览器缓存,否则使用本机缓存,再没有的话就是用 host
  • 如果本地没有,就向 dns 域名服务器查询(当然,中间可能还会经过路由,也有缓存等),查询到对应的 IP。

tcp/ip 请求

这里的 tcp/ip 请求需要了解 3 次握手规则建立连接以及断开连接时的四次挥手。

一、为什么需要三次握手?

假设有这样的一个场景,client 发出的第一个请求链接报文段没有丢失,而是因为在网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才打到 sever,这个报文本应该是失效的,如果不是三次握手而是两次握手,会让客服端和服务端再次建立连接,导致不必要的错误和资源的浪费。如果采用的是三次握手,就算是失效的那个报文段发送过来了,服务端收到了那个失效的报文并回复了确认报文,由于 client 不会再次发出确认,由于服务器收不到确认,就知道客户端并没有请求连接。

二、何为三次握手?

1、客户端发送一个 SYN 标志的报文到服务器,这是三次握手的第一个报文;

2、服务端接收到请求,回应一个 ACK 标志和 SYN 标志的报文给客户端,询问客户端是否准备好传输数据。这是三次握手的第二个报文;

3、客户端回应服务端一个 ACK 标志的报文,表示可以传输了,这是第三个报文;

tcp/ip 请求需要了解 3 次握手规则建立连接以及断开连接时的四次挥手

三、为什么需要四次挥手?

由于 TCP 连接是全双工的,因此需要每个方向独立的关闭,当一方完成它的数据传送任务后就能发送一个 FIN 信号来终止这个方向上的连接,收到一个 FIN 仅仅是意味着这一个方向上没有数据的流动,但任然可以传输数据。首先进行的是关闭一方的主动关闭,而另一方执行被动关闭。那为什么在握手的时候 ACK 和 SYN 可以一起发送,而这里是分开的呢?再次强调 TCP 是全双工模式,接受到 FIN 意味着没有数据发来,但可以继续发送数据。

四、何为四次挥手?

1、客户端发送一个 FIN,用来关闭客户端到服务端的数据传送,客户端进入 FIN-WAIT-1 终止等待 1 状态;

2、服务端接受到 FIN 信号,并回应一个 ACK,此时,客户端进入 CLOSE-WAIT 等待关闭状态;

3、客户端收到服务端的确认信号后,客户端进入 FIN-WAIT-2 终止等待 2 状态;服务端将最后的数据发送完以后,发出 FIN 信号报文,进入 LAST-ACK 最后确认状态;

4、客户端收到服务端发送的 FIN 信号,发出 ACK 确认信号,客户端进入 TIME-WAIT 时间等待状态。此时 TCP 连接并没有释放,必须经过 2*MSL(最长报文段寿命)的时间后,才进入 close 状态。服务端只要接受到客户端的确认信息,立即进入 CLOSE 状态。等撤销 TCB 之后,结束这次的 TCP 连接。可以看到服务端结束 TCP 的时间比客户端早一些。

为什么需要四次挥手

五、为什么客户端还需等待 2MSL?

1、保证客户端最后发送的 ACK 报文能达到服务器,因为这个报文肯能会丢失。在服务端看来,客户端如果没有回应 ACK 报文的话,应该是发送的请求断开的报文没有收到,于是服务器又会重新发送一次,而客户端就能在 2MSL 时间段内收到这个重传的报文。接着给出回应的报文,并重启 2MSL 的计时器。

2、防止已经失效的报文段出现在本次的连接中,客户端发送完最后一个确认报文后,在 2MSL 时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失,这样新的连接中不会出现旧的连接的请求报文。

五层因特网协议

其实这个概念挺难记全的,记不全没关系,但是要有一个整体概念。

其实就是一个概念:从客户端发出 http 请求到服务器接收,中间会经过一系列的流程。

简括就是:从应用层的发送 http 请求,到传输层通过三次握手建立 tcp/ip 连接,再到网络层的 ip 寻址,再到数据链路层的封装成帧,最后到物理层的利用物理介质传输。

当然,服务端的接收就是反过来的步骤。

五层因特尔协议栈其实就是:1.应用层(dns,http)2.传输层(tcp,udp)建立 tcp 连接(三次握手)3.网络层(IP,ARP)IP 寻址 4.数据链路层(PPP)5.物理层

OSI 七层框架:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

表示层:主要处理两个通信系统中交换信息的表示方式,包括数据格式交换,数据加密与解密,数据压缩与终端类型转换等

会话层:它具体管理不同用户和进程之间的对话,如控制登陆和注销过程

网络通讯 HTTP 协议

HTTP 协议是基于 TCP 协议出现的,在 TCP 的基础上规定了 Request-Response 的模型,决定了通讯必须由浏览器端发起的,首先来了解下 HTTP 协议的格式:

HTTP 协议格式

HTTP 协议大致可以分成以下部分:其中 path 是请求路径、version 是固定的字符串,依次介绍下面的每个部分:

网络通讯 HTTP 协议

HTTP Method 请求方法

在 requestline 里面的方法部分,表示 HTTP 的操作类型,常见的几种请求方法如下:

  • GET:浏览器通过地址访问页面均属于 get 请求
  • POST:常见的表单提交
  • HEAD:跟 get 类似,区别在于只返回请求头
  • PUT:表示添加资源
  • DELETE:表示删除资源
  • CONNECT:多用于 HTTPS 和 WebSocket
  • OPTIONS
  • TRACE

HTTP Status code 状态码

常见的状态码有以下几种:

  • 1xx:临时回应
  • 2xx:请求成功,如 200
  • 3xx:请求目标有变化,如 302 和 301 表示临时和永久重定向,304 表示客户端没有更新内容
  • 4xx;请求错误,如 403 无权限,404 访问的资源不存在
  • 5xx:服务端错误,如 500 服务端错误,503 服务端暂时错误等

前端开发中,最熟悉的系列无非是大家都喜欢的 200 请求成功的标志,在面试中,问得较多的是 304 缓存问题和 301、302 重定向的问题。

HTTP HEAD(HTTP 头)

HTTP 头可以看做是一个键值对,在 HTTP 标准中,Request Header 如下图:

HTTP HEAD(HTTP 头)

Response Header 如下图:

Response Header 如下图

在实际的开发中,完整的列表可以参考 rfc2616 标准。

HTTP Request Body

HTTP 请求的 body 主要用于表单的提交,常见的 body 格式:

  • application/json
  • application/x-www-form-urlencoded:使用 form 标签提交的 html 请求,默认产生
  • multipart/form-data:当有文件上传时,使用的格式

HTTPS

HTTPS 在 HTTP 的基础上增加了两个作用,一是确定请求的目标服务端身份,二是保证传输的数据不会被篡改或者窃听,该协议使用加密通道来传输 HTTP 内容,所以首先需要与服务端简历 TLS 加密通道。可以在此处查看详情:https://tools.ietf.org/html/rfc2818

HTTP2

HTTP2 是 HTTP1.1 的升级版,有两大改进:一是支持服务端推送,二是支持 TCP 链接复用:则使用同一个 TCP 链接来传输多个 HTTP 请求。

构建 DOM 树

当浏览器使用 HTTP 向服务端请求页面后,那么如何去解析请求回来的 HTML 代码、构建 DOM 树呢?

构建 DOM 树

字符流如何解析成词

首先浏览器读取获取的 HTML,根据指定的文件编码方式如 UTF-8 转换为字符流,再将字符串转换为词 Token。那什么是词?词是编译原理中的最小单元,如标签开始、属性、标签结束、注释、CDATA 节点。Token 会标识出当前 Token 的种类。举个列子:

<p class="a" >hello</p>

这里就可以拆分成<p(p 标签的开始)、class=”a”(属性)、 style=”font-size: inherit;color: inherit;line-height: inherit;”>(p 标签的结束)、hello(文本)、</p>(结束标签)</p(p 标签的开始)、class=”a”(属性)、>

构建 DOM 树

接下来就是将词变成 DOM 树。在构建 DOM 树时,是一边生成 Token 一边消耗 Token 来生成节点的。

<html>
<head>
    <title>Web page parsing</title>
</head>
<body>
    <div>
        <h1>Web page parsing</h1>
        <p>This is an example Web page.</p>
    </div>
</body>
</html>

构建的 DOM 树:

构建的 DOM 树

构建 CSSOM

在构建完 DOM 树,当前的对象只包含节点和属性,没有任何样式信息,那么浏览器是如何给 DOM 树添加 CSS 属性呢?我们知道浏览器是流式的处理整个过程,我们拿到 DOM 树构造好的元素,依次去检查他匹配的规则,再根据规则的优先级,做覆盖和调整。

构建渲染树

当 CSSOM 树和 DOM 树都得到之后,将两个树进行合并就得到了渲染树:

构建渲染树

布局与绘制

当浏览器生成渲染树以后,就会根据渲染树来进行布局。在这个过程中,每一个元素都要要弄清楚各个节点在页面中的确切位置和大小,把对应的盒变为相应的位图。一个元素可能对应多个盒(如内联元素,可能被分成多行)每一个盒都对应着一个位图。合成把部分位图合成变成合成层。最终的绘制过程就是把位图合成层绘制到屏幕上。

总结

浏览器的工作流程大致就是:

构建 DOM 树-构建 CSSOM-构建渲染树-布局-绘制

以上关于web前端开发应该明白的浏览器工作原理的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

23

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » web前端开发应该明白的浏览器工作原理

2 评论

  1. 做前端开发必须懂得知识 :razz:

发表回复