Skip to content

外部资源引入优化

资源引入方式

在HTML文档中引入外部资源的方式有两种,linkscript

preloadprefetch

link通常用于引入CSS样式表或者字体文件等,但是现代浏览器通常支持通过以下两种方式引入JS脚本

html
<link rel="preload" href="script.js" as="script">
<link rel="prefetch" href="script.js" as="script">

preloadprefetch都是link标签的属性,用于提前加载资源。两者的区别在于preload会立即加载资源,而prefetch会在浏览器空闲时加载资源。

这两种方式可以提前加载资源,但是不会执行脚本。脚本的执行仍然需要<script>标签。

preload的加载是并行加载,不会阻塞文档的解析过程,适用于一些重点资源的加载,如首屏渲染的关键资源。

prefetch的加载是在浏览器空闲时加载,不会影响当前页面的加载,适用于一些非关键资源的加载,如未来页面的资源预加载。

asyncdefer

一般情况下,浏览器在解析HTML文档时,遇到script 标签时会暂停文档解析,加载并执行脚本,然后再继续解析文档。这样会导致页面加载速度变慢,因为脚本的加载和执行是阻塞的。 文档未解析完成时的async脚本加载

async

当浏览器遇到带有async属性的script标签时

html
<script src="example.js" async></script>

会异步加载,不会阻塞文档解析。但是,异步加载的脚本不一定会按照它们在文档中的顺序执行,而是在加载完成后立即执行,注意执行过程是会阻塞文档解析的。

如果遇到async脚本时文档解析并未结束,具体过程如下图所示 文档未解析完成时的async脚本加载

如果遇到async脚本时文档解析已经完成,或者脚本异步加载完成时文档解析已完成,则具体过程如下图所示 文档未解析完成时的async脚本加载

WARNING

由于async脚本的执行时机不确定,所以不要在async脚本中使用脚本间互相依赖或者依赖DOM的内容,否则可能会出现问题。

defer

当浏览器遇到带有defer属性的script标签时

html
<script src="example.js" defer></script>

会异步加载,不会阻塞文档解析。但是,defer脚本会在文档解析完成后按照它们在文档中的顺序执行,并且在DOMContentLoaded事件之前执行defer脚本加载

总结

特性preloadprefetchasyncdefer
目的提前加载关键资源预加载未来可能需要的资源异步加载和执行JavaScript异步加载和延迟执行JavaScript
优先级高优先级加载低优先级加载高优先级加载高优先级加载
加载时间脚本加载与文档解析同时进行浏览器空闲时加载脚本加载与文档解析同时进行脚本加载与文档解析同时进行
执行时间不执行不执行下载完成后立即执行DOM解析完成后再执行
执行顺序不执行不执行不保证顺序保证按顺序执行
典型应用场景字体、样式、关键脚本下一个页面的资源、图片、视频等第三方脚本、广告脚本等DOM相关的功能脚本

基于 Apache-2.0 许可发布