What makes changing styles via batch (cssText) in Chrome slower than changing them individually (.style.property)?

I recently came across some interesting tips in the "High Performance Javascript" book regarding optimizing for minimizing repaints and reflows. One of the suggestions was to batch DOM changes for better performance, such as utilizing:

var el = document.getElementById('mydiv');
el.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;';

as opposed to

var el = document.getElementById('mydiv');
el.style.borderLeft = '1px';
el.style.borderRight = '2px';
el.style.padding = '5px';

Intrigued by this, I decided to conduct a test in Chrome to verify the claim. Here is the code snippet I used for testing:

var ie = (function(){
    var undef, v = 3, div = document.createElement('div');

    while (
        div.innerHTML = '<!--[if gt IE '+(++v)+']><i></i><![endif]-->',
        div.getElementsByTagName('i')[0]
    );

    return v> 4 ? v : undef;
}());


// First insert 100*100 element

var total = 100 * 100;
var round = 100 * 100;

var body = document.querySelector("body");

if (ie) {
    total = round = 100 * 10;       
}

var createElement = function (id) {
    var div = document.createElement("div");
    div.setAttribute("id", "id-" + id);
    return div;
}

for (var i = 0; i <= total; i++) {
    body.appendChild(createElement(i));
}

// Then change style randomly
function randomFromInterval(from, to) {
    return Math.floor(Math.random() * (to-from+1)+from);
}

function randomWidth() {
    return randomFromInterval(0, 200) + "px";
}

function randomHeight() {
    return randomFromInterval(0, 200) + "px";
}

function randomColor() {
    var r = randomFromInterval(0, 255),
        g = randomFromInterval(0, 255),
        b = randomFromInterval(0, 255);

    return "rgb(" + r + ", " + g + ", " + b + ")";
}

var time = +new Date();

for (var i = 0; i <= round; i++) {
    var id = randomFromInterval(0, total);
    var div = document.querySelector("#id-" + id);

    // The `slower` way...but surprisingly faster
    div.style.width = randomHeight();
    div.style.height = randomWidth();
    div.style.backgroundColor = randomColor();
}

console.log(+new Date() - time);

Here is the demo link:

http://jsfiddle.net/9BV5E/

http://jsfiddle.net/9BV5E/1/

The first demo uses the .style. method while the second one employs the cssTest approach;

Furthermore, I also tested both methods in IE8 and found that their execution times were nearly identical.

Does this mean the book's advice is incorrect? Are there other factors at play?

Answer №1

Could you share your testing method with me?

Have you considered inputting the test cases into a platform like jsperf.com similar to those shown in this link?

Based on the available information, it seems that using cssText is preferable for setting multiple styles at once compared to individual style applications. Despite conducting tests, I have been unable to reproduce the results you mentioned.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to uninstall Bootstrap from an ASP.NET project?

After setting up the backend for my ASP.Net webforms project, I am now shifting my focus to design. My goal is to incorporate Google Material Design Lite into the project, but I am facing a challenge. Despite removing all the Bootstrap stylesheets that w ...

"Mongo server is rejecting the connection, and the reason is unclear to me

I created a MongoDB model with the following structure:- var mongoose = require('mongoose'); const itemsModel = new mongoose.Schema({ _id: { type: String, }, userName: { type: String, required: true }, ...

Setting the Content-Type of a JavaScript file within a NodeJS application

I am facing an issue with opening a js-file on my NodeJS server, as it always specifies the .js file with a Content-Type of "text/html." My objective is to send user-input from an html form to a JavaScript file for performing calculations and later genera ...

What is the process for adjusting the position following the modification of a table value in React?

In my React UI, I have set up two text fields for entering values. After saving the values, they are displayed in a table below (designed with antd). When I click on a record in the table to edit it, I want the data from that record to populate the text f ...

Preventing controller from reloading with dynamic routes

My goal is to prevent the controller from reloading when using dynamic routes. For example, if I have a route defined as '/home/:param', and I navigate from '/home/path1' to '/home/path2', the controller should not be reload ...

Issue with using Javascript variables within Highcharts

I am facing an issue with displaying a high charts pie chart dynamically. When I pass the exact value format into the data index in the high chart, it doesn't show anything in the chart. However, if I directly assign a value to a variable, it works fi ...

FullCalendar jQuery caught in an endless loop

After successfully implementing drag and drop deletion, I encountered a new issue. Whenever I delete an event, the removal process functions properly but then the code gets stuck in a loop within the eventDragStop function causing the calendar to freeze ...

The jQuery selector threw an Uncaught SyntaxError due to an Unexpected identifier

Just starting out with programming, I'm attempting to send data using my Python script. I'm unsure of what the error message is indicating. $(document).ready(function() { $("tags").keyup(function({ var search = $("tags").val() $.post(" ...

Insert a new store into an existing IndexedDB database that is already open

After opening and passing the onupgradeneeded event in IndexedDB, is there a way to create a new store? My attempted code: var store = db.createObjectStore('blah', {keyPath: "id", autoIncrement:true}); This resulted in the following error mess ...

How can I use jQuery to hide a div after submitting a form?

I am struggling to hide a specific div using an onclick function on my form submit button. However, despite my efforts, the div is not disappearing. Can anyone suggest a better approach for achieving this? My goal is to conceal a div element on my webpag ...

The occurrence of the error "Failed to resolve component" in Vue 3.0.11 seems to be random, particularly when using recursive components

After thoroughly checking all similar questions on this platform, I did not find any relevant solutions. In most cases, the error seems to occur when utilizing components:[comp1,comp2] This is incorrect because the components property should be an object. ...

Enhancing the style of the top menu Index by applying a border-bottom effect when hovering over it in a CSS Horizontal Drop Down Menu

I'm having trouble adding a border-bottom: 1px solid #FFF to all the top menu (index) items when they are hovered over. Can anyone help me with this? #menu{ padding:0; margin:0; position: fixed; top: 30px; left: 0px; font-size ...

When the form is submitted, the values of the items are being reverted back

I'm currently working on a single web page using nodejs, expressjs, and mongoDB. On the page, I have two text boxes that define the filter clause for the collection in mongoDB. Additionally, there is an HTML table that displays the documents from the ...

Manipulating text on an image without using canvas, using vanilla JavaScript

I've been working on a project to create a meme generator without using canvas, as part of my DOM manipulation practice in vanilla JavaScript. I'm facing challenges in adding text to the user-submitted pictures and need some guidance in achieving ...

Fetching works flawlessly in the local environment, but encounters issues when deployed

Fetching Data Problem in Vercel Deployment vs Localhost I'm encountering a problem with fetching data in my React app. Here's a simplified version of the code snippet: useEffect(() => { async function fetchData() { const res = await fet ...

What could be the reason for axios yielding [object Promise] rather than the actual data?

My issue involves a function that retrieves data from an API. However, when I integrate this function into an EJS template, it returns a promise instead of the desired data. Strangely, when I console.log the data, it displays the correct information. Assi ...

How can I assign a default value for a multiple select dropdown list in AngularJS?

I am currently facing an issue with my multiselect dropdown. The code for the dropdown is as follows: <select id="year" multiple ng-model="type" ng-disabled="!type1" > <option value="all" selected>all</option>; <option value= ...

How to disable event.preventDefault on a hyperlink with a delay using jQuery or JavaScript

I need to disable event.preventDefault after a certain period of time on a hyperlink using jQuery or JavaScript. When I click on the link, it should redirect me to the specified href link after a delay because I need to send an AJAX request during that tim ...

Dynamically load modules within an AngularJS application

Is there a way to dynamically load module scripts? I have 2 JS files: module1.js (function() { var mod = angular.module('module1', []); .... })(); This is the second one: module2.js (function() { var mod = angular.module('m ...

Incorporating ratings and heart icons next to every movie title

I am tasked with creating a simple Movie listing website where users can add or remove movies from their favorites list. Instead of a standard add to favorites button, I would like to use the heart icon from Bootstrap. Additionally, I want to display the r ...