Function for adding a tag to the first row of a table is running slowly I have a jQuery function which adds a tag to the first row of a table. I previously tried using append, however that didn't work. I now have the following solution which is very slow and it gives this warning:


  A script on this page is causing Internet Explorer to run slowly


Function:

jQuery.fn.fixGridView = function () {
    "use strict";
   // var start = +new Date();  // log start timestamp 
    if (jQuery(this).is('table') &amp;&amp; this.find('thead').length === 0) {

        var theadv = "&lt;thead&gt;&lt;tr&gt;" + this.find('tbody tr:first').html(); +"&lt;/tr&gt;&lt;/thead&gt;";

        this.find('tbody tr:first').remove();
        var htmlv = this.html();
        this.html(theadv + htmlv);
    }
    //var end = +new Date();  // log end timestamp
   // var diff = end - start;
   // alert(diff);
    return this;
};


I have to use IE8, it is client's requirement.
I have also created a jsfiddle.
As far as I understand, you just want to wrap the first as &lt;thead&gt; and the rest in &lt;tbody&gt;. Why it's slow:


html() is one possible cause. That's because you're reconstructing the DOM rather than reusing what's there already.
find() is a descendant lookup function. It looks for elements deep into the tree. If  you know that the element is a few levels down, then use multiple children() calls instead which only searches one level deep.
Just to add, attribute selectors like [id*="gvCategories"] are very slow. Better to use multiple classes instead, like class="MainContent gvCategories". That way, you can do $('.gvCategories'), which is faster.


The fastest and most painless fix is to just write the HTML with the first row in a &lt;thead&gt;. Plain and simple.

If you really want to go with JS, then here's my take on it and the performance test to prove it

jQuery.fn.fixGridView = function () {
    "use strict";

    // A jQuery object may be more than one element. Operate on each  using each()
    // Additionally, return the result to allow chainability.
    return this.each(function () {
        // Cache the element to avoid doing DOM refetch
        var element = $(this);
        if (!element.is('table')) return;  

        // No need for tbody, since the browser automatically adds it
        // http://stackoverflow.com/a/938143/575527

        // Now we avoid using find() since it looks for all descendants.
        // Instead, we use children() to limit our search to 2 levels of children
        var rows = element.children('tbody').children('tr');
        var thead = element.children('thead').length;

        // Get the first row, wrap it in &lt;thead&gt;, and prepend it to the table
        if(!thead) rows.eq(0).wrap('&lt;thead/&gt;').parent().prependTo(element);


    });

};

$(document).ready(function () {
    $('.gvCategories').fixGridView();
});