防止浏览器在重排期间变得无响应

时间:2014-08-18 16:24:58

标签: javascript html css dom

我使用javascript函数将非常大的嵌套表添加到站点。我设法优化了javascript本身,因此它运行得非常快,但浏览器在回流过程中往往会挂起(通常持续5-10秒),因为添加50 MB的HTML并不罕见在每一次去。只有一个回流事件,但最好删除此无响应时段。

是否可以在后台运行重排事件,或者将子表默认为display: none并有一个显示它们的按钮会更简单吗?

代码将根据需要发布。

AJAX请求:

function getResult(command,server) { 
        var xmlhttp=new XMLHttpRequest();
        xmlhttp.open("POST",baseCommand.concat(server).concat(basePath).concat(command),false);
        xmlhttp.send(null);
        result=JSON.parse(xmlhttp.responseText);
        return result;
}

用于构建网站的代码:

function buildTabs() {
        var tabsString="";
        //Formatting and such here
        for (var i in commands) {
            tabsString=tabsString.concat(buildTab(commands[i]));
        }
        //A bit more formatting
        document.getElementById('tabsTable').innerHTML=tabsString;
    }

1 个答案:

答案 0 :(得分:2)

好像你正在使用这种模式:

var container = document.getElementById('container_id');
// Container is an already existing and visible DOM node which holds tables
var result = getResult(command, server);
var table = document.createElement('table');
container.appendChild(table);
// Here comes the big nested for-loop
// which fills the table with results from AJAX call

这样,您可以强制浏览器重新计算单元格大小,并在每次添加新行时重绘表格。这会伤害您的浏览器。

在表格尚未附加到文档时填充表格。这种方式计算和重绘只会进行一次。正确的模式是这样的:

var container = document.getElementById('container_id');
// Container is an already existing and visible DOM node which holds tables
var result = getResult(command, server);
var table = document.createElement('table');
// Here comes the big nested for-loop
// which fills the table with results from AJAX call
container.appendChild(table);

编辑:虽然上述情况仍然存在,但真正的问题是修改DOM树的错误方法。我们不构建一个巨大的HTML字符串并将其分配给某个元素的innerHTML属性。我们使用DOM manipulation methods

示例:

function buildTabs(nested_array){
    var table = document.createElement('table');
    // Also use CSS classes to do formatting - not inline styles
    table.addClass('my_table_class');
    var tbody = document.createElement('tbody');
    for (var i in nested_array){
        var row = nested_array[i];
        var tr = document.createElement('tr');
        for (var j in row){
            var cell = row[j];
            td = document.createElement('td');
            text_node = document.createTextNode(cell);
            td.appendChild(text_node);
            tr.appendChild(td);
        }
        tbody.appendChild(tr);
    }
    table.appendChild(tbody);
    document.getElementById('tabsTable').appendChild(table);
}