关键呈现路径过程是浏览器首先在屏幕上呈现页面的任务序列,即,下载,处理和转换html,css和javascript代码为实际像素,并将其绘制在屏幕上。
关键呈现路径优化是最小化浏览器执行序列的每个步骤所花费的时间的过程,优先显示与当前用户动作相关的内容。
这个过程中的大部分都与页面的可见部分有关,而不需要向下滚动浏览器窗口。这部分也被称为“折叠之上”。为了更好的可用性,atf应该尽可能的被渲染,这样做可以减少网络往返次数。渲染atf所需的资源被认为是关键的,并且优化“折叠之上”意味着最小化关键资源对首次渲染页面的时间的影响。
在这篇文章中,我们将通过关键渲染路径优化序列。
首先,我将概述浏览器执行的任务来呈现页面内容。接下来,我将剖析我们可以执行的最相关的操作来优化关键渲染路径。最后,我将列出一些有用的(和受欢迎的)wordpress优化插件。关键的渲染路径序列以下是浏览器执行的一系列步骤:
首先,浏览器下载并解析html标记并构建dom然后下载并处理css标记并构建css对象模型它组合了渲染树中所需的dom和cssom节点,这是所有可见节点的树状结构它计算页面中每个对象的尺寸和位置最后它在屏幕上绘制像素dom在google的“ 关键呈现路径优化”指南中也进行了解释,浏览器按照四个步骤构建文档对象模型:
首先,浏览器读取行字节并将其转换为单个字符然后它将尖括号内的字符串转换成记号这些令牌被转换成节点对象节点对象以包含html内容,属性和节点之间所有关系的树状数据结构链接。这个结构是文档对象模型。这里需要注意的是浏览器增量地构建dom。这使我们有机会通过创建高效的dom结构来加速页面的呈现。
dom结构
cssom解析器遇到link引用外部css样式表的标记时,会阻止解析并发出对此资源的请求。一旦收到css文件,浏览器就开始建立一个css节点的树型数据结构。
浏览器读取.css文件的行字节并将其转换为单个字符它将大括号内的字符串转换为记号这些令牌被转换成节点对象节点对象以包含每个节点的css属性以及节点之间的关系的树状数据结构链接。这个结构是css对象模型(cssom)。与dom构建不同,cssom构建不是增量式的。浏览器不能使用样式表的一部分,因为可以在相同样式表中对样式进行改进和重新声明。由于这个原因,浏览器会阻止渲染过程,直到它接收并解析所有的css。这意味着css呈现阻塞。
cssom结构
渲染树浏览器将dom和cssom合并到render tree中,render tree是包含所有节点和属性的最终树结构,这些节点和属性用于将页面呈现在屏幕上。
渲染树只包含渲染页面所需的节点。结果,不可见节点被省略。
浏览器使用“渲染树”来计算节点的尺寸和位置,最终作为绘制过程的输入。
渲染树结构
布局和绘画在布局阶段,浏览器计算渲染树的每个节点的尺寸和位置。在这个阶段,浏览器从根开始遍历渲染树,并产生一个盒子模型。这个信息最终被用来将渲染树的每个节点转换成屏幕上的实际像素。
关键的渲染路径优化运行整个过程所需的时间可以变化。这取决于许多因素,如文档大小,请求数量,应用的样式,用户设备等。
谷歌的一个最相关的建议是优先考虑可见内容,以尽可能快地渲染“折叠之上”,提供了两条主要规则:
构建html以首先加载关键的,高于折叠的内容减少html,css和js资源使用的数据量在google的pagespeed指南中也有解释,如果呈现atf所需的数据量超过了初始拥塞窗口(14.6kb),则需要在服务器和浏览器之间进行额外的网络往返。在具有高延迟的移动网络上,这将显着延迟页面加载(阅读更多延迟)。
浏览器增量地构建dom,这使我们有机会通过构建html来减少呈现atf所需的时间,从而首先加载上面的折叠并推迟页面的其余部分。
上述折叠内容因用户设备而异
但是,优化并没有结束于构建有效的dom结构。相反,这是一个涉及整个关键渲染路径序列的改进和度量过程。
让我们深潜吧。
最小化资源维度通过缩小,压缩和缓存html,css和javascript资源,我们可以减少浏览器下载的数据量:
缩小是从源代码中删除不必要的字符,如评论和空白的过程。这些字符在开发中非常有用,但是为了呈现页面,它们对于浏览器来说是无用的。压缩是web服务器和客户端减小传输文件的大小以提高速度和带宽利用率的能力缓存:每个浏览器都带有一个http缓存的实现。我们需要做的是确保每个服务器响应提供正确的http头来指示浏览器何时以及多长时间缓存所请求的资源优化css现在我们知道,浏览器必须等到获取并处理css代码才能呈现页面(css呈现阻止)。但并不是所有的css资源都是渲染阻塞的。
css可以限定为特定的条件,我们可以使用媒体类型和媒体查询来优化它。如果您正在屏幕上查看网页,则浏览器将发送打印介质类型的请求,但不会阻止此资源页面的呈现。
拿下面的link标签:
<link rel=stylesheet href=style.css />这个标签的引用样式表适用于任何条件下,与当前媒体类型,屏幕分辨率,设备方向等无关。这意味着css资源始终是呈现屏蔽的。
幸运的是,我们可以在特定条件下发送css资源的请求。我们可以将打印样式移动到一个单独的文件中,并使用该media属性告诉浏览器在打印页面时应该只加载指定的样式表,并且不需要屏蔽在屏幕上的渲染:
<link rel=stylesheet href=print.css media=print />浏览器仍然下载print.css样式表,但不会阻止渲染。此外,浏览器必须下载较少的主要css文件的数据,这将有助于我们加快下载。我们可以在link属性上指定任何媒体查询,所以我们可以将css拆分成多个文件并有条件加载:
<link rel=stylesheet href=style.css media=screen />
<link rel=stylesheet href=portrait.css media=orientation:portrait />
<link rel=stylesheet href=widescreen.css media=(min-width: 42rem) />确保您的样式实际上是呈现页面所需的。如果不是,则可以向媒体标记属性添加适当的值,并取消屏蔽呈现。
媒体类型和查询可以帮助我们加快页面渲染,但我们可以做更多。
缩小css:空白和注释只能帮助我们阅读css声明。通过从样式表中删除注释和空白,我们可以显着减少css文件的字节数合并多个css文件:这将减少http请求的数量。对于性能受高延迟影响的移动连接,此操作尤其重要(有关延迟的详细信息,请参阅此部分)。内联关键css:从某种意义上说,某些样式是至关重要的,因为它们需要呈现页面的上方折叠。您应该始终将内联重要样式直接考虑到html标记中,以避免额外的http请求。但避免内联大型css文件,因为这可能需要额外的往返才能呈现上面的折叠,这将导致pagespeed警告。加快布局和绘制过程浏览器花费在布局文档上的时间取决于要布置的dom元素的数量以及这些布局的复杂程度。
如果您有很多dom元素,浏览器可能需要很长时间来计算它们的位置和尺寸:尽可能避免布局。喜欢新的flexbox模型,因为它比旧的flexbox和浮动布局更快。避免强制使用javascript进行同步布局计算元素的大小和位置需要时间并降低性能。尽可能简化dom,并避免使用javascript来预测布局过程,这将有助于浏览器加快页面渲染的速度(详细了解布局优化)。
严格连接到布局的是“绘制”过程,这可能是“临界渲染路径”序列中最耗时的阶段,因为无论何时您更改元素的布局或任何非几何属性,浏览器都会触发一个绘制事件。在这个阶段尽可能简单的事情可以帮助浏览器加快绘画过程。例如,box-shadow需要某种计算的属性花费比固体边框颜色更长的时间。
chrome devtools允许识别正在绘制页面的部分
优化绘画过程可能并不那么容易,您应该利用浏览器的开发工具来测量浏览器触发每个绘画事件的时间。您可以在google的“渲染性能指南”中阅读有关此主题的更多信息。
使javascript解冻当浏览器遇到脚本标记时,必须停止解析html代码。内联脚本在文档中的确切位置执行,并阻止dom构造,直到js引擎完成运行。换句话说,内联javascript可以显着延迟页面的初始渲染。但是javascript也允许操作css属性,因此浏览器必须暂停脚本执行,直到它完成下载并构建cssom为止。这意味着javascript是解析器阻塞。
在外部js文件的情况下,解析器还必须等待,直到从缓存或远程服务器获取资源,这可能会大大减慢首次呈现页面的时间。
这就是说,我们可以做些什么来尽量减少浏览器加载和执行javascript的时间?
异步加载javascript:标记的布尔async属性script指示浏览器异步执行脚本(如果可能的话),而不阻止dom构造。浏览器发送脚本的http请求,并继续解析dom。而且,脚本不会阻止cssom构造,这意味着它不会阻塞关键呈现路径(有关脚本标记属性的更多信息,请参阅mdn文档)推迟javascript:标签的布尔defer属性script告