网站性能优化—CRP

2023-11-24 10:59
文章标签 网站 优化 性能 crp

本文主要是介绍网站性能优化—CRP,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

为了把HTML、CSS和JavaScript转化成活灵活现、绚丽多彩的网页,浏览器需要处理一系列的中间过程,优化性能其实就是了解这个过程中发生了什么-即CRP(Critical Rendering Path,关键渲染路径)。首先,我们从头开始快速学习一下浏览器是如何显示一个简单网页的。

浏览器渲染一个网页的过程

构建对象模型

文档对象模型(DOM)
<html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet"><title>Critical Path</title></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div></body>
</html>

一个普通的页面,里面包含一些文本和一张图片,浏览器是如何处理这个页面的呢?
clipboard.png

  1. 转换:浏览器从磁盘或网络读取HTML的原始字节,然后根据指定的文件编码格式(例如 UTF-8)将其转换为相应字符

  2. 令牌化:浏览器把字符转化成W3C HTML5 标准指定的各种确切的令牌,比如"<html>"、"<body>"以及其他在尖括号内的字符串。每个令牌都有特殊的含义以及它自己的一套规则

  3. 词法分析:生成的令牌转化为对象,这个对象定义了它们的属性及规则

  4. DOM构建:最后,由于HTML标记定义了不同标签之间的关系(某些标签嵌套在其他标签中),创建的对象在树状的数据结构中互相链接,树状数据结构也捕获了原始标签定义的父子关系:HTML对象是body对象的父对象,bodyp对象的父对象等等
    clipboard.png

上述整个流程的最终输出是文档对象模型,即这个简单网页的 "DOM",浏览器完成页面的所有后续处理都是建立在这个DOM基础上的。
打开Chrome DevTools > Timeline,录制时间轴,上述过程对应Loading事件中的Parse HTML事件,可以查看到执行这一过程所需要的时间。
DOM树捕获了文档标记的属性及关系,但它没有告诉我们元素在渲染时是什么样子的。这是CSSOM要干的活,也就是接下来要讲的。

CSS对象模型(CSSOM)

当浏览器构建上述网页DOM的时候,在head里面碰到一个link标签,这个标签引用了一个外部的CSS样式表:style.css。浏览器预测会需要这个资源来渲染页面,因此会立即发出一个该资源的请求,该请求返回以下内容:

body { font-size: 16px }
p { font-weight: bold }
span { color: red }
p span { display: none }
img { float: right }

与HTML一样,我们需要将收到的 CSS 规则转换为浏览器可以理解、能够处理的东西。因此,我们重复与处理 HTML 非常相似的过程:
clipboard.png

最终输出的是CSS对象模型,即CSSOM。
clipboard.png

想要查看CSS处理过程所花费的时间,可以在录制的时间轴中查看Rendering事件中的Recalculate Style事件:与DOM解析不同,timeline不显示单独的“Parse CSS”条目,而是在Recalculate Style事件下一同捕获CSS解析CSSOM构建以及computed styles的递归计算

构建渲染树、布局及绘制

前面介绍了我们根据输入的HTML及CSS构建了DOM树和CSSOM树,但二者是独立的对象:DOM描述的是文档内容,CSSOM描述的是应用于文档的样式规则。浏览器会把DOM和CSSOM组合起来构建一个渲染树(Render-tree),渲染树会捕获页面上所有可见的DOM内容以及应用在每个节点上的CSSOM样式。

clipboard.png

构建渲染树的过程大致如下:

  1. 从DOM树的根节点开始,遍历每个可见的节点

    • 某些节点不可见(例如 script 标签、meta 标签等),因为它们不会体现在渲染结果中,所以会被忽略

    • 某些通过 CSS 隐藏的节点在渲染树中也会被忽略,比如应用了 display:none 规则的节点

  2. 为每一个可见的节点匹配并应用对应的CSSOM规则

  3. 生成有内容计算样式的可见节点

