输入url后回车发生了什么(持续更新)

在大多数情况下,浏览器被认为是单线程的。也就是说,他们从头到尾执行一项任务,然后再开始另一项任务。为了实现流畅的交互,开发人员的目标是确保高性能的站点交互,从平滑滚动到触摸响应。渲染时间是关键,确保主线程可以完成我们交给它的所有工作,并且仍然始终可以处理用户交互。通过了解浏览器的单线程性质并在可能和适当的情况下最大程度地减少主线程的职责,以确保渲染顺利并且对交互的响应立即响应,可以提高 Web 性能。

导航:DNS解析

导航是加载网页的第一步。每当用户通过在地址栏中输入 URL、单击链接、提交表单以及其他操作来请求页面时,就会发生这种情况。

Web 性能的目标之一是最大限度地减少完成导航所需的时间。在理想条件下,这通常不会花费太长时间,但延迟和带宽是可能导致延迟的敌人。

DNS查询

导航到网页的第一步是查找该页面的资源所在的位置。如果您导航到https://example.com,HTML 页面位于 IP 地址为 的服务器上93.184.216.34。如果您从未访问过此站点,则必须进行 DNS 查找。

您的浏览器请求 DNS 查找,该查找最终由名称服务器进行处理,而名称服务器又以 IP 地址进行响应。在此初始请求之后,IP 可能会被缓存一段时间,这通过从缓存中检索 IP 地址而不是再次联系名称服务器来加速后续请求。

对于页面加载,通常只需为每个主机名执行一次 DNS 查找。但是,必须对请求页面引用的每个唯一主机名进行 DNS 查找。如果您的字体、图像、脚本、广告和指标都具有不同的主机名,则必须对每一个进行 DNS 查找。

这可能会影响性能,尤其是在移动网络上。当用户使用移动网络时,每次 DNS 查找都必须从手机到手机信号塔才能到达权威 DNS 服务器。电话、手机信号塔和名称服务器之间的距离会显着增加延迟。

握手:TCP连接

一旦知道 IP 地址,浏览器就会通过TCP 三向握手建立与服务器的连接。这种机制的设计使得尝试通信的两个实体(在本例中为浏览器和 Web 服务器)可以在传输数据之前协商网络 TCP 套接字连接的参数(通常通过HTTPS)。

TCP 的三向握手技术通常称为“SYN-SYN-ACK”,或更准确地说是 SYN、SYN-ACK、ACK,因为 TCP 传输三个消息来协商并启动两台计算机之间的 TCP 会话。是的,这意味着每个服务器之间还要来回三个消息,并且请求尚未发出。

TLS 协商

对于通过 HTTPS 建立的安全连接,需要再次“握手”。此握手(或者更确切地说TLS协商)确定将使用哪个密码来加密通信、验证服务器并在开始实际数据传输之前建立安全连接。在实际发送内容请求之前,这还需要与服务器进行五次以上的往返。

虽然确保连接安全会增加页面加载时间,但安全连接值得付出延迟代价,因为浏览器和 Web 服务器之间传输的数据无法被第三方解密。

经过八次与服务器的往返之后,浏览器终于​​能够发出请求。

发送:HTTP请求

一旦我们与 Web 服务器建立了连接,浏览器就会代表用户发送初始HTTP GET请求,对于网站来说,该请求通常是 HTML 文件。

回复:HTTP相应

服务器收到请求后,会回复相关的响应头和 HTML 内容。

该初始请求的响应包含接收到的数据的第一个字节。第一个字节的时间(TTFB) 是用户发出请求(例如通过单击链接)到收到第一个 HTML 数据包之间的时间。第一个内容块通常是 14KB 的数据。

在我们上面的例子中,请求肯定小于14KB,但是直到浏览器在解析过程中遇到链接时才会请求链接的资源,如下所述。

拥塞控制/TCP慢启动

TCP 数据包在传输过程中被分成段。由于 TCP 保证数据包的顺序,因此服务器在发送一定数量的数据段后必须收到客户端以 ACK 数据包形式的确认。

如果服务器在每个数据段后等待 ACK,那么即使在低负载网络的情况下,也会导致来自客户端的频繁 ACK 并可能增加传输时间。

另一方面,一次发送太多报文段可能会导致这样的问题:在繁忙的网络中,客户端将无法接收报文段,并且会在很长一段时间内保持以 ACK 进行响应,而服务器则必须保持重新发送片段。

为了平衡传输的报文段数量,采用TCP慢启动算法逐渐增加传输的数据量,直到可以确定最大网络带宽,并在网络负载较高的情况下减少传输的数据量。

