<div id="foo"></div>
function addClass(el, classNames)
{
if (!classNames) { return; }
if (!Object.prototype.toString.call(classNames) === "[object Array]")
{
classNames = classNames.split(' ');
}
var className = el.getAttribute("class") || "";
var i, classMap = {}, currentClasses = [], length;
if (className !== null)
{
currentClasses = className.split(" ");
length = currentClasses.length;
for (i = 0; i < length; i++)
{
if (currentClasses[i] !== "")
{
classMap[currentClasses[i]] = "";
}
}
}
var changed = false, trimmedName;
var newAdded = [];
length = classNames.length;
for (i = 0; i < length; i++)
{
trimmedName = classNames[i].trim();
if ((trimmedName.length > 0) && !(trimmedName in classMap))
{
currentClasses.push(trimmedName);
newAdded.push(trimmedName);
classMap[trimmedName] = "";
changed = true;
}
}
if (changed)
{
el.setAttribute("class", currentClasses.join(" ").trim());
}
return newAdded;
}
function addClass2(el, classNames)
{
if (!classNames) { return; }
if (!Object.prototype.toString.call(classNames) === "[object Array]")
{
classNames = classNames.split(' ');
}
var className = el.getAttribute("class") || "";
var trimmedName;
var newAdded = [];
var length = classNames.length;
var list = el.classList;
for (i = 0; i < length; i++)
{
trimmedName = classNames[i].trim();
list.add(trimmedName);
}
return newAdded;
}
var i = 1000;
while (i--) {
var element = document.getElementById("foo");
element.className = "bar2";
addClass(element, ["bar", "bar2", "bar3"]);
}
var i = 1000;
while (i--) {
var element = document.getElementById("foo");
element.className = "bar2";
var list = element.classList;
list.add("bar");
list.add("bar2");
list.add("bar3");
}
var i = 1000;
while (i--) {
var element = document.getElementById("foo");
element.className = "bar2";
element.classList.add("bar", "bar2", "bar3");
}
var i = 1000;
while (i--) {
var element = document.getElementById("foo");
element.className = "bar2";
addClass2(element, ["bar", "bar2", "bar3"]);
}
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
addClass function | |
classList | |
classList multiple params | |
addClass function with classList |
Test name | Executions per second |
---|---|
addClass function | 275.9 Ops/sec |
classList | 278.6 Ops/sec |
classList multiple params | 458.3 Ops/sec |
addClass function with classList | 255.3 Ops/sec |
I'd be happy to explain the benchmark and its various aspects.
What is tested on the provided JSON?
The benchmark tests the performance of two approaches for adding classes to an HTML element:
addClass
function (which is not part of the standard JavaScript API, but rather a custom implementation).classList
property of an HTML element.Options compared:
There are three test cases that compare these two approaches:
"bar"
)."bar", "bar2", "bar3"
).Pros and Cons of each approach:
addClass function:
setAttribute
) instead of relying on the classList
property.classList:
addClass
function due to the additional overhead of parsing the classList.add()
method.Other considerations:
classList
property is a modern feature introduced in HTML5, so its support may not be universal.Library used:
None of the benchmark definitions explicitly mention any external libraries. However, the custom addClass
function and classList
implementation are self-contained and don't require any additional libraries.
Special JS features or syntax:
The benchmark uses:
classList
property, which is a modern feature introduced in HTML5.getAttribute()
and setAttribute()
methods for modifying attributes, which are part of the standard JavaScript API.Overall, this benchmark provides valuable insights into the performance differences between two approaches to adding classes to an HTML element.