小提示:注意visibility: hiddendisplay: none二者的区别。visibility: hidden只是让元素在视觉上不可见,但是元素在页面布局中仍然占据空间。而display: none则是从渲染树中删除某一个元素,不仅视觉上不可见,渲染树上也没有,更不会影响到页面的布局。

最终输出的就是一个包含了所有可见节点的内容及样式信息的渲染树。

到目前为止,我们已经计算出了哪些节点是可见的以及它们的计算样式,但是我们还没有计算它们在设备视口(viewport)中的准确位置及尺寸大小——这就是布局(Layout)阶段要做的工作,也就是常说的重排(reflow)

为了计算出页面中每个对象的准确大小和位置,浏览器从渲染树的根节点开始遍历,计算页面上每个对象的几何信息。举例如下:

<html><head><meta name="viewport" content="width=device-width,initial-scale=1"><title>Critial Path: Hello world!</title></head><body><div style="width: 50%"><div style="width: 50%">Hello world!</div></div></body>
</html>

上面页面的 body 包含两个嵌套 div:第一个 div(父元素)将节点尺寸大小设置为视口宽度的 50%,第二个 div 的宽度为父元素的 50%,即视口宽度的 25%!
clipboard.png

布局过程的输出是一个“盒子模型”,它精确地捕获了每个元素在视口中的准确位置及尺寸大小:所有相对度量单位都被转换为屏幕上的绝对像素。

自此,我们已经知道了哪些节点是可见的以及它们的计算样式和几何信息,然后我们就可以把这些信息传送到最后一个阶段,即把渲染树中的每一个节点都转化到屏幕上实际的像素点。这个步骤通常被称为绘制(painting)或者栅格化(rasterizing)

构建渲染树、布局与绘制所消耗的时间也可以通过timeline来查看:

clipboard.png

  • "Layout" 事件捕获渲染树的构建及位置、尺寸的计算

  • 布局完成时,浏览器会触发 'Paint' 事件:将渲染树转化为屏幕上的实际像素

终于,我们的页面在设备视口中可见了。
clipboard.png

现在回顾一下浏览器执行的几个步骤:

  • 处理 HTML 标记,构建 DOM 树

  • 处理 CSS 标记,构建 CSSOM 树

  • 将 DOM 树和 CSSOM 树融合成渲染树

  • 根据渲染树进行布局,计算每个节点的几何信息

  • 在屏幕上绘制各个节点

优化关键渲染路径即尽可能地缩短上述第 1 步到第 5 步耗费的总时间。

优化CRP

阻塞渲染的CSS

在构建渲染树部分我们已了解到:CRP要求DOM和CSSOM两者融合在一起才能构建渲染树。这就导致了一个性能问题:HTML和CSS都是阻塞渲染的资源。HTML很显然,没有DOM就没有内容去渲染。CSS没有那么明显,但确实是阻塞渲染的资源。我们知道一个正常的网页如果没有引入专用的css,页面有多丑陋。当我们的网页引入了专用的css,页面一加载出来的时候就是绚丽多彩的,如果css不阻塞渲染,我们看到的很可能是这样的一个画面:页面刚加载出来的时候其丑无比,过了一会,页面又变漂亮了……

既然CSS是阻塞渲染的资源,这就意味着在CSSOM构建完成之前,浏览器不会去渲染任何已处理的内容。要尽早、尽快地把CSS下载到客户端以优化首次渲染的时间

使用CSS“媒体类型”和“媒体查询”优化阻塞渲染的CSS:

<link href="style.css" rel="stylesheet">
<link href="print.css" rel="stylesheet" media="print">
<link href="other.css" rel="stylesheet" media="(min-width: 40em)">
  • 第一条声明阻塞渲染,匹配所有情况

  • 第二条声明只适用于打印(媒体类型),因此,页面在浏览器中首次加载时,不会阻塞渲染

  • 第三条声明提供了媒体查询,由浏览器判断:如果条件符合,则在该样式表下载并处理完以前,浏览器会阻塞渲染

