<?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>输入 URL 到页面渲染完成 on Last Stand</title><link>https://amatsuzero.github.io/LastStand/tags/%E8%BE%93%E5%85%A5-url-%E5%88%B0%E9%A1%B5%E9%9D%A2%E6%B8%B2%E6%9F%93%E5%AE%8C%E6%88%90/</link><description>Recent content in 输入 URL 到页面渲染完成 on Last Stand</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Wed, 06 Nov 2024 00:00:00 +0800</lastBuildDate><atom:link href="https://amatsuzero.github.io/LastStand/tags/%E8%BE%93%E5%85%A5-url-%E5%88%B0%E9%A1%B5%E9%9D%A2%E6%B8%B2%E6%9F%93%E5%AE%8C%E6%88%90/index.xml" rel="self" type="application/rss+xml"/><item><title>输入 URL 到页面渲染完成</title><link>https://amatsuzero.github.io/LastStand/posts/frontend/html/html-024/</link><pubDate>Tue, 05 Nov 2024 00:00:00 +0800</pubDate><guid>https://amatsuzero.github.io/LastStand/posts/frontend/html/html-024/</guid><description>&lt;h2 id="一网站加载概述"&gt;一、网站加载概述&lt;/h2&gt;
&lt;p&gt;面试过程中，常常遇到这样一道面试题，输入URL到页面加载完毕，浏览器做了哪些工作？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;首先输入一个URL，你会看到浏览器上面的标签页出现了一个loading图标，开始时是逆时针旋转，接着顺时针旋转，当前页面消失，显示我们常说的空白页面，接着出现显示我们请求的新页面。此时如果网络很差，你有可能看到短暂的DOM页面，然后再看到渲染后的正常页面，这是从表面看到的加载过程，实际浏览器做的要多得多。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;为什么浏览器这么多戏呢？直接显示不好吗，当然不行，就像喝粥，能直接吃米、喝水吗？&lt;/p&gt;
&lt;p&gt;在用户输入URL到页面展示，浏览器要先向服务器获取前端资源，然后再将服务器返回的字节流转化成对应的页面，每一阶段都需要浏览器对应的能力进行处理的。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;作为前端开发，了解整个过程其实很重要，只有知道了浏览器加载页面的整个过程，才能在开发中避免可能跳的坑，才能在发现问题后迅速定位问题，才能在性能优化时提出更多的解决方案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;比如下面问题，看了文章相信你就知道了为什么了&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;为什么会存在空白页面？(为了解决这个问题，各大厂都在实践各种方案）&lt;/li&gt;
&lt;li&gt;为什么js要在Dom后面引入&lt;/li&gt;
&lt;li&gt;为什么有个页面崩溃会导致多个页面崩溃&lt;/li&gt;
&lt;li&gt;浏览器的缓存策略是怎样的？&lt;/li&gt;
&lt;li&gt;为什么我们常常修改host就可以访问对应的域名&lt;/li&gt;
&lt;li&gt;等等&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="二浏览器的多进程架构"&gt;二、浏览器的多进程架构&lt;/h2&gt;
&lt;p&gt;为了看懂下面的内容，这里必须要了解下现代浏览器的&lt;code&gt;多进程架构&lt;/code&gt;，&lt;code&gt;进程&lt;/code&gt;和&lt;code&gt;线程&lt;/code&gt;的关系等知识点。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;浏览器也是从单个进程架构一步步迭代到现代的多进程架构。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/html/html-024/image-01.webp"&gt;&lt;/p&gt;
&lt;p&gt;如上图，我们可以看到&lt;code&gt;线程&lt;/code&gt;和&lt;code&gt;进程&lt;/code&gt;的关系&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;通常一个程序实例就是一个进程，浏览器会为他分配内存空间。&lt;/li&gt;
&lt;li&gt;一个进程间的数据是共享的，单线程就是一个进程包含一个线程，一个线程处理所有的任务&lt;/li&gt;
&lt;li&gt;多线程就是，一个进程中包含多个线程可以同时执行任务，共享数据和内存&lt;/li&gt;
&lt;li&gt;线程不能单独存在，必须依附于进程，一个线程失败，会导致进程执行失败，进程销毁，内存会被立即回收。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="1进程"&gt;1、进程&lt;/h3&gt;
&lt;p&gt;下图是我们打开一个掘金首页后，再打开任务管理器，观察发现，此时浏览器包括的进程有很多，浏览器主进程，GPU进程，网络进程，存储进程，音频进程，渲染进程，多个插件进程。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/html/html-024/image-02.webp"&gt;&lt;/p&gt;
&lt;p&gt;这些进程负责的功能如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;进程&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;浏览器进程&lt;/td&gt;
&lt;td&gt;负责浏览器各个子进程的通信，处理浏览器界面，包括地址栏等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;渲染进程&lt;/td&gt;
&lt;td&gt;也就是我们看到的图中的标签页进程，也就是我们常说的浏览器内核，v8就在这个进程。主要负责解析html、js、css渲染页面等&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;网络进程&lt;/td&gt;
&lt;td&gt;负责发起网络请求，解析返回头信息&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GUI进程&lt;/td&gt;
&lt;td&gt;负责将渲染进程生成的图块转化成位图&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;渲染进程是运行在沙箱之中的，可以执行js，但是不能获取系统权限，和浏览器进程通过IPC通讯。这是为了保证浏览器进程的安全，锁进沙箱，即使有恶意代码，也不能突破沙箱读取或写入系统信息。&lt;/p&gt;
&lt;h3 id="2线程"&gt;2、线程&lt;/h3&gt;
&lt;p&gt;通过上图，我们已经知道线程是不能独立存在的，必须依附于进程。这里我们主要关注下渲染进程，因为他的主要工作就是：完成页面的渲染和展示。&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://amatsuzero.github.io/LastStand/posts/frontend/html/html-024/image-03.webp"&gt;&lt;/p&gt;
&lt;p&gt;如图，我们可以看到渲染进程包括很多线程，除了图上展示的，还有合成线程等，各有各的作用，具体内容，我们将会在后面一章节，浏览器渲染原理分析中在来讨论。&lt;/p&gt;
&lt;h2 id="三浏览器请求的具体流程"&gt;三、浏览器请求的具体流程&lt;/h2&gt;
&lt;p&gt;从用户输入域名到浏览器渲染页面完成的过程，可以分为以下几个部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1、输入信息处理&lt;/li&gt;
&lt;li&gt;2、网络请求&lt;/li&gt;
&lt;li&gt;3、服务器返回请求资源&lt;/li&gt;
&lt;li&gt;4、浏览器渲染&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里每一步涉及到的知识都非常多，其中缓存也在每个阶段占了很大比重，接着展开描述前三个阶段：&lt;/p&gt;
&lt;h3 id="1地址栏输入信息处理"&gt;1、地址栏输入信息处理&lt;/h3&gt;
&lt;p&gt;当输入一个URL，浏览器会判断输入信息是检索信息还是请求URL&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果是检索的信息，就构建请求搜索的URL，调用浏览器默认的搜索引擎进行检索。&lt;/li&gt;
&lt;li&gt;如果符合URL格式，浏览器主进程就通过IPC通信机制将URL发送给网络进程。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2网络进程发起网络请求"&gt;2、网络进程发起网络请求&lt;/h3&gt;
&lt;p&gt;1）网络进程首先会查找浏览器缓存，判断缓存是否存在，是否过期&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果存在且不过期，就直接返回缓存信息。具体的缓存策略可以接着看下面的&lt;a href="https://fe.ecool.fun/knowledge-learn#cache"&gt;浏览器缓存策略&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2）如果没有缓存或过期，就开始进行DNS解析&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DNS解析的过程也很复杂，最终目的就是拿到目标主机的IP地址，具体的解析过程可以看下面的域名解析&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3）建立http连接或https连接&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;http通过三次握手建立连接&lt;/li&gt;
&lt;li&gt;https需要建立TLS连接，浏览器会验证网站的数字证书是否合法，是否到期，是否安全等，这里https有自己的一套认证逻辑，我们重点不在这一块。&lt;/li&gt;
&lt;li&gt;这里两个问题常被问到，不了解可以学习一下&lt;br&gt;
&lt;ul&gt;
&lt;li&gt;http和https的区别？&lt;/li&gt;
&lt;li&gt;简述三次握手、四次挥手？&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4）发送请求&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;网络进程会构建http请求头，向服务器发送实际请求&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;5）网络传输，服务器处理，返回对应的资源&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;请求从应用层发出，经过运输层、网络层、物理层、数据链路层找到服务器，服务器拿到请求信息，返回对应的资源&lt;/li&gt;
&lt;li&gt;这里的服务器可能是代理服务器，也可能是CDN节点，会判断当前数据是否存在缓存，如果有缓存且有效，直接返回（具体看配置的缓存策略），否则才会从服务器获取。&lt;/li&gt;
&lt;li&gt;网络传输数据也是很复杂的过程，具体可以看下面简单的介绍&lt;a href="https://fe.ecool.fun/knowledge-learn#net"&gt;计算机网络体系模型&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="3服务器返回对应资源"&gt;3、服务器返回对应资源&lt;/h3&gt;
&lt;p&gt;1）处理返回信息&lt;/p&gt;</description></item></channel></rss>