<canvas id="canvas" width="320" height="320"></canvas>
const canvas = document.getElementById('canvas')
canvas.style.imageRendering = 'pixelated'
canvas.style.backgroundColor = '#000'
canvas.style.outline = 'none'
canvas.style.cursor = 'none'
canvas.style.transform = `scale(2)`
document.body.replaceChildren(canvas)
const ctx = canvas.getContext('2d')
function drawimgdata(img) {
ctx.drawImage(img, 0, 0)
img.close()
}
function drawpixels(pixels) {
const imgdata = new ImageData(pixels, 320, 180)
ctx.putImageData(imgdata, 0, 0)
}
function drawrandom() {
for (let n = 0; n < 300; n++)
for (let y = 0; y < 180; y++) {
for (let x = 0; x < 320; x++) {
let i = y * 320 * 4 + x * 4
pixels[i + 0] = Math.random() * 255
pixels[i + 1] = Math.random() * 255
pixels[i + 2] = Math.random() * 255
pixels[i + 3] = 255
}
}
}
const c = new OffscreenCanvas(320, 180)
const ctx2 = c.getContext('2d')
const pixels = new Uint8ClampedArray(320 * 180 * 4)
const imgdata = new ImageData(pixels, 320, 180)
drawrandom()
ctx2.putImageData(imgdata, 0, 0)
drawimgdata(c.transferToImageBitmap())
drawrandom()
drawpixels(pixels)
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
imgdata | |
pixels |
Test name | Executions per second |
---|---|
imgdata | 3.7 Ops/sec |
pixels | 3.7 Ops/sec |
In the provided benchmark, two specific methods for rendering images to a canvas in a web browser are compared: using putImageData
and using drawImage
. The benchmark measures the performance of these two methods based on how quickly they can execute the render operations.
putImageData
:drawrandom()
function is called to populate a Uint8ClampedArray
with random pixel data.ImageBitmap
using transferToImageBitmap()
, which is then drawn on the canvas using drawimgdata
.putImageData
:drawrandom()
function is used to fill the pixels
array with random data.drawpixels(pixels)
function then draws the filled image directly onto the canvas.drawimgdata(c.transferToImageBitmap())
Pros:
transferToImageBitmap()
converts the pixels into an ImageBitmap
, which can be rendered more efficiently in the canvas context since it leverages faster textures on the GPU.Cons:
ImageBitmap
may negate the performance benefits for smaller images or less complex rendering scenarios.ImageBitmap
interface.drawpixels(pixels)
Pros:
putImageData()
allows straightforward manipulation of the pixel data.Cons:
putImageData()
is often slower than sending an ImageBitmap
to the GPU, especially when used with large datasets or high-frequency updates.OffscreenCanvas: This is a HTML Canvas API that allows you to create a canvas that is not displayed in the DOM. It enables rendering off-screen and can be useful for web workers or for optimizing rendering performance in certain situations. Here, it's employed to create a secondary canvas context for drawing operations.
ImageData: This is part of the HTML Canvas API and represents the underlying pixel data for a rectangle of an image. This will house the actual pixel values for rendering.
Canvas API: Both putImageData
and drawImage
are part of the HTML Canvas 2D Context, a critical tool for graphics rendering in web applications.
ImageBitmap: This special object represents a bitmap image that can be drawn to the canvas, allowing more efficient and potentially faster rendering when dealing with images.
WebGL: For more complex and performance-heavy graphical applications, leveraging WebGL would be more suitable. It provides a way to use the GPU more effectively for rendering, especially when dealing with 3D graphics or complex 2D visualizations.
svg.js or D3.js: These libraries provide alternative means to create graphics and visualizations with different performance characteristics and capabilities. They may be preferable for specific use cases like vector graphics or data-driven visualizations.
Other Canvas Rendering Libraries: There are myriad libraries such as PixiJS that optimize canvas rendering for game development and interactive animations.
In summary, this benchmark allows engineers to assess the performance implications of rendering techniques on HTML canvases. Developers need to weigh the benefits of different rendering methods based on application needs, especially in performance-sensitive contexts. Understanding the nuances of how data is processed and rendered can lead to more efficient web applications.