小提示:「阻塞渲染」仅是指该资源是否会阻塞浏览器的首次页面渲染。无论 CSS 是否阻塞渲染,CSS 资源都会被下载,只是说非阻塞性资源的优先级比较低而已。

阻塞解析的JavaScript

JS可以修改页面的内容、样式以及响应用户的交互,JS在DOMCSSOMJS执行之间引入了很多新的依赖关系,导致浏览器在处理和渲染页面上出现大幅延迟:

  • 当浏览器遇到<script>标签时,DOM构建会暂停,直到脚本执行完毕

  • JavaScript 执行会暂停,直到CSSOM准备就绪

解析器阻塞 vs. 异步 JavaScript

默认情况下,JavaScript 执行会阻塞解析器:当浏览器在文档中遇到<script>标签时,DOM构建必须暂停,浏览器把控制权移交给JS引擎,JS引擎编译并执行脚本,脚本执行完毕后再继续构建DOM。

事实上,内联脚本始终会阻塞解析器,除非你编写额外的代码来延迟它们的执行。那通过<script>引入的外联脚本呢?结果是一样的,浏览器都会暂停,然后执行脚本,脚本执行完毕之后再去处理文档的剩余部分。尽管如此,通过<script>引入外联脚本还是有一个很大的好处。

默认情况下,所有 JS 均会阻塞解析器,因为浏览器不知道脚本想在页面上做什么,因此它必须假定最糟的情况并阻塞解析器。但是,如果我们能够有个信号告知浏览器,说脚本无需在文档中引用它的确切位置被执行呢?这样一来,浏览器就会继续构建DOM,并在脚本准备就绪后执行脚本。

这个信号就是async——在script标签里面添加async关键字,其有两个特性:

  • 告诉浏览器当它碰到<script>标签时不用阻塞DOM构建,因此浏览器会忽略脚本请求,继续解析DOM

  • JS执行不依赖CSSOM:如果在CSSOM就绪之前脚本已经就绪,脚本可以立即执行

很显然,这将会显著提升性能!

小提示:另一个信号是defer,关于两者的区别可以参考一下这个问题的答案defer和async的区别

分析CRP性能

先定义三个用于描述CRP的词汇:

  • 关键资源:能够阻止网页首次渲染的资源

  • 关键路径长度:往返过程的数量,或者获取所有关键资源所需的总时间

  • 关键字节:网页首次渲染所需的总字节数,是所有关键资源的传输文件大小总和。

demo1:

<html><head><meta name="viewport" content="width=device-width,initial-scale=1"><title>Critical Path: No Style</title></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div></body>
</html>

最简单的可用网页仅由 HTML 标记组成:无 CSS、JavaScript 或其他类型的资源。要呈现此网页,浏览器必须初始化请求、等待 HTML 文档准备就绪、对其进行解析、构建 DOM,最后使其呈现在屏幕上。
clipboard.png

  • 1个关键资源

  • 1个关键路径长度(假设文件很小)

  • 5KB关键字节

T0 和 T1 之间的时间用于捕获网络传输和服务器处理时间。 在最理想的情况(HTML 文件较小)下,我们仅需一个网络往返过程即可提取整个文档(由于 TCP 传输协议的工作方式,较大的文件可能需要多个往返过程)。

demo2:

<html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet"></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div></body>
</html>

clipboard.png

  • 2个关键资源

  • 2个或更多个关键路径长度

  • 9KB关键字节

我们必须同时使用 HTML 和 CSS 来构建渲染树,因此 HTML 和 CSS 均为关键资源;浏览器需要一个网络往返过程来提取 HTML 文档,然后检索到的标记告知我们还需要 CSS 文件,这意味着,浏览器必须返回服务器并获取 CSS,然后才能在屏幕上呈现网页,因此,该网页最少需要两个往返过程才能显示(CSS 文件可能需要多个往返过程,重点在'最少');两种资源加起来的关键字节总量最多为 9 KB。