传输的报文段数由拥塞窗口(CWND)的值控制,可以初始化为1、2、4或10个MSS(以太网协议上的MSS为1500字节)。该值是要发送的字节数,客户端收到该字节后必须发送 ACK。

如果收到 ACK,则 CWND 值将加倍,因此服务器下次将能够发送更多数据段。如果没有收到 ACK,则 CWND 值将减半。因此,该机制在发送太多分段和发送太少分段之间实现了平衡。

解析:HTML渲染

一旦浏览器接收到第一块数据,它就可以开始解析接收到的信息。解析是浏览器将通过网络接收到的数据转换为DOM和CSSOM 的步骤,渲染器使用它们将页面绘制到屏幕上。

DOM 是浏览器标记的内部表示。DOM 也是公开的,可以通过 JavaScript 中的各种 API 进行操作。

即使请求页面的 HTML 大于初始 14KB 数据包,浏览器也会开始解析并尝试根据其拥有的数据呈现体验。这就是为什么在前 14KB 中包含浏览器开始渲染页面所需的所有内容,或者至少包含页面模板(首次渲染所需的 CSS 和 HTML)对于 Web 性能优化非常重要的原因。但在将任何内容呈现到屏幕上之前,必须解析 HTML、CSS 和 JavaScript。

构建 DOM 树

我们描述了关键渲染路径中的五个步骤。

第一步是处理 HTML 标记并构建 DOM 树。HTML 解析涉及标记化和树构建。HTML 标记包括开始和结束标记,以及属性名称和值。如果文档格式良好,则解析它会直接且更快。解析器将标记化输入解析到文档中,构建文档树。

DOM 树描述了文档的内容。该<html>元素是文档树的第一个元素和根节点。树反映了不同元素之间的关系和层次结构。嵌套在其他元素中的元素是子节点。DOM 节点的数量越多,构建 DOM 树所需的时间就越长。

当解析器找到非阻塞资源(例如图像)时,浏览器将请求这些资源并继续解析。当遇到 CSS 文件时,解析可以继续,但<script>元素(尤其是那些没有asyncordefer属性的元素)会阻止渲染,并暂停 HTML 的解析。尽管浏览器的预加载扫描程序加速了这一过程,但过多的脚本仍然可能是一个重要的瓶颈。

预装扫描仪

当浏览器构建 DOM 树时,这个过程占用主线程。发生这种情况时,预加载扫描器将解析可用内容并请求高优先级资源,例如 CSS、JavaScript 和 Web 字体。感谢预加载扫描器,我们不必等到解析器找到对外部资源的引用来请求它。它将在后台检索资源,以便当主 HTML 解析器到达所请求的资源时,它们可能已经在运行或已被下载。预加载扫描仪提供的优化可减少阻塞。

<link rel="stylesheet" href="styles.css" />
<script src="myscript.js" async></script>
<img src="myimage.jpg" alt="image description" />
<script src="anotherscript.js" async></script>

在此示例中,当主线程解析 HTML 和 CSS 时,预加载扫描器将找到脚本和图像,并开始下载它们。为了确保脚本不会阻止进程,请添加该async属性,defer如果 JavaScript 解析和执行顺序很重要,则添加该属性。

等待获取 CSS 不会阻止 HTML 解析或下载,但它会阻止 JavaScript,因为 JavaScript 经常用于查询 CSS 属性对元素的影响。

构建 CSSOM 树

关键渲染路径的第二步是处理 CSS 并构建 CSSOM 树。CSS 对象模型类似于 DOM。DOM 和 CSSOM 都是树。它们是独立的数据结构。浏览器将 CSS 规则转换为它可以理解和使用的样式映射。浏览器遍历 CSS 中的每个规则集,根据 CSS 选择器创建具有父、子和兄弟关系的节点树。

与 HTML 一样,浏览器需要将接收到的 CSS 规则转换为它可以使用的内容。因此,它重复 HTML 到对象的过程,但对于 CSS。

CSSOM 树包含来自用户代理样式表的样式。浏览器从适用于节点的最通用规则开始,并通过应用更具体的规则递归地细化计算的样式。换句话说,它级联了属性值。

构建 CSSOM 非常非常快,并且在当前的开发人员工具中不会以独特的颜色显示。相反,开发人员工具中的“重新计算样式”显示了解析 CSS、构建 CSSOM 树和递归计算计算样式所需的总时间。在 Web 性能优化方面,有一些唾手可得的成果,因为创建 CSSOM 的总时间通常小于一次 DNS 查找所需的时间。

其他工艺

JavaScript 编译

