Toggle navigation
MeasureThat.net
Create a benchmark
Tools
Feedback
FAQ
Register
Log In
Rendering
(version: 0)
Comparing performance of:
DOM vs Canvas
Created:
8 years ago
by:
Guest
Jump to the latest result
HTML Preparation code:
<div id="test"></div>
Tests:
DOM
class Line { constructor(parent) { const line = parent.appendChild(document.createElement("pre")); list.style.display = "inline-block"; line.style.margin = "0"; this.element = line; } get width() { return this.element.offsetWidth; } get height() { return this.element.offsetHeight; } get text() { return this.element.textContent; } set text(value) { this.element.textContent = value; } } class Box { constructor(container, characters) { this.container = container; this.characters = characters; // TODO: Update only needed parts of box, rather than replacing the entire shape. window.addEventListener("resize", () => this.render()); } render() { this.container.innerHTML = ""; let currentLine = new Line(this.container); // Top line of the box. currentLine.text += this.characters.corner; while(currentLine.width < this.container.scrollWidth) { currentLine.text += this.characters.horizontal; } currentLine.text = currentLine.text.slice(0, -1) + this.characters.corner; // Middle portion of the box. while(this.container.offsetHeight === this.container.scrollHeight) { currentLine = new Line(this.container); currentLine.text = this.characters.vertical; while(currentLine.width < this.container.scrollWidth) { currentLine.text += " "; } currentLine.text = currentLine.text.slice(0, -1) + this.characters.vertical; } this.container.removeChild(this.container.lastChild); // Bottom line of the box. currentLine = new Line(this.container); currentLine.textContent = this.characters.corner; while(currentLine.width < this.container.scrollWidth) { currentLine.text += this.characters.horizontal; } currentLine.text = currentLine.text.slice(0, -1) + this.characters.corner; } } const test = new Box(document.getElementById("test"), { vertical: "|", horizontal: "-", corner: "+" }); test.render();
Canvas
const Ruler = { measureText(text, font) { const canvas = Ruler.canvas || (Ruler.canvas = document.createElement("canvas")); const context = canvas.getContext("2d"); context.font = font; return Math.ceil(context.measureText(text).width); } } class Box { constructor(container, characters) { this.container = container; this.characters = characters; this.container.style.whiteSpace = "pre"; // TODO: Update only needed parts of box, rather than replacing the entire shape. window.addEventListener("resize", () => this.render()); } get width() { return this.container.scrollWidth; } get height() { return this.container.scrollHeight; } get text() { return this.container.textContent; } set text(value) { this.container.textContent = value; } get font() { const containerStyle = window.getComputedStyle(this.container); return `${containerStyle.fontWeight} ${containerStyle.fontSize} ${containerStyle.fontFamily}`; } render() { this.text = ""; const lines = []; let currentLine = this.characters.corner; // First line. while(Ruler.measureText(currentLine + this.characters.corner + "\r\n", this.font) < this.width) { currentLine += this.characters.horizontal; } lines.push(currentLine + this.characters.corner + "\r\n"); // Middle portion. while(parseInt(window.getComputedStyle(this.container).fontSize) * (lines.length + 2) < this.height) { currentLine = this.characters.vertical; while(Math.ceil(Ruler.measureText(currentLine + this.characters.vertical + "\r\n", this.font)) < this.width) { currentLine += " "; } lines.push(currentLine + this.characters.vertical + "\r\n"); } // Last line. currentLine = this.characters.corner; while(Ruler.measureText(currentLine + this.characters.corner + "\r\n", this.font) < this.width) { currentLine += this.characters.horizontal; } lines.push(currentLine + this.characters.corner); this.text = lines.join(""); } } const test = new Box(document.getElementById("test"), { vertical: "|", horizontal: "-", corner: "+" }); test.render();
Rendered benchmark preparation results:
Suite status:
<idle, ready to run>
Run tests (2)
Previous results
Fork
Test case name
Result
DOM
Canvas
Fastest:
N/A
Slowest:
N/A
Latest run results:
Run details:
(Test run date:
10 months ago
)
User agent:
Mozilla/5.0 (Linux; arm_64; Android 10; Joy 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.7103.117 YaBrowser/25.6.2.117.00 SA/3 Mobile Safari/537.36
Browser/OS:
Yandex Browser 25 on Android
View result in a separate tab
Embed
Embed Benchmark Result
Test name
Executions per second
DOM
0.0 Ops/sec
Canvas
124.8 Ops/sec
Autogenerated LLM Summary
(model
llama3.2:3b
, generated one year ago):
I'll break down what's being tested in the provided JSON and explain the different approaches, their pros and cons, and other considerations. **Benchmark Definition** The benchmark definition is an object that describes the test case. In this case, there are two benchmark definitions: 1. `Rendering` (not shown in the provided code) 2. `DOM` 3. `Canvas` **Script Preparation Code** For both `DOM` and `Canvas`, the script preparation code is empty (`"Script Preparation Code": null`). This means that no additional setup or initialization code is required before running the benchmark. **Html Preparation Code** The HTML preparation code is the same for both `DOM` and `Canvas`: `"<div id="test"></div>"` This code creates a simple `<div>` element with an ID of "test". The `id` attribute will be used to identify this element in the DOM or canvas context. **Individual Test Cases** There are two test cases: 1. **DOM** * This test case uses the `classList` API and the `window.getComputedStyle()` method to access the CSS styles of an element. * It measures the execution time of a script that updates the text content of an element using the `textContent` property. 2. **Canvas** * This test case uses the HTML5 Canvas API to render text on a canvas element. * It measures the execution time of a script that generates and renders multiple lines of text on the canvas. **Comparison** The two test cases differ in their approach: 1. **DOM**: Uses the `classList` API and `window.getComputedStyle()` to access CSS styles, which is more expensive than using a canvas or other rendering context. 2. **Canvas**: Directly uses the Canvas API to render text, which can be faster because it avoids the overhead of CSS parsing and styling. **Pros and Cons** 1. **DOM**: * Pros: Easy to implement and understand, doesn't require additional libraries or setup. * Cons: Can be slower due to the overhead of CSS parsing and styling. 2. **Canvas**: * Pros: Can be faster because it avoids the overhead of CSS parsing and styling, allows for more control over rendering. * Cons: Requires a good understanding of HTML5 Canvas API and can be more complex to implement. **Other Considerations** 1. **Browser Rendering**: The benchmark results show that Chrome 60 on a Mac OS X 10.12.6 machine has a significantly faster execution time for the `Canvas` test case compared to the `DOM` test case. 2. **Device Platform and Operating System**: The results also show that the device platform and operating system can affect the execution times of both tests. In conclusion, the benchmark tests are designed to compare the performance of rendering text in different contexts: DOM (using CSS styles) versus Canvas (using the HTML5 Canvas API). The results suggest that the Canvas approach can be faster, but this depends on the specific browser, device platform, and operating system being used.
Related benchmarks:
spread vs for of
querySelector vs querySelectorAll vs getElementsByClassName vs querySelector (ID) vs getElementByID
JS selector functions
querySelector vs querySelectorAll vs getElementsByClassName vs querySelector (ID) vs getElementsByID 20x
queryall vs classname
Comments
Confirm delete:
Do you really want to delete benchmark?