demo3:

<html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet"></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div><script src="app.js"></script></body>
</html>

clipboard.png

  • 3个关键资源

  • 2个或更多个关键路径长度

  • 11KB关键字节

我们有三个关键资源,关键字节总量最多为 11 KB,但是关键路径长度仍然是两个往返过程,因为我们可以并行传输 CSS 和 JavaScript!

demo4:
如果app.js中的内容不涉及到操作DOM和CSSOM,只是一些分析类型的代码和其他不需要阻塞页面渲染的代码,则可以在<script>中加入“async”属性:

<html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet"></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div><script src="app.js" async></script></body>
</html>

clipboard.png

异步执行脚本有以下几项优势:

  • 脚本再也不会阻止解析器,所以也不再是CRP的组成部分

  • 因为没有其他关键脚本,CSS 也不需要阻止DomContentLoaded事件

  • DomContentLoaded事件触发得越早,其他应用逻辑执行的时间就越早

因此,经过优化的网页恢复到了具有两个关键资源(HTML 和 CSS)、具有两个往返过程的最短关键路径长度和 9 KB 的关键字节总量。

demo5:

如果CSS样式表仅适用于打印:

<html><head><meta name="viewport" content="width=device-width,initial-scale=1"><link href="style.css" rel="stylesheet" media="print"></head><body><p>Hello <span>web performance</span> students!</p><div><img src="awesome-photo.jpg"></div><script src="app.js" async></script></body>
</html>

clipboard.png

因为 style.css 资源仅用于打印,所以只要DOM构建完成,浏览器就具有了渲染网页的足够信息! 所以,该网页仅具有一个关键资源(HTML),最小关键呈现路径长度为一个往返过程和5KB的关键字节。

优化CRP

常规步骤:

  1. 分析、描述关键路径:关键资源数量、字节数、关键路径长度

  2. 最小化关键资源数量:删除相应资源、延迟下载、标记为异步资源等

  3. 减少关键字节数,以减少资源下载时间(往返次数)

  4. 优化剩余关键资源的加载顺序:尽可能早的下载所有关键资源,以缩短关键路径长度


References

  • https://developers.google.com...

  • https://cn.udacity.com/course...

这篇关于网站性能优化—CRP的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/421803

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

MySQL高性能优化规范

前言:      笔者最近上班途中突然想丰富下自己的数据库优化技能。于是在查阅了多篇文章后,总结出了这篇! 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保留关键字(如果表名中包含关键字查询时,需要将其用单引号括起来) 数据库对象的命名要能做到见名识意,并且最后不要超过32个字符 临时库表必须以tmp_为前缀并以日期为后缀,备份

黑神话,XSKY 星飞全闪单卷性能突破310万

当下,云计算仍然是企业主要的基础架构,随着关键业务的逐步虚拟化和云化,对于块存储的性能要求也日益提高。企业对于低延迟、高稳定性的存储解决方案的需求日益迫切。为了满足这些日益增长的 IO 密集型应用场景,众多云服务提供商正在不断推陈出新,推出具有更低时延和更高 IOPS 性能的云硬盘产品。 8 月 22 日 2024 DTCC 大会上(第十五届中国数据库技术大会),XSKY星辰天合正式公布了基于星

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

速盾高防cdn是怎么解决网站攻击的?

速盾高防CDN是一种基于云计算技术的网络安全解决方案,可以有效地保护网站免受各种网络攻击的威胁。它通过在全球多个节点部署服务器,将网站内容缓存到这些服务器上,并通过智能路由技术将用户的请求引导到最近的服务器上,以提供更快的访问速度和更好的网络性能。 速盾高防CDN主要采用以下几种方式来解决网站攻击: 分布式拒绝服务攻击(DDoS)防护:DDoS攻击是一种常见的网络攻击手段,攻击者通过向目标网