John1984 John1984 - 7 months ago 35
Javascript Question

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!

Answer

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

Comments