夜下客

繁体版 简体版
夜下客 > JS修炼法则 > 第16章 html预加载技术

第16章 html预加载技术

一.背景

在工作中的项目脚手架生成的H5页面中,其index.html 如下:

你发现了嘛。上面<link> 标签中写了一遍,下面<script> 标签中又写了一遍。

在<link> 中进行了 预加载, 在<script> 进行执行,执行时省略了下载步骤,节约了时间,即提前加载资源。

二.原理

<linkrel="preload"> 可以实现动态加载,但不执行,同时preload 不会阻塞 windows 的 onload 事件,除非,preload资源的请求刚好来自于会阻塞 window 加载的资源。

应用场景就是上述代码的那个场景:你想提前下载好某一个资源,但并不在下载结束后就执行下,等到某一时刻再执行。

在<linkrel="preload"> 出现之前,浏览器下载脚本之后会直接执行。

基于这个特点,如果你想在脚本插入的位置,直接执行脚本,而不等待其下载,那你就必须提前下载脚本。

现在开动脑筋想一下,提前获取某个网络资源有哪些方式?

首先想到的是发起请求,但是通过XHR获取的脚本,本质上是获取了当前脚本中的内容,而非说把这个脚本CV了一份到浏览器,因为浏览器不能写文件,所以这个内容我们只能先保存下来,后续只能通过eval() 方法执行,但eval() 本身也有副作用,导致其不是很可靠。

所以 preload 诞生了。

<linkrel=“prefetch”>的作用是告诉浏览器加载下一页面可能会用到的资源,注意,是下一页面,而不是当前页面。因此该方法的加载优先级非常低(自然,相比当前页面所需的资源,未来可能会用到的资源就没那么重要了),也就是说该方式的作用是加速下一个页面的加载速度。

三.preload解决了什么

HTML 解析器在创建 DOM 时如果碰上同步脚本(synchronous script),解析器会停止创建 DOM,转而去执行脚本。所以,如果资源的获取只发生在解析器创建 DOM时,同步脚本的介入将使网络处于空置状态,尤其是对外部脚本资源来说,当然,页面内的脚本有时也会导致延迟。

预加载器(Preloader)的出现就是为了优化这个过程,预加载器通过分析浏览器对 HTML 文档的早期解析结果(这一阶段叫做“令牌化(tokenization)”),找到可能包含资源的标签(tag),并将这些资源的 URL 收集起来。令牌化阶段的输出将会送到真正的 HTML 解析器手中,而收集起来的资源 URLs 会和资源类型一起被送到读取器(fetcher)手中,读取器会根据这些资源对页面加载速度的影响进行有次序地加载。

四.当前浏览器是否支持preload

『加入书签,方便阅读』