再博客优化的过程中我们经常会嵌入很多第三方的js,第三方js提供更丰富的功能,但是却拖垮了网页的加载速度。这个时候我们可以使用async/defer来推迟js的加载。

在HTML5以前,script标签没有这两个属性,而浏览器单纯的按照顺序解析(解析)并执行,HTML5之后,我们可以在脚本标签定义他的行为,包括网路请求是否同步,执行时机等等。

选择async还是defer

广泛地说,可以通过你加载的js用途来判断你的选择

顺序DOMContentLoaded
async加载优先顺序。脚本在文档中的顺序不重要 —— 先加载完成的先执行不相关。可能在文档加载完成前加载并执行完毕。如果脚本很小或者来自于缓存,同时文档足够长,就会发生这种情况。
defer文档顺序(它们在文档中的顺序)在文档加载和解析完成之后(如果需要,则会等待),即在 DOMContentLoaded 之前执行。

在实际开发中,defer 用于需要整个 DOM 的脚本,和/或脚本的相对执行顺序很重要的时候。

async 用于独立脚本,例如计数器或广告,这些脚本的相对执行顺序无关紧要。

选择之前应该怎么做

请注意:如果你使用的是deferasync,那么用于将在脚本加载完成 之前 先看到页面。

在这种情况下,某些图形组件可能尚未初始化完成。

因此,请记得添加一个“正在加载”的提示,并禁用尚不可用的按钮。以让用户可以清楚地看到,他现在可以在页面上做什么,以及还有什么是正在准备中的。

例如博客的话开启加载动画是一个不错的选择。

如何添加defer/async?

原代码:

1
<script src="/zhheo/blogex.js"></script>

添加async后:

1
<script async src="/zhheo/blogex.js"></script>

defer同理

原代码:

1
script(src=url_for(theme.CDN.algolia_js))

添加async后:

1
script(async src=url_for(theme.CDN.algolia_js))

defer同理

Hexo的butterfly主题下如何优化

修改主题文件layout/includes/additional-js.pug中的引入js代码,根据用途来进行调整。

例如其中一部分:

1
2
3
4
5
//- search
if theme.algolia_search.enable
script(async src=url_for(theme.CDN.algolia_js))
else if theme.local_search.enable
script(async src=url_for(theme.CDN.local_search))

修改配置文件_config.yml中的inject里面的代码

例如其中一部分改成:

1
2
3
Inject:
bottom:
- <script async src="/zhheo/blogex.js"></script>

注意,部分js不能够添加推迟加载的标签,会影响正常加载,请保持不变:

1
2
3
4
5
script(src=url_for(theme.CDN.jquery))
script(src=url_for(theme.CDN.utils))
script(src=url_for(theme.CDN.main))
if theme.lazyload.enable
script(src=url_for(theme.CDN.lazyload))

参考文档

script中defer跟async是什么?

脚本:async,defer