在解析 CSS 并创建 CSSOM 的同时,正在下载其他资源,包括 JavaScript 文件(感谢预加载扫描器)。JavaScript 被解析、编译和解释。脚本被解析为抽象语法树。一些浏览器引擎采用抽象语法树并将它们传递给编译器,输出字节码。这称为 JavaScript 编译。大部分代码在主线程上解释,但也有例外,例如在Web Workers中运行的代码。

构建可访问性树

浏览器还构建辅助设备用来解析和解释内容的可访问性树。可访问性对象模型 (AOM) 就像 DOM 的语义版本。当 DOM 更新时,浏览器也会更新可访问性树。辅助技术本身无法修改辅助功能树。

在构建 AOM 之前,屏幕阅读器无法访问内容。

渲染

渲染步骤包括样式、布局、绘制,在某些情况下还包括合成。在解析步骤中创建的 CSSOM 和 DOM 树被组合成渲染树,然后使用该渲染树计算每个可见元素的布局,然后将其绘制到屏幕上。在某些情况下,内容可以提升到其自己的层并进行合成,通过在 GPU 而不是 CPU 上绘制部分屏幕来提高性能,从而释放主线程。

风格

关键渲染路径的第三步是将 DOM 和 CSSOM 组合成渲染树。计算样式树或渲染树的构造从 DOM 树的根开始,遍历每个可见节点。

不会显示的元素(例如<head>元素及其子元素以及带有 的任何节点display: none(例如script { display: none; }您在用户代理样式表中找到的 ))不会包含在渲染树中,因为它们不会出现在渲染输出中。应用的节点visibility: hidden包含在渲染树中,因为它们确实占用空间。由于我们没有给出任何指令来覆盖用户代理默认值,因此script上面代码示例中的节点将不会包含在渲染树中。

每个可见节点都应用了其 CSSOM 规则。渲染树保存所有具有内容和计算样式的可见节点 - 将所有相关样式与 DOM 树中的每个可见节点进行匹配,并根据 CSS 级联确定每个节点的计算样式。

布局

关键渲染路径的第四步是在渲染树上运行布局以计算每个节点的几何形状。布局是确定渲染树中所有节点的尺寸和位置,以及确定页面上每个对象的大小和位置的过程。回流是页面或整个文档的任何部分的任何后续尺寸和位置确定。

一旦构建了渲染树,布局就开始了。渲染树识别显示哪些节点(即使不可见)及其计算样式,但不识别每个节点的尺寸或位置。为了确定每个对象的确切大小和位置,浏览器从渲染树的根开始并遍历它。

在网页上,几乎所有东西都是一个盒子。不同的设备和不同的桌面首选项意味着无限数量的不同视口大小。在此阶段,考虑到视口大小,浏览器确定屏幕上所有不同框的大小。以视口的大小为基础,布局通常从主体开始,布置所有主体后代的尺寸,以及每个元素的盒模型属性,为不知道尺寸的替换元素提供占位符空间,例如作为我们的形象。

第一次确定每个节点的大小和位置称为布局。随后的重新计算称为回流。在我们的示例中,假设初始布局发生在返回图像之前。由于我们没有声明图像的尺寸,因此一旦知道图像尺寸就会进行回流。

重绘

关键渲染路径的最后一步是将各个节点绘制到屏幕上,第一次出现称为第一个有意义的绘制。在绘画或光栅化阶段,浏览器将布局阶段计算的每个框转换为屏幕上的实际像素。绘画涉及将元素的每个视觉部分绘制到屏幕上,包括文本、颜色、边框、阴影以及按钮和图像等替换元素。浏览器需要非常快地完成此操作。

为了确保平滑的滚动和动画,所有占用主线程的事情,包括计算样式、回流和绘制,都必须让浏览器在 16.67 毫秒以内完成。在 2048 x 1536 分辨率下,iPad 有超过 3,145,000 个像素可绘制到屏幕上。这是大量必须快速绘制的像素。为了确保重新绘制比初始绘制更快,屏幕上的绘图通常分为几个层。如果发生这种情况,则需要进行合成。

绘画可以将布局树中的元素分解为图层。将内容提升到 GPU 上的图层(而不是 CPU 上的主线程)可提高绘制和重绘制性能。有一些特定的属性和元素可以实例化图层,包括<video>和<canvas>,以及任何具有 CSS 属性opacity、 3D transform、will-change和其他一些元素。这些节点将与其后代一起绘制到它们自己的层上,除非后代由于上述一个(或多个)原因需要自己的层。

层确实可以提高性能,但在内存管理方面成本高昂,因此不应过度使用作为 Web 性能优化策略的一部分。

