<canvas></canvas>
let image,
imageData,
ctx = new OffscreenCanvas(0, 0).getContext('2d'),
main = document.querySelector('canvas'),
c = main.getContext('2d'),
width, height,
imageAsBlob,
imageAsBitmap
async function globalMeasureThatScriptPrepareFunction() {
image = await loadImage();
({width, height} = image)
ctx.canvas.width = main.width = width
ctx.canvas.height = main.height = height
ctx.drawImage(image, 0, 0, width, height)
imageData = ctx.getImageData(0, 0, width, height)
imageAsBlob = await loadImage(URL.createObjectURL(await ctx.canvas.convertToBlob()))
imageAsBitmap = await createImageBitmap(ctx.canvas, 0, 0, width, height)
}
function loadImage(url = `https://www.measurethat.net/images/Picture1.png`) {
return new Promise(resolve => {
const img = new Image
img.src = url
img.onload = () => resolve(img)
})
}
function clear() {
c.clearRect(0, 0, width, height)
}
const repeatCount = 1
function test(num) {
switch (num) {
case 1:
for (let n = repeatCount; n--;) {
c.drawImage(image, 0, 0, width, height)
clear()
}
break
case 2:
for (let n = repeatCount; n--;) {
c.putImageData(imageData, 0, 0)
clear()
}
break
case 3:
for (let n = repeatCount; n--;) {
c.drawImage(imageAsBlob, 0, 0)
clear()
}
break
case 4:
for (let n = repeatCount; n--;) {
c.drawImage(imageAsBitmap, 0, 0)
clear()
}
break
}
}
test(1)
test(2)
test(3)
test(4)
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
draw image directly | |
putImageData | |
draw image blob | |
draw image bitmap |
Test name | Executions per second |
---|---|
draw image directly | 295122.2 Ops/sec |
putImageData | 2357.6 Ops/sec |
draw image blob | 335755.2 Ops/sec |
draw image bitmap | 651771.6 Ops/sec |
The provided benchmark tests the performance of various methods for drawing images onto a canvas in a web browser environment using JavaScript. The methods used in the benchmark are as follows:
draw image directly: This method tests the performance of drawing an image directly onto the canvas using the drawImage
method of the Canvas API.
putImageData: This method tests the performance of drawing pixel data to the canvas using the putImageData
method, which requires pre-rendered pixel data by calling getImageData
on the canvas context.
draw image blob: This method tests the performance of drawing an image represented as a Blob object using the drawImage
method, which is created by converting a canvas to a Blob.
draw image bitmap: This method assesses the performance of drawing an image represented as an ImageBitmap, which is also created from the canvas. The createImageBitmap
function is used to convert a canvas to an ImageBitmap for this purpose.
draw image directly vs. putImageData:
drawImage
: This method is straightforward and can be faster for rendering images directly because it avoids setting pixel data manually.putImageData
: This provides fine control over pixel manipulation but may involve a higher overhead since it requires creating an image data object.drawImage
: Less control over individual pixels, which may not be beneficial for certain image manipulations.putImageData
: Slower due to the overhead of dealing with pixel data, especially for large images.draw image blob vs. draw image bitmap:
drawImage
, so they generally perform similarly, as can be seen in the benchmark results.draw image blob
: Can be useful for loading images dynamically from binary sources, allowing for more flexibility in image handling.draw image bitmap
: ImageBitmap is optimized for rendering and may improve performance since it can be reused and is decoded on a separate thread.draw image blob
: Requires conversion of the canvas content to a Blob, which can introduce additional overhead.draw image bitmap
: Involves additional overhead in the creation of ImageBitmap, depending on the complexity of the image source.The benchmark results show that drawing images directly (method 1) achieved the highest number of executions per second (260,473.19), indicating it is the fastest approach under the conditions tested. The next best approach was drawing image blobs (250,487.13) and then drawing image bitmaps (233,858.23), both performing significantly better than using the putImageData
method (4,568.14), which had a much lower execution rate.
Although this benchmark does not explicitly utilize third-party libraries, it employs fundamental capabilities of the Canvas API, which is built into modern web browsers for rendering graphics and images.
Canvas API: This API allows for drawing graphics via JavaScript, providing methods like drawImage
, putImageData
, and more. It is essential for web graphics and provides tools for dynamic image creation and manipulation.
ImageBitmap: This is a built-in browser interface that represents an image in a bitmap format for optimized rendering in the Canvas API. The createImageBitmap
method is used for this conversion, making it easier to handle images more efficiently in complex applications.
Other alternatives to the methods tested might include:
WebGL: For more complex graphics operations, WebGL enables rendering accelerated 2D and 3D graphics and could provide much better performance for certain applications.
SVG (Scalable Vector Graphics): For vector-based graphics, SVG is another option that allows for scalable images, though it has its own performance considerations compared to raster images.
CSS Animation & Transitions: For certain applications, CSS can handle image manipulation efficiently without involving heavy JavaScript computations, leveraging the browser’s rendering engine.
In summary, the benchmark provides valuable insights into the performance characteristics of various methods for rendering images on a canvas in JavaScript. Each method offers different trade-offs between ease of use, performance, and control, allowing developers to choose the most suitable option based on their application's requirements. The results recommend direct image rendering for typical use cases; however, scenarios requiring image manipulation might still consider putImageData
or optimizing bitmaps for performance.