John1984
John1984

Reputation: 987

Performance issue when adding classes to large DOM

I have a very large group of divs (over 5000) which I need to apply a class to. This operation causes a significant performance drain / UI lag.

I've tried two methods to add the class to the divs:

// jQuery approach
$("div", "#document").addClass("default");

// Vanilla JS (HTML5)
var obj_list = document.getElementById("document").querySelectorAll('div');

for (var index = 0; index < obj_list.length; index++) 
{
    obj_list[index].classList.add("action"); 
}

Neither method provide any noticeable difference performance wise. I'm wondering if there's another option for achieving this?

Thanks!

Upvotes: 0

Views: 445

Answers (1)

Ali Mamedov
Ali Mamedov

Reputation: 5256

I have tried to do some experiments with huge count of <div> elements in one page.

Here It is my example:

<style type="text/css">
    .default {

        color: red;
    }
</style>
<script src="https://code.jquery.com/jquery-2.2.3.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {

    $('#generate').click(function() {

        for (var i = 0; i <= 5000; i++) {

            $('#container').append('<div class="tick">some text</div>');
        }
    });

    $('#add').click(function() {

        var
            divs,
            countFrom,
            length,
            runner,
            requestAnimation;

        divs = document.getElementById("container").querySelectorAll('div');
        countFrom = 0;
        length = divs.length;

        runner = function() {

            if (countFrom < length) {

                divs[countFrom++].className = 'default'; 
                requestAnimationFrame(runner)
            }
            else {

                cancelAnimationFrame(requestAnimation);
                console.log('READY');
            }
        };

        requestAnimation = requestAnimationFrame(runner);
    });
});
</script>
<div>
    <input type="button" id="generate" value="Generate"> <br>
    <input type="button" id="add" value="Run it! Yay!"> <br>
</div>
<div id="container">

</div> 

First click on "Generate" button (5000 divs will be appended to container). Next click "Run It" button. The process will be started asynchronously. The page will not be blocked by the process.

To run this process asynchronously, I have used Window.requestAnimationFrame() method instead of slow setInterval().

Script speed: one addClass operation per frame. You can easily increase this speed by modifying my code. For example, 100 addClass operations per frame by using for loop...

Demo

Upvotes: 1

Related Questions