✊构建浏览器工作原理知识体系(开篇)

🌻 前言

作为一个前端工程师,浏览器是我们密不可分的朋友,想要深耕前端,就必须和浏览器“交心”💞。

为什么你觉得偶尔看浏览器的工作原理,但总是忘呢😵‍💫,因为你没有形成一个完整的知识网络,你的记忆是碎片化的。正如人的神经网络,只有当你的记忆相互依赖,相互链接,才能形成长期稳定的记忆。

所以本文我将用一条知识线将浏览器工作原理的知识串联起来,因为本文的目的是为了帮助大家建立浏览器基础的思维树,所以很多细节点不做过多阐述,先有了树,后面你在上面伸展枝叶就会发现清晰明了很多。欢迎点赞支持或评论指正。

目录:

  1. # ✊构建浏览器工作原理知识体系(开篇)
  2. # ✊构建浏览器工作原理知识体系(浏览器内核篇)
  3. # ✊构建浏览器工作原理知识体系(网络协议篇)
  4. ✊构建浏览器工作原理知识体系(网页加载超详细全过程篇) 待更新

🪴一、了解进程、线程

进程:计算机正在运行的一个程序的实例。每个进程都有自己的内存空间、系统资源(如文件描述符、I/O 等),以及一个或多个线程(执行指令的基本单位);

线程:线程是进程中的执行单元,是操作系统调度的最小单位。在一个进程中可以有多个线程,它们共享进程的资源,但拥有各自的执行流。线程是进程的一部分,同一个进程中的多个线程可以并发执行,共享进程的地址空间和系统资源。

通俗的说,比如浏览器是一座工厂,进程就是工厂里的不同车间,线程是车间里的流水线,它是是工厂中的实际运作单位。

你需要了解:

  • 进程具有独立性,所有进程互相隔离,独立运行。一个进程崩溃不会影响其他进程。进程与进程之间的通信,是通过进程间通信(Inter-Process Communication,简称IPC)来进行数据交换和协作的。

  • 一个进程包含多个线程,每个线程并行执行不同的任务。其中一个线程崩溃了,那么整个进程也就崩溃了。线程之间可以相互通信。

并行和并发

🚨关于并行和并发的概念一定要清晰,因为很多问题的根源或者性能优化方案都是依靠并行或并发的。

并发是指多个任务在同一时间段内交替执行,从外部看似乎是同时执行的

并行是指多个任务在同一时刻同时执行

关于进程通信(IPC)

进程间通信方式有以下七种:

  1. 管道(Pipe): 管道是一种半双工的通信方式,它在父进程和子进程之间创建一个共享的文件描述符,通过文件描述符进行通信。管道可以分为匿名管道和命名管道。
  2. 消息队列(Message Queue): 消息队列是一种进程间通信的机制,进程通过发送消息到队列,其他进程可以从队列中接收消息。消息队列提供了一种异步的通信方式。
  3. 共享内存(Shared Memory): 共享内存允许多个进程访问同一块物理内存区域,进程可以直接读写共享内存中的数据。共享内存是一种高效的 IPC 方式,但需要额外的同步机制来确保数据的一致性。
  4. 信号量(Semaphore): 信号量是一种用于进程同步的机制,它可以用来控制对共享资源的访问。信号量可以用于解决临界区问题,确保多个进程按照一定顺序访问共享资源。
  5. 套接字(Socket): 套接字是一种网络编程中常用的通信方式,它可以在同一台主机上的不同进程间进行通信,也可以在网络上的不同主机上的进程间进行通信。
  6. 文件映射(File Mapping): 文件映射允许多个进程共享同一文件的内存映射区域,可以通过对这个内存区域的读写来进行进程间通信。
  7. 信号(Signal): 信号是一种软件中断,用于通知进程发生了某个事件。进程可以通过注册信号处理函数来捕获和处理信号。

根据交换信息量的多少和效率的高低,分为低级通信和高级通信。以上共享内存、管道、消息队列、套接字属于高级通信。

这里简单说下Chrome的 IPC 通信机制。它的渲染器进程通信由 Mojo 实现(以前是使用Chromium IPC),Mojo 是源于 Chrome 的 IPC 跨平台框架,它诞生于 chromium ,用来实现 chromium 进程内/进程间的通信。目前,它也被用于 ChromeOS。

🧨 想了解 Mojo的,可以看下 Mojo 设计者写的文档:Mojo介绍

线程安全

