浏览器何时会发起网络请求,去加载一张图片?

写在前面

本文首发于公众号:符合预期的CoyPanjavascript

浏览器在何时会去加载一张图片呢?固然是咱们网页中有图片的时候。在平时的项目开发中,咱们还经常会用图片进行日志上报,大概像下面这样:html

var img = new Image();
img.src = 'http://上报地址?a=1'
复制代码

新建一个Image,将其src赋值,浏览器便会发出一个网络请求。java

再来考虑一下下面的代码:canvas

var scriptEl = document.createElement('script');
scriptEl.src = 'http://xxxx.js';
复制代码

上面的代码会发起网络请求么?浏览器

答案是:不会。只须要增长一行代码,将script插入到DOM树中,便会触发网络请求。网络

var scriptEl = document.createElement('script');
scriptEl.src = 'http://xxxx.js';
document.body.appendChild(scriptEl); // 这行代码会触发请求
复制代码

何时会触发一次图片请求?

再来看下面的代码:app

var imgStr = '<img src="xxx.png">';
var divEl = document.createElement('div');
divEl.innerHTML = imgStr;
复制代码

上面的代码会触发网络请求么?答案是:会的。虽然divEl并无被插入到DOM树中,可是网络请求依然会触发。这种表现一开始是让我有点意外的。因而乎,我开始了探索。函数

翻了一下html规范,发现了下面这段话:ui

地址:html.spec.whatwg.org/multipage/i…spa

大概的意思就是:

若是浏览器禁用了js脚本,那么浏览器能够当即请求图片,也能够根据须要加载图片。若是浏览器没有禁用js脚本,当img元素被建立,或者经历一些变化(src被赋值等) 时,浏览器必须当即进入一个update the image data的流程。在update the image data这个流程中,若是图片元素尚未内容,而且图片元素的src已被赋值,浏览器会当即发起请求去请求图片。

这样,就能够解释上述的现象了:

Case 1

var img = new Image();
img.src = 'http://上报地址?a=1'

// Object.prototype.toString.call(img) === "[object HTMLImageElement]"
复制代码

使用Image构造函数时,生成了一个HTMLImageElement实例,也就是一个img元素,而后给这个img元素的src赋了值。很显然,咱们使用了javascript。按照规范,浏览器必须当即发起网路请求,更新图片数据。

Case 2

var imgStr = '<img src="xxx.png">';
var divEl = document.createElement('div');
divEl.innerHTML = imgStr;

// Object.prototype.toString.call(divEl.firstChild) === "[object HTMLImageElement]"
复制代码

在使用了innerHTML后,其实咱们也是生成了一个HTMLImageElement实例。按照规范,浏览器也必须当即发起网络请求,更新图片数据。

总结一下:只要咱们在代码中建立了一个img元素(HTMLImageElement实例),而且咱们给这个img元素的src赋值了,那么浏览器就会发起网络请求,加载图片内容

何时触发一次script请求?

咱们再来规范里是怎么规定script标签的。

地址:html.spec.whatwg.org/multipage/s…

在script标签的相关规范里,我没有找到明确的说明在什么状况下须要发起网络请求加载资源。另外,我看到了上面红框里的这段话。归纳一下,就是:

浏览器能够在设置script元素的src时候,就发起网络请求加载资源。可是若是最后,这个script元素没有插入DOM的话,网络请求就彻底被浪费了。

能够理解为:浏览器能够在设置script元素的时候,自行考虑是否须要当即发起网络请求加载资源。而后浏览器在实现的时候,为了节约资源,并无当即发起请求,而是选择了在插入DOM树后,才发起请求。

(这里不是很肯定,可是没有找到更进一步的说明)

跳出规范来思考

不考虑规范,在平时的业务中,咱们新建图片后,无论图片是否最终插入DOM树,都须要当即拿到图片的信息,好比canvas,好比经过图片的宽高进行页面排版等。所以,新建img元素后当即发起请求拿到图片数据,是合乎逻辑的。

对于script元素来讲,也不存在须要单独操做的场景,为了节省资源,script插入DOM树后再发起网络请求,也是合乎逻辑的。

写在后面

在业务开发中,某些代码看起来很理所固然,便没有多想。偶尔会遇到让人意外的表现,这个时候探索一下,加深一下理解,也算是符合预期吧。

相关文章
相关标签/搜索