如今,我正在优化一些js代码。有一个名为appendXYZ的函数,它与其他函数循环调用。它看起来如下所示:
function OuterFunc (){
for(...){// about 150 times
...
appendXYZ();
//other dependent functions
...
}
}
现在,我非常确定appendXYZ会导致较高的cpu使用率-它可以达到50%,但是,如果我删除此功能,CPU使用率仅为1%。当CPU使用率为50%时,浏览器几乎被冻结,页面缺乏响应能力。而且,OuterFunc每20秒执行一次,appendXYZ来自第三方脚本代码,我无法对其进行修改。那么如何优化此代码?
现在我正在尝试使用setTimeout,但我不知道它是否有效。
我不知道该函数的作用,但是您可以尝试使其调用异步。
它可能会也可能不会,并且仍然需要相同数量的CPU,但是至少应该释放一点浏览器。
function OuterFunc (){
for( var i = 0; i < 150; i++ ){
// ...
setTimeout( appendXYZ, 0 );
//other dependent functions
// ...
}
}
再次可能会破坏功能。无法看到更多代码就无法分辨。
如果您要传递参数,则需要类似以下内容:
function invoker( j ) {
return function() {
appendXYZ( j );
};
}
function OuterFunc (){
for( var i = 0; i < 150; i++ ){
// ...
setTimeout( invoker( i ), 0 );
//other dependent functions
// ...
}
}
如果您无法做任何事情来优化实际代码,则可以分散执行循环迭代,以保持浏览器的响应速度。根据Robert Miller's paper,您可以按住UI并仍能感觉到对用户响应的最长时间为100毫秒。有关如何使用setTimeout
执行此操作的技术,请参见UI responsiveness and javascript。
[可能性是OuterFunc
执行时间大于其重复间隔。换句话说,OutherFunc
的执行时间超过20毫秒,每20秒被调用一次,它将产生一个[[stackoverflow异常,因为该函数在完成它在无限循环中执行之前被调用。如果使用setInterval
每20毫秒执行一次OuterFunc
函数,则可以通过使用setTimeout
调用来模拟setInterval
函数来解决此问题:
(function helper(){
OutherFunc();
// after the OutherFunc is done executing, trigger it after 20 milliseconds
setTimeout(helper, 20);
})();
仅当setInterval
是浏览器冻结的原因时,这才有帮助。如果这对您没有帮助,并且您不太在意旧版浏览器,则可以使用web-workers实现某种“threading”。这样,您的代码将在不同的线程中执行,这肯定会加快您的应用程序的速度(也称为再见浏览器冻结)。
希望这会有所帮助!