第一种,最常用的“给script加个async属性”。
平时咱引JS文件,不就是写个<script src="xxx.js"></script>
嘛?只要在这个标签里加个async
,比如<script async src="xxx.js"></script>
,浏览器就不会“卡着等”这个JS加载完再干别的了。它会一边加载这个JS,一边继续渲染页面上的文字、图片,等JS加载好立马执行。不过有个小特点:如果同时加了好几个带async的JS,哪个先加载完就先执行哪个,不管你写的顺序。
第二种,跟async有点像的“defer属性”。
也是在script标签里加属性,写成<script defer src="xxx.js"></script>
。它跟async一样,不会让页面“卡住等加载”,也是边加载边渲染页面。但不一样的是,加了defer的JS,会严格按照你写标签的顺序来执行——比如你先写了A.js的defer标签,再写B.js的,那不管A和B谁先加载完,都一定是A先执行。而且更贴心的是,它会等整个页面的HTML都解析完了,才会执行这些JS,不用担心JS里要操作的元素还没出来。
第三种,“用JS代码自己创建script标签”。
就是咱不直接在HTML里写script标签,而是用JS动态造一个。比如写一段代码:
// 先造个script标签
let newScript = document.createElement('script');
// 给这个标签指定要加载的JS文件地址
newScript.src = 'xxx.js';
// 把这个标签塞到页面里(比如塞到body末尾)
document.body.appendChild(newScript);
这么干的话,这个JS也是异步加载的,不会挡着页面渲染。而且你还能加个“加载完成的回调”——比如想等这个JS加载完再干别的,就加一句newScript.onload = function() { 这里写加载完要执行的事儿 }
,很灵活。
第四种,“用import()函数(ES6里的法子)”。
这个更像“按需加载”,比如用户点了某个按钮之后,才加载对应的JS。写法大概是这样:
// 比如给按钮加个点击事件
document.getElementById('btn').onclick = function() {
// 点击后才加载xxx.js,加载完会执行then里的代码
import('./xxx.js').then(function(module) {
// 这里可以用xxx.js里导出的东西
});
};
这种适合那种“不是一打开页面就需要”的JS,比如某个弹窗里的功能,用户不点弹窗就不用加载,能省点加载时间。
总结下就是:想简单搞,就给script加async或defer;想自己控制加载时机(比如用户操作后再加载),就用JS造标签或者import()。核心都是不让JS加载拖慢页面显示,让用户看着页面加载更流畅。