Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 防止浏览器在回流期间变得无响应_Javascript_Html_Css_Dom - Fatal编程技术网

Javascript 防止浏览器在回流期间变得无响应

Javascript 防止浏览器在回流期间变得无响应,javascript,html,css,dom,Javascript,Html,Css,Dom,我使用javascript函数向站点添加非常大的嵌套表。我已经设法优化了javascript本身,使其运行得相当快,但是浏览器在回流时往往会挂起(通常为5-10秒),因为每次都要添加50MB的HTML并不少见。只有一个回流事件,但最好删除此非响应期 是否可以让回流事件在后台运行,或者让子表默认为display:none并有一个按钮来显示它们更简单 代码将在必要时发布 AJAX请求: function getResult(command,server) { var xmlhttp

我使用javascript函数向站点添加非常大的嵌套表。我已经设法优化了javascript本身,使其运行得相当快,但是浏览器在回流时往往会挂起(通常为5-10秒),因为每次都要添加50MB的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;
    }

似乎您正在使用这种模式:

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);
EDIT:尽管上面的说法仍然成立,但真正的问题是修改DOM树的错误方法。我们不会构建一个巨大的HTML字符串并将其分配给某个元素的
innerHTML
属性。我们使用
DOM操作方法

例如:

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);
}

你考虑过分页吗?或者类似谷歌图片的功能(滚动时加载)。发布发出AJAX请求的代码。另外,请告诉我们您是从服务器获取HTML还是仅获取数据,然后使用JS构建DOM部分?@ElmoVanKielmo仅从服务器获取JSON字符串-我使用JS构建DOM。我将在主体中发布AJAX请求的代码,尽管对于较大的表只需要大约2秒钟,那么AJAX就不是问题了。您是立即向文档中添加新元素,还是构建整个DOM部件并在准备就绪时将其追加?50MB的HTML总是会给您带来性能问题。我已经将其简化为一个回流事件-我使用了与您描述的第二个类似的方法,使用函数创建表,然后立即追加整个表。引起问题的似乎是变化的规模,而不是事件的数量。我将在问题中添加代码。请注意,性能问题的另一部分是在一个循环中连接(我假设)50MB的字符串数据,天知道有多少次。您基本上是在复制50MB字符串,并将其扔掉每个循环。@tcooc我不是在复制字符串。你什么意思?@ElmoVanKielmo我想他是想回答我me@ElmoVanKielmo我刚刚补充了您的解决方案,另一个严重的性能问题是字符串concats的使用。