合成

当文档的各个部分绘制在不同的层中且彼此重叠时,需要进行合成以确保它们以正确的顺序绘制到屏幕上并正确呈现内容。

当页面继续加载资源时,可能会发生重排(回想一下我们迟到的示例图像)。回流引发了重新绘制和重新合成。如果我们定义了图像的尺寸,则不需要回流,并且只有需要重新绘制的图层才会被重新绘制,并在必要时进行合成。但我们没有包括图像尺寸!从服务器获取图像后,渲染过程将返回到布局步骤并从那里重新开始。

互动性

一旦主线程完成页面绘制,您可能会认为我们已经“准备就绪”。情况不一定如此。如果加载包含 JavaScript,则该加载已正确延迟,并且仅在onload事件触发后执行,则主线程可能很忙,并且无法用于滚动、触摸和其他交互。

交互时间(TTI) 是衡量从导致 DNS 查找和 TCP 连接的第一个请求到页面交互所需时间的时间 — 交互是页面响应第一次内容绘制之后的时间点50 毫秒内的用户交互。如果主线程被占用解析、编译和执行 JavaScript,则它不可用,因此无法及时(小于 50 毫秒)响应用户交互。

在我们的示例中,也许图像加载得很快,但anotherscript.js文件可能有 2MB,而我们用户的网络连接速度很慢。在这种情况下,用户会非常快地看到页面,但在下载、解析和执行脚本之前无法滚动而不出现卡顿。这不是一个好的用户体验。避免占用主线程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/577696.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Wireshark网络工具来了

Wireshark是网络包分析工具。网络包分析工具的主要作用是尝试捕获网络包&#xff0c;并尝试显示包的尽可能详细的情况。 Wireshark是一个免费开源软件&#xff0c;不需要付费&#xff0c;免费使用&#xff0c;可以直接登陆到Wireshark的官网下载安装。 在windows环境中&#x…

FPFA.一种二倍频电路代码描述以及测量详情

一、前言 1、因为需要倍频电路所以找了个二倍频的电路&#xff0c;通过fpga实际测量发现经过倍频后的电路峰值降低。不过这个也正常&#xff0c;因为该电路只要过触发点就会开始发生波形变化&#xff0c;而电路的触发值不是峰值。​​​​​​​ 2、继续对电路做倍频后信号做二…

LeetCode_Java判断给出的字符串是否是合法的括号序列

