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