new Image() VS document.createElement('img')

Published:

我们都知道,在前端开发中创建图片有两种方试,分别是 new Image()document.createElement('img')。具体调用方式:

var img1 = new Image();
var img2 = document.createElement('img');

初一看,貌似没什么区别,但仔细看看,总是觉得有什么不同,下面我们就来从详细分析这两个方法的区别。

先来看看 MDN 对二者的定义

  1. Image()

    The Image() constructor creates a new HTMLImageElement instance. It is functionality equivalent to document.createElement('img').

  2. 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 的时候,设置 visibilityhidden,避免触发 reflow 提高性能。