public class BracketSequence {public static void main(String[] args) {System.out.println(isValid("([])"));}public static boolean isValid(String s) {if(snull || s.length()0){return true;}//新建栈&#xff0c;用以存储左括号Stack<Character> sta…

嵌入式开发常见的3个C语言技巧

​1.操作寄存器 在嵌入式开发中&#xff0c;常常要操作寄存器&#xff0c;对寄存器进行写入&#xff0c;读出等等操作。每个寄存器都有自己固有的地址&#xff0c;通过C语言访问这些地址就变得尤为重要。 #define GSTATUS1 (*(volatile unsigned int *)0x560000B0)在这里…

国外加固Appdome环境检测与绕过

文章目录 前言第一部分&#xff1a;定位检测逻辑的通用思路1. 通过linux“一切皆文件”思路定位2. 分析现有检测软件猜测可能检测点3. 通过正向开发思路定位4. 通过activity及弹窗定位 第二部分&#xff1a;检测结果展示整体流程1. Jni反射调用doDispath完成广播发送2. NativeB…

第11章 GUI Page439 步骤十二 为图元编号 支持直线

运行效果&#xff1a; 关键代码&#xff1a; 为IItem类新增三个函数&#xff0c;两个纯虚 为直线类&#xff0c;新增一个_index成员&#xff0c;并实现GetIndex和SetIndex两个函数 窗口类新增一个 _item_id成员&#xff0c;并初始化 在将图元压入队列之前&#xff0c;设置图元…

多继承与多重继承

多继承与多重继承 实验介绍 多继承与多重继承虽然只相差一个字,但是却是两个不同的概念。实验首先是要区分多继承与多重继承,其次是要学习多继承与多重继承的使用方式。 知识点 多继承与多重继承概念继承构造函数多继承与多重继承概念 多继承与多重继承可以从字面上理解。…

IDEA2018升级2023,lombok插件不兼容导致get/set方法无法使用

1、问题 最近了解到一款叫CodeGeeX 的智能编程助手&#xff0c;想要试用一下&#xff0c;但是IDEA2018版本太低了&#xff0c;没有CodeGeeX插件&#xff0c;于是打算将IDEA升级到2023.2.5版本&#xff0c;具体升级过程略过&#xff0c;升级完成后&#xff0c;启动项目&#xf…

图像去噪综述

传统方法 最经典最新的图像去噪算法 (360doc.com) 图像去噪算法综述 - 百度文库 (baidu.com) 传统图像去噪总结_传统图像降噪算法-CSDN博客 图像降噪有哪些方法&#xff1f; (qq.com) 深度学习方法 综述 | 图像去噪方法比较 (qq.com)

【强化学习】PPO:近端策略优化算法

近端策略优化算法 《Proximal Policy Optimization Algorithms》 论文地址&#xff1a;https://arxiv.org/pdf/1707.06347.pdf 一、 置信域方法(Trust Region Methods) ​ 设 π θ o l d \pi_{\theta_{old}} πθold​​是先前参数为 θ o l d \theta_{old} θold​的策略网…

市场复盘总结 20231225

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整 昨日回顾&#xff1a; SELECT CODE,成交额排名,净流入排名,代码,名称,DDE大单金额,涨幅,主力净额,DDE大单净量,CONVERT(DATETIME, 最后封…

C++入门编程一(基本框架代码、宏定义、标识符、数据类型)

文章目录 一、基本框架代码解释多行注释缩进自动排版宏定义关键字 标识符命名规则标识符sizeof()关键字实型(浮点型)字符型转义字符字符串类型布尔类型数据的输入 基于b站黑马c视频做的笔记&#xff0c;仅供参考和复习&#xff01;&#xff01;&#xff01; 一、基本框架代码解…

Java Web Day07-08_Layui

1. Layui概念介绍 layui&#xff08;谐音&#xff1a;类 UI) 是一套开源的 Web UI 解决方案&#xff0c;采用自身经典的模块化规范&#xff0c;并遵循原生 HTML/CSS/JS 的开发方式&#xff0c;极易上手&#xff0c;拿来即用。其风格简约轻盈&#xff0c;而组件优雅丰盈&#x…

【算法集训】基础数据结构:十三、哈希表

今天是基础数据结构的最后一个。至此我们的基础数据结构系列就结束了!!! 这几天先告一段落&#xff0c;等期末考试完继续更新算法系列。 哈希表又叫散列表&#xff0c;通常用数组来实现&#xff0c;又叫做哈希数组。 一、概念 常用哈希函数 1、直接定址法&#xff1b; 关键字…

返利机器人赚佣金工作原理及实现思路探索

返利机器人赚佣金工作原理及实现思路探索 大家好&#xff0c;我是免费搭建查券返利机器人赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天&#xff0c;我将带大家深入探索返利机器人的工作原理和实现思路&…

C++成员函数的两种实现

文章目录 前言一、类内实现二、类外实现 前言 C 中成员函数两种实现&#xff1a; 类内实现 和 类外实现。 一、类内实现 在定义类的时候&#xff0c;直接定义了函数体。 #include <iostream> using namespace std; class Point {public:void setPoint(int x, int y)…

overtureDNS使用介绍

Overture是一个定制的DNS中继服务器。 在此下在二进制版本 https://github.com/shawn1m/overture/releases默认配置文件./config.yml bindAddress: :53 debugHTTPAddress: 127.0.0.1:5555 dohEnabled: false primaryDNS:- name: DNSPodaddress: 119.29.29.29:53protocol: udp…

Python Opencv实践 - 人体姿态检测

本文仍然使用mediapipe做练手项目&#xff0c;封装一个PoseDetector类用作基础姿态检测类。 mediapipe中人体姿态检测的结果和手部跟踪检测的结果是类似的&#xff0c;都是输出一些定位点&#xff0c;各个定位点的id和对应人体的位置如下图所示&#xff1a; 关于mediapipe的pos…

Fastjson中关于json的处理与配置

Fastjson是一个Java语言编写的高性能的JSON处理器,由阿里巴巴公司开发。 无依赖&#xff0c;不需要例外额外的jar&#xff0c;能够直接跑在JDK上。 FastJson在复杂类型的Bean转换Json上会出现一些问题&#xff0c;可能会出现引用的类型&#xff0c;导致Json转换出错&#xff0c…

案例分析:三一重工集团数字化转型

三一重工集团&#xff0c;作为制造业中的数字化转型佼佼者&#xff0c;荣获“全球灯塔工厂”的殊荣&#xff0c;率先采用了物联网、云计算、大数据等尖端技术手段。数字化转型让三一重工步入了全面信息化的管理时代&#xff0c;通过ERP、CRM、HRM等系统的协同运作&#xff0c;实…