new Image() VS document.createElement('img')
Published:
我们都知道,在前端开发中创建图片有两种方试,分别是 new Image()
和 document.createElement('img')
。具体调用方式:
var img1 = new Image();
var img2 = document.createElement('img');
初一看,貌似没什么区别,但仔细看看,总是觉得有什么不同,下面我们就来从详细分析这两个方法的区别。
先来看看 MDN 对二者的定义
-
The Image() constructor creates a new HTMLImageElement instance. It is functionality equivalent to document.createElement('img').
-
In an HTML document, the Document.createElement() method creates the HTML element specified by tagName, or an HTMLUnknownElement if tagName isn't recognized. In a XUL document, it creates the specified XUL element. In other documents, it creates an element with a null namespace URI.
我们注意到在 Image()
的定义中有一句 It is functionality equivalent to document.createElement('img').
,即 Image()
在功能上相当于 document.createElement('img')
。的确,在功能上二者可以说是一致的。
var img1 = new Image();
var img2 = document.createElement('img');
console.log('img1 info: ', img1, typeof img1, img1.nodeType);
console.log('img2 info: ', img2, typeof img2, img2.nodeType);
上面这段代码在控制台运行结果如下:
可以看出来,二者都是生成的 img
对象,node 类型也是一样的,都是元素节点。下面我们来比较一下二者的性能,代码如下所示:
(function () {
var IMG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==';
var COUNT = 1000000;
console.time('new Image');
for (var i = 0; i < COUNT; i++) {
var cacheImage = new Image();
cacheImage.src = IMG;
cacheImage.onload = function () {
cacheImage.src = '';
cacheImage = null;
};
}
console.timeEnd('new Image');
console.time('createElement');
for (var i = 0; i < COUNT; i++) {
var cacheImage1 = document.createElement('img');
cacheImage1.src = IMG;
cacheImage1.onload = function () {
cacheImage1.src = '';
cacheImage1 = null;
};
}
console.timeEnd('createElement');
})();
大家可以改变次数 COUNT
多试几次,我们可以发现,十万次左右时,createElement
的效率会更高,但是当 COUNT
设置为 1000000 时,new Image()
的效率更高。因此可以得到一个基本结论:生成 image 次数小于十万次时,选择 createElement
。
这里有一个 jsPref,也说明了在次数比较少时,createElement
的效率更高,同时,这里还提供了一种更高效的做法,就是使用页面中的一个固定的 img
元素,同时在改变 img 的 src 的时候,设置 visibility
为 hidden
,避免触发 reflow
提高性能。