浏览器中的预加载扫描器
Icon could not be loaded
5 min read
#writings#FE

There never was a good knife made of bad steel. — Benjamin Franklin

浏览器自身也会做很多优化手段来提高性能,预加载扫描器就是其中之一。

什么是预加载扫描器?

每个浏览器都有个主要的HTML解析器,用于将标记原始标记并将其转化为对象模型。但是当解析器遇到阻塞资源时会暂停,例如加载了<link>元素的样式表,或者加载了没有asyncdefer属性的<script>

image.png

会暂停原因如下:

阻塞任何一个关键渲染路径都是不可取的,这会延迟其他重要资源的发现而阻碍进程。浏览器通过称为预加载扫描器的辅助HTML解析器来尽力缓解这些问题。

image.png 该图描述了预加载扫描器如何与主 HTML 解析器并行工作以推测性地加载资源。在这里,主 HTML 解析器在开始处理 <body> 元素中的图像标记之前加载和处理 CSS 时被阻止,但预加载扫描器可以在原始标记中继续向前查找,以找到该图像资源并开始在主 HTML 解析器解除阻塞之前加载它。

可能破坏预加载扫描器的行为

动态注入脚本

不要在脚本中使用DOM注入脚本,如下所示:

<script>
// 默认注入的脚本是async
const scriptEl = document.createElement('script');  
scriptEl.src = '/yall.min.js';  
document.head.appendChild(scriptEl);  
</script>

根据需要使用<script>以及deferasync属性

首屏JavaScript懒加载

不要在首屏使用基于JavaScript的懒加载:

<img data-src="/sand-wasp.jpg" alt="Sand Wasp" width="384" height="255">

使用data-前缀是使用JavaScript实现懒加载的常见形式。 例如上方代码所示,通过JavaScript检查视口并在可见时将data-src替换为src属性

由于预加载扫描器读取src、srcset等属性,设置为data-src会导致图像引用无法被发现。

CSS背景图像

预加载扫描器也无法扫描到CSS背景图像。

与HTML一样,浏览器将CSS处理为自己的对象模型,称为CSSOM。如果在构建CSSOM过程中发现外部资源,则在发现时请求这些资源,而不是由预加载扫描器请求。 此情况可使用rel-preload提前获取该图像:

<!-- Make sure this is in the <head> below any  
stylesheets, so as not to block them from loading -->  
<link rel="preload" as="image" href="lcp-image.jpg">

过多的内联资源

内联资源可能比下载资源更快,因为不会发起单独的请求。它就在文档中,并且会立即加载。然而它也有明显缺点: