This method is about 50% faster, even in IE, than the previous methods examined. The improvement comes from reducing the number of DOM changes to one compared with replacing each row (the first method), and perhaps not working with elements and document fragments. There are certainly fewer lines of code.

In tables, only the cells can be altered with innerHTML. Do not write to the innerHTML property of table, thead, tfoot, tbody, and row elements.

This technique makes use of innerHTML to replace the complete table not just the rows. In IE, the innerHTML property of table, thead, tfoot, tbody, and tr is read only. In other browsers, innerHTML is writable on non cell table elements, but that is discouraged. Those elements have properties to track the table structure that may not be correctly updated. Consequently, to use innerHTML, the complete table has to be replaced.

HTML  

    <div id="tableDiv">
    </div>

That HTML is as minimal as it gets. Since the table is completely replaced, the only required HTML is a div to hold the table. There should be nothing else in this div; although, you could have a table.

JavaScript  

 1 function loadTable2(target, source) {
 2     var dataDiv = document.getElementById(target);
 3     var tmpArray = [];
 4     var rowTemplate = "<tr id='%0%'><td>%1%<\/td><td>%2%<\/td><td>%3%<\/td><td>%4%<\/td>";
 5     tmpArray[0] = '<table id="tbl" summary="">\n<thead><th>First Name<\/th><th>Last Name<\/th><th>Dept<\/th><th">Office<\/th><\/thead>\n<tbody id="data-area">';
 6 
 7     for (var i = 0, k = 1, j = source.length - 1; i < j; i++, k++) {
 8         tmpArray[k] = rowTemplate.replace(/%(\d)%/g, cvrt);
 9     }
10
11     tmpArray[k] = "<\/tbody>\n<\/table>";
12     dataDiv.innerHTML = tmpArray.join("\n") 
13 
14     function cvrt() {
15         return source[i][arguments[1]];
16     }
17 }

The JavaScript has only seventeen lines, and every performance enhancing technique has been used. The code builds an HTML string representing the table from the opening <table> to the closing </table>. Then the string is assigned to the innerHTML property of the table's container div.

On line 4, a template for a row is defined. It has numeric place holders in the form %n% that match the expected value's array index. The template is used on line 8 with a regular expression. Names or labels could be used instead of numbers, which would be useful if each array row had and object for the cells, then the placeholder would be %name%.

The regular expression, on line 8, used in the string replace method generates a string representing a table row by replacing the placeholders with the cell values. The replacement value in replace is a function. By putting parenthesis around the meta character \d the number is passed to the function as the second argument. (More on Regular Expression.)

If names where used instead of numbers, the regular expression would look like this /%(name1|name2|name3)%/g.

The function used as the replacement value is nested within the load function. Nested functions have access to all of the parent function's local variables so it has the correct value i.

String concatenation is an expensive process. To avoid that cost, the row strings are put in a temporary array and then joined in one statement using the array join method.

Writing data into the HTML document is where most of the process time is used. The JavaScript processing represents a small percentage of the elapsed time. Writing all the data into the document at one time is where the performance increase is achieved.

Threaded JavaScript  

It is possible to cause JavaScript to run in theads concurrent with other processes. Runing the table load process in its own thread, when it is run on page load, allows images to finish loading.

<script type="text/javascript">
    setTimeout(function(){loadTable2("tableDiv", dataArray);}, 0);
</script>

The snippet of code above is located just before the closing body tag. Using the setTimeout function causes our table loading code to run in a separate thread.