0%

同步加载、异步加载、延迟加载和预加载

同步加载、异步加载、延迟加载和预加载

同步加载

默认的是同步加载

1
<script src="http://yourdomain.com/script.js"></script>

同步模式又称阻塞模式,会阻止浏览器的后续操作,相当于阻止了后续的文件的解析,执行等。

流览器之所以会采用同步模式,是因为加载的js文件中有对dom的操作,重定向,输出document等默认行为,所以同步才是最安全的。

通常加载js文件或者放<script>标签都在结构最后面,也是因为它会阻止浏览器后续操作的原因,所以放在后面,当页面结构和样式全部渲染完成再执行js,提升用户体验

异步加载

异步加载又称非阻塞加载,浏览器在下载执行js的同时,还会继续进行后续页面的处理。主要有两种方式

H5 async

当浏览器解析到script脚本,没有defer或async时浏览器会立即加载并执行指定的脚本,“立即”指在渲染该script标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行
当浏览器解析到script脚本,有async时

1
<script async src="main.js"></script>

浏览器会立即下载脚本,但不妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本。加载和渲染后续文档元素的过程和main.js的加载与执行并行进行,这个过程是异步的

onload

把插入script的方法放在一个函数里面,然后放在window.onload方法里面执行,这样就解决了阻塞onload事件触发的问题

1
2
3
4
5
6
7
8
document.onload = ()=>{
let s = document.createElement('script');
s.type = 'text/javascript';
s.async = true;
s.src = 'http://yourdomain.com/script.js';
const x = document.getElementsByTagName('script')[0];
x.parentNode.insertBefore(s, x);
}

延迟加载、懒加载

有些代码、资源在某种特定情况下才需要,并不是一股脑子都加载出来了,这个时候就需要延迟加载。

以一些不在视窗内的图片为例

在懒加载的时候,通常是需要跳过原本的执行步骤。比如:懒加载图片时,需要进行标签的站位,事先设定图片宽高,使用 data-* 属性设置好待请求的图片地址,这时,图片还没有被浏览器下载。

1
<img class="qLazy" data-original='https://xyz.abc.com/common/logo.png' />

由于没有此时没有设置 src 属性,所以 data-original 地址对应的图片并不会进行加载。 如果直接在 src 属性设置好图片地址,浏览器解析到则会直接下载,那么,就失去了懒加载的意义。

监听 scroll 事件

在懒加载时,需要制定懒加载的容器。比如:某些可以滚动的内容列表区域。 但在实际开发中,往往不会显式的制定容器,举个例子:手机端常常会有长列表,随整个页面滚动展现,这时如果进行懒加载优化,默认滚动容器应该为 window 对象。

判断资源位置是否在视窗内

这个功能是懒加载功能的核心,因为,懒加载也可以称为延迟加载,但什么时候进行加载呢?一定是用户在看到或者即将要看到待加载资源的时候,提前进行加载。这样,用户在看到资源时,资源已经加载完毕,可以给用户更好体验。 借用网络上一张图片加以说明:

即:当绿色待加载的页面元素,即将进入蓝色可视区域或已经进入可视区域后,执行懒加载方法。

判断加载资源或执行相应的回调逻辑。

H5 defer

当浏览器解析到script脚本,有defer时

1
2
3
<script defer="defer" src="main1.js"></script>

<script defer="defer" src="main2.js"></script>

此时单纯看这两个需要被加载的js文件和其他HTML的渲染,CSS的加载,图片的加载等是同时进行的,是异步操作

但是单看main1.js和main2.js又和同步的执行是一样的,当加载main1.js的时候,main2.js会等待main1.js加载完毕再加载

这就是defer的作用了,当有defer的时候,先架加载第一个延迟脚本

async VS defer

相同点:异步加载文件

不同点:

async:虽然是异步加载,但当有多个脚本异步加载的时候,不一定先加载哪一个,加载顺序不一定

defer:加载顺序由第一个延迟脚本到最后一个延迟脚本

预加载

预加载是一种浏览器机制,使用浏览器空闲时间来预先下载/加载用户接下来很可能会浏览的页面/资源,当用户访问某个预加载的链接时,如果从缓存命中,页面就得以快速呈现

参考 & 引用

https://www.jianshu.com/p/6e44256eacfd
https://github.com/haizlin/fe-interview/issues/1559
http://www.sohu.com/a/297706573_505779