上面我提到了,线程会共享进程的地址空间和系统资源。所以这些拥有共享数据的多条线程处理并发式任务时,由于多个线程操作同一资源,操作时间并未错开,而使得内存中的操作重复,从而数据错乱,造成线程安全问题。具体线程安全的原因可以总结为以下5点:

  1. 抢占式执行:多线程的调度是随机的,万恶之源;
  2. 多线程修改同一个变量:这个很好理解,就是多个线程同时修改一个变量,就会出现问题,这里就不举例了;
  3. 操作是原子的:简单来说就是每个线程的指令都是独立的,所以修改同一变量时才会出问题,对此问题,我们可以把相同操作的所有指令封装到一起;
  4. 指令重排序:编译器可能会改变两个操作的先后顺序,处理器也可能不会按照目标代码的顺序执行。内核这样的操作其实是对内存访问有序操作的一种优化,可以在不影响单线程程序正确的情况下提升程序的性能,但是同时就会可能影响代码执行的正确性,导致线程安全问题;
  5. 内存可见性问题:当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程应该能够立即看得到修改后的值,但是在多线程环境下,一个线程对共享变量的操作对其他线程是不可见的,所以无法立即同步数据。

总结来讲,就是线程并发或者内核优化机制导致的线程安全问题。那怎么解决线程安全问题呢🤔?一般有以下几种思路:

  1. 锁机制、互斥量、信号量: 这些都是同步控制的机制,通过对关键区域的加锁,确保在同一时刻只有一个线程能够访问共享资源。加锁是非常常见的解决线程安全的手段;
  2. 线程安全的数据结构: 使用线程安全的数据结构可以减少对共享数据的直接访问,从而减小同步的压力。
  3. Web Workers: 在一些需要并行计算的场景下,使用 Web Workers 可以将任务分发到独立的线程中执行,减少对主线程的竞争。
  4. 事件驱动: 使用事件驱动的编程模型,通过发布和订阅事件来进行通信,可以降低对共享状态的依赖。
  5. Atomic操作: 使用原子操作,确保某些操作在执行时是不可中断的,避免了在多线程环境下的竞争问题。

🪴二、浏览器有哪些进程?

现在的浏览器基本都是采用多进程架构设计,即一个标签页(也就是一个网页)会启用多个进程,一般至少有如下四个进程:

  • 浏览器进程:整个浏览器的主进程,负责协调、控制其他进程;
  • 渲染进程(也可以叫内核进程):负责渲染页面内容的进程;
  • 网络进程:负责处理网络请求,每个标签页都共享同一个网络进程,以减少资源占用。
  • GPU进程:负责处理浏览器中与图形相关的任务,,例如加速页面绘制、处理 CSS 动画、执行 WebGL 操作等。GPU 进程与渲染进程分离,以提高性能。

除此以外,还可能开辟插件进程,如果页面使用了插件(例如 Flash、Java 等),则会有对应的插件进程。

渲染进程(也叫内核进程,因为浏览器内核、js引擎就是在渲染进程中工作的)和网络进程是我们前端程序员最需要关注的两个进程,下面我们就分别说说这两个进程究竟干了些什么?

🪴三、渲染进程有哪些线程?

五大类线程

渲染进程共有以下5类线程:

无标题-2024-02-23-1141.png

注意是5类线程,不是5个线程,例如GUI渲染线程就有渲染主线程、布局线程、合成器线程、栅格线程等;

  1. GUI渲染线程:负责渲染网页,具体见下一章,当页面触发重绘、回流时该线程也会执行;

注意:GUI渲染线程和JS引擎线程是互斥的(因为GUI 渲染线程和 JavaScript 引擎线程都需要访问和操作 DOM,所以做了线程安全的处理),当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。这也就是为什么js文件会阻塞页面加载,一般最好放在html底部引入的原因。

  1. JS引擎线程:该线程是使用js引擎处理Javascript脚本程序,解析Javascript脚本,运行代码;

  2. 事件触发线程:负责处理用户输入和触发相应的事件(例如,点击按钮时,事件触发线程会负责处理这个点击事件)。它管理一个事件队列,当对应的事件被触发时,事件触发线程会把该事件添加到事件队列的队尾,等待JS引擎的处理;

  3. 定时器触发线程:负责处理通过 setTimeoutsetInterval 等方法设置的定时器,触发相应的回调函数。

  4. 异步HTTP请求线程:XMLHttpRequest连接后,浏览器会新开一个线程请求,检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将回调函数放入事件队列中,等待JS引擎空闲后执行;

为什么事件触发、定时器触发、异步异步HTTP请求都会有各自的线程处理呢?因为JS引擎是单线程的,这些异步任务会阻塞js的执行。所以要单独开启几个线程和主线程并行执行。
这些处理异步操作的线程会把所有异步任务推到一个任务队列里,等待 JS 引擎空闲时,再把他们添加到可执行栈中,开始执行(这里就又延伸到 Event Loop 的机制了)

渲染进程中的异步HTTP请求线程和网络进程有何区别?

看到这里有同学就要问了,渲染进程中的异步HTTP请求线程负责处理异步 HTTP 请求,那浏览器的另一个进程-网络进程是干嘛呢?两个有什么区别?

渲染进程中的异步 HTTP 请求线程是专门用来处理 JavaScript 层面的异步网络请求的,例如使用XMLHttpRequest 对象或 Fetch API。而网络进程就比较全面了,它负责处理所有的网络操作,包括页面导航、处理主页面的请求、子页面的请求、资源加载等。

另外他们两个是协同工作的,例如 JS 发起的异步网络请求,要经历:DNS 解析:-> 建立连接 -> 发送请求 -> 接收响应

当HTTP 异步请求线程处理 JS 代码发起的请求时,DNS 解析和建立连接通常在网络进程中执行,HTTP 异步请求线程则负责发送请求和接收响应。

🪴四、事件循环机制Event Loop

上面我们说了事件循环机制基于 JS 线程是单线程的。虽然渲染进程有很多线程,但是JavaScript执行是在一个单一的线程中进行的。

以下是事件循环的过程

  • 主线程的任务是不断地执行执行栈中的代码。
  • 当执行栈为空时,会检查任务队列中是否有待执行的任务。
  • 如果有,将任务队列中的回调函数添加到执行栈,继续执行。

从上面渲染引擎的几大线程角度来说,JS事件循环机制可以这么理解:

当 JS 引擎从上至下按顺序执行代码时,遇到异步任务,会交由其他几个负责异步任务的线程去执行(事件触发线程、定时器线程、异步Http请求线程)并将异步回调推到任务队列里。

想要快速理解事件循环机制?了解以下这几点就明白了,不明白你提刀来砍我🔪🤣👌

  • 任务队列有两组,一个是宏任务队列,一个是微任务队列,定时器线程会把定时器回调推到宏任务队列,其他异步任务都会被推到微任务队列;

  • 执行时是执行一个宏任务,然后执行这个宏任务里产生的所有微任务,然后再执行一个宏任务,再执行这个宏任务里产生的所有微任务,一直循环下去;

  • 其实你可以这么理解,把定时器的回调内容不要当作异步代码,只是被延迟执行的同步代码。上一点就可以理解成执行完所有同步任务,执行所有产生的异步任务,然后再执行所有同步任务,再执行产生的所有异步任务;

  • 最后超简单的理解,你可以这么想,忽略宏任务里的setImmediate(node.js的函数,浏览器中不存在)、I/O 操作等,在浏览器中,宏任务其实只需要关注定时器、延时器。所以可以这么想:JS 从上向下执行,同步代码执行完后,执行除了定时器以外的所有异步任务,然后执行一个定时器,再执行所有除了定时器以外的所有异步任务,一直往复下去…

在这里插入图片描述

🪴五、网络进程有哪些线程

网络进程里我们需要知道以下线程:

  • DNS 解析线程(DNS Thread): 负责进行 DNS 解析,将域名解析为 IP 地址。
  • SSL 线程(SSL Thread): 处理 SSL/TLS 相关的加密和安全通信。
  • 网络请求线程(Network Thread): 负责处理主要的网络请求和响应,包括接收和发送数据。
  • IPC 线程(Inter-Process Communication Thread): 负责进程间通信。

网络进程的主要工作包括:

  • 发起和处理网络请求,包括 HTTP 请求、WebSocket 等。
  • 执行 DNS 解析,将域名解析为 IP 地址。
  • 建立和管理网络连接。
  • 处理安全通信,包括 SSL/TLS 加密。
  • 处理缓存,包括 HTTP 缓存的读取和写入。
  • 处理文件的读取和写入。
  • 与其他进程(如浏览器进程)进行通信。

🪴六、详解渲染进程|浏览器引擎工作原理

本章主要讲解浏览器的两个引擎:渲染引擎、js引擎的工作原理。包括渲染引擎的渲染过程、js引擎的工作原理、js引擎的垃圾回收机制、内存泄漏问题定位等

书接下回,点个关注敬请期待(更新后会在此处贴上链接)

🪴七、详解网络进程|Http协议

本章主要讲解与网络进程息息相关的网络通信协议相关的知识,例如TCP/IP协议、TCP建立连接的过程、https加密机制、http首部字段等知识

书接下回,点个关注敬请期待(更新后会在此处贴上链接)

🪴八、网页加载超详细全流程

从 URL 输入到页面展现到底发生了什么?这是一个老生常谈的问题。我将会从网络通信协议、进程协作、浏览器引擎工作流程等全方位讲解这个过程。帮你真正理解网页的加载过程,而不是浮于表面。

书接下回,点个关注敬请期待(更新后会在此处贴上链接)

🎁 说在最后

因为篇幅问题,本文先列出来整体的思维网络,后面详细的一些讲解单独抽离,作为系列文章以后更新,感兴趣的可以点个关注,不要错过~🥳🥳🥳

先看后赞,养成习惯👍
收藏吃灰,不如学会🍗
点个关注,不要迷路🪤

  • 20
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端阿彬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值