<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>浏览器渲染过程中的网络层面 on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/%E6%B5%8F%E8%A7%88%E5%99%A8%E6%B8%B2%E6%9F%93%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E7%BD%91%E7%BB%9C%E5%B1%82%E9%9D%A2/</link><description>Recent content in 浏览器渲染过程中的网络层面 on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Mon, 04 Aug 2025 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/%E6%B5%8F%E8%A7%88%E5%99%A8%E6%B8%B2%E6%9F%93%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E7%BD%91%E7%BB%9C%E5%B1%82%E9%9D%A2/index.xml" rel="self" type="application/rss+xml"/><item><title>浏览器渲染过程中的网络层面</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/network/network-019/</link><pubDate>Mon, 28 Jul 2025 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/network/network-019/</guid><description>&lt;h2 id="一梳理主干流程"&gt;一、梳理主干流程&lt;/h2&gt;
&lt;p&gt;知识体系中，最重要的是骨架，脉络。有了骨架后，才方便填充细节。所以，先梳理下主干流程：&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;浏览器接收url并开启一个新进程（这一部分可以展开浏览器的进程与线程的关系）&lt;/li&gt;
&lt;li&gt;浏览器解析输入的 URL，提取出其中的协议、域名和路径等信息。（这部分涉及URL组成部分）&lt;/li&gt;
&lt;li&gt;浏览器向 DNS 服务器发送请求，DNS服务器通过 多层查询 将该 域名 解析为对应的 IP地址 ，然后将请求发送到该IP地址上，与 服务器 建立连接和交换数据。（这部分涉及DNS查询）&lt;/li&gt;
&lt;li&gt;浏览器与服务器建立 TCP 连接。（这部分涉及TCP三次握手/四次挥手/5层网络协议）&lt;/li&gt;
&lt;li&gt;浏览器向服务器发送 HTTP 请求，包含请求头和请求体。（4,5,6,7包含http头部、响应码、报文结构、cookie等知识）&lt;/li&gt;
&lt;li&gt;服务器接收并处理请求，并返回响应数据，包含状态码、响应头和响应体。&lt;/li&gt;
&lt;li&gt;浏览器接收到响应数据，解析响应头和响应体，并根据状态码判断是否成功。&lt;/li&gt;
&lt;li&gt;如果响应成功，浏览器接收到http数据包后的解析流程（这部分涉及到html - 词法分析，解析成DOM树，解析CSS生成CSSOM树（样式树），合并生成render渲染树（样式计算）。然后layout布局，分层，调用GPU绘制等，最后将绘制的结果合成最终的页面图像，显示在屏幕上。这个过程会发生回流和重绘）。&lt;/li&gt;
&lt;li&gt;连接结束 -&amp;gt; 断开TCP连接 四次挥手&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;梳理出主干骨架，然后就需要往骨架上填充细节内容。&lt;/p&gt;
&lt;p&gt;接下来重点介绍“浏览器渲染过程中的网络层面”。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="二浏览器接收url并开启一个新进程"&gt;二、浏览器接收url并开启一个新进程&lt;/h2&gt;
&lt;p&gt;这部分内容开始之前我们需要先通过一张图对 进程 和 线程 的关系有一个初步的了解。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/network/network-019/image-01.webp"&gt;&lt;/p&gt;
&lt;h3 id="1-浏览器是多进程的"&gt;1. 浏览器是多进程的&lt;/h3&gt;
&lt;p&gt;浏览器是多进程的，有一个主进程，每打开一个tab页面都会新开一个&lt;strong&gt;进程&lt;/strong&gt;（某些情况下多个tab会合并进程）。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：在这里浏览器应该也有自己的优化机制，有时候打开多个tab页后，比如打开多个空白标签页。可以在Chrome任务管理器中看到，进程被合并了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;进程可能包括主进程，插件进程，GPU，tab页（浏览器内核）等等。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Browser进程&lt;/strong&gt;：浏览器的主进程（负责协调、主控），只有一个。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第三方插件进程&lt;/strong&gt;：每种类型的插件对应一个进程，仅当使用该插件时才创建。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPU进程&lt;/strong&gt;：最多一个，用于3D绘制等。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;浏览器渲染进程&lt;/strong&gt;（浏览器内核）（内部是多线程的）：默认每个Tab页面一个进程，互不影响。作用是页面渲染，脚本执行，事件处理等。（浏览器有时候会优化，如多个空白页合并成一个进程）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;强化记忆：&lt;strong&gt;&lt;code&gt;在浏览器中打开一个网页相当于新起了一个进程（进程内有自己的多线程）&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;下图以 chrome浏览器 为例。我们可以自己通过Chrome的更多工具 =》 任务管理器 自行验证查看，可以看到chrome的任务管理器中有多个进程（分别是每一个Tab页面有一个独立的进程，以及一个主进程）&lt;br&gt;
然后能看到每个进程的内存资源信息以及cpu占有率。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/network/network-019/image-02.webp"&gt;&lt;/p&gt;
&lt;h3 id="2-浏览器内核是多线程的"&gt;2. 浏览器内核是多线程的&lt;/h3&gt;
&lt;p&gt;每一个tab页面可以看作是浏览器内核的一个进程，然后这个进程是多线程的，它有几大类子线程&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GUI渲染线程&lt;/strong&gt;：负责渲染浏览器界面，解析HTML，CSS，构建DOM树和RenderObject树，布局和绘制等。&lt;code&gt;GUI渲染线程与JS引擎线程是互斥的&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JS引擎线程&lt;/strong&gt;：也叫 JS 内核，负责解析执行 JS 脚本程序的主线程，例如 V8 引擎。JS引擎一直等待着任务队列中任务的到来，然后加以处理，一个Tab页（renderer进程）中无论什么时候都只有一个JS线程在运行JS程序。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;事件触发线程&lt;/strong&gt;：属于浏览器内核线程，主要用于控制事件，例如鼠标、键盘等，当事件被触发时，就会把事件的处理函数推进事件队列，等待 JS 引擎线程执行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定时器触发线程&lt;/strong&gt;：主要控制 setInterval和 setTimeout，用来计时，计时完毕后，则把定时器的处理函数推进事件队列中，等待 JS 引擎线程。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;异步http请求线程&lt;/strong&gt;：通过XMLHttpRequest连接后，通过浏览器新开的一个线程，监控readyState状态变更时，如果设置了该状态的回调函数，则将该状态的处理函数推进事件队列中，等待JS引擎线程执行。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/network/network-019/image-03.webp"&gt;&lt;/p&gt;</description></item></channel></rss>