// Normal, intensive, operation
var table = document.getElementsByTagName("tbody");
for ( var i = 0; i < 2000; i++ ) {
var tr = document.createElement("tr");
for ( var t = 0; t < 6; t++ ){
var td = document.createElement("td");
td.appendChild( document.createTextNode("" + t));
tr.appendChild( td );
}
table.appendChild( tr );
}
}
在这个例子中,我们创建了总数为26000个DOM节点,并将数字填入表中,这太昂贵了,很有可能将浏览器挂起以阻止用户正常的交互。我们可以将计时器引入其中,从而得到与众不同,也许更好的结果。
用计时器将耗时较长的任务拆分开来:
<table><tbody></tbody></table>
var table = document.getElementsByTagName("tbody");
var i = 0, max = 1999;
setTimeout(function(){
for ( var step = i + 500; i < step; i++ ) {
var tr = document.createElement("tr");
for ( var t = 0; t < 6; t++ ){
var td = document.createElement("td");
td.appendChild( document.createTextNode("" + t));
tr.appendChild( td );
}
}
table.appendChild( tr );
}
if ( i < max )
setTimeout( arguments.callee, 0 );
}, 0);
在我们修改的例子中,我们将密集的计算分成四部分,每个创建6500个节点。这些计算不太可能中断浏览器正常的流。最糟糕的情况也只是这些数字可能随时调整(例如,使其在250-500之间变化,这样我们的每一个单元将产生3500DOM个节点)。但是,给人印象最深的是我们如何改变我们的代码以适应新的异步系统。我们需要做更多的工作以确保元素的数字正确生成(该循环不会永无休止)。这些代码与我们初始的很相似。注意,我们使用闭包维持代码片段间的迭代状态,毫无疑问,不使用闭包,此代码将更为复杂。
与原来的技术相比,使用该技术有一个明显的变化。浏览器的长时挂起被4个视觉化的页面更新替代。虽然浏览器尝试着尽可能快得去执行这些代码片段,它也在计时器的每一步操作之后渲染DOM变化(就好像大量的更新)。大多数情况下,用户觉察不到此种类型的更新,但记住它们曾经发生过很重要。
有一种情况会使该技术能专门为我服务--我构建的计算大学生日程排列的应用程序。起初,该应用程序是典型的CGI(客户与服务器交流,服务器计算出日程表之后将其返回)。但我对它作了改变,讲所有的日程计算放到客户端,这是日程计算的视图:
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/webkaifa/)这些计算的代价相当昂贵(需要遍历数以千计的排列以找到正确的答案)。将日程计算分割成实实在在的单元使这一问题得到了解决(用已经完成的那部分更新用户界面)。最后,用户提交的是快速、反应灵敏、可用性较高的用户界面。
如此有用的技术常常令人惊奇。你会发现它经常被用于长时运行的程序之中,就像测试箱(我们在这章末尾讨论它)。更为重要的是,这种技术向我们显示了解决浏览器环境的限制是多么的轻而易举,同时也为用户提供了丰富的经验。
猜你喜欢