非阻塞式JavaScript

12

我想知道是否有可能以一种不会阻塞用户体验的方式加载JavaScript。我不确定如何实现相同的效果,但我正在寻找一个跨浏览器的解决方案。我想知道是否有人能够指导我正确的方向。将js放在页面底部效果不太好。

谢谢你的时间。


啊,我曾经有一个非常好的链接,但是现在找不到了。 - Greg
需要澄清一下:您是在谈论加载JavaScript文件资源,例如<script>标签,还是JavaScript函数的执行? - Jonathon Faust
由于这不是跨浏览器的,我不会将其发布为解决方案,但对于不会冻结DOM事件的线程化JavaScript,请查看Web Workers API。 - Patrick Roberts
7个回答

14

Javascript运行在单线程中,因此如果您有大量的Javascript调用,比如使用ExtJS等库,它可能会变慢。然而,您可以考虑以下替代方案:

首先,尽可能优化代码。

其次,您可以使用Javascript中的计时器来模拟异步工作。这是一个很好的示例:http://ejohn.org/blog/how-javascript-timers-work/

如果您想获得更多信息,以下是一些额外的提示,可尝试减少Javascript冻结时间。

http://debuggable.com/posts/run-intense-js-without-freezing-the-browser:480f4dd6-f864-4f72-ae16-41cccbdd56cb

祝你好运!


3
引用这个答案
JavaScript资源请求确实会阻塞,但有方法可以解决(即:head中的DOM注入脚本标签和AJAX请求),在没有看到页面之前这可能是发生的情况。
包含多个相同JS资源的副本非常糟糕,但不一定致命,并且通常出现在较大的网站上,这些网站可能来自不同团队的工作,或者只是坏的编码、规划或维护。
至于雅虎建议将脚本放在body底部,这可以改善感知响应时间,并在一定程度上提高实际加载时间(因为所有先前的资源都被允许异步),但它永远不会像非阻塞请求那样有效(尽管它们具有技术能力的高门槛)。
您可以查看YUI博客条目关于非阻塞Javascript

2
当页面加载时,它一次只能同时下载2个javascript文件,因此尽量减少javascript文件的数量和大小(通过Minification、obsfucation和GZipping)可以帮助提高加载体验。
在javascript中使用回调函数也可以帮助非阻塞地运行项目。
一个jQuery示例:
$('#id').click(function(){
  $.post('url',data,function(callbackdata){//do something
         });

});

2

在Google上搜索“onload Javascript”可以提供很多信息,例如http://onlinetools.org/articles/unobtrusivejavascript/chapter4.html这样的网页。 - H_I
1
是的?我太懒了,没有提到它,但它在指出的文章中。 - H_I

1

使用小延迟的setTimeout函数可以让控制流程继续进行,同时安排另一个函数稍后执行。这对于防止UI阻塞或意外依赖其他函数的成功执行特别有用。

我发现这非常有用,可以防止JavaScript错误干扰绑定事件。例如,在表单上安装提交处理程序:

$('#form').submit(function() {
  setTimeout(function() {
    // Submit handler function, i.e. do an ajax submission of the form
    $.ajax(...etc...);
  }, 1);
  // Return false before the handler executes, ensuring the form won't manually submit
  // in the event of a js error in the handler
  return false;
});

0

延迟执行 JavaScript 可以是一个非常好的解决方案,如果你有一些不紧急需要立即加载的 JavaScript。


1
不,这是所有主流浏览器都支持的:http://www.webkit.org/blog/1395/running-scripts-in-webkit/ http://hacks.mozilla.org/2009/06/defer/ - mikl

-1

看看这个jQuery插件(http://code.google.com/p/funky-jq-plugins/wiki/nonblocking)。

它旨在使用计时器来模拟多线程环境,其中UI线程不会被迭代长列表等要求操作冻结。非常酷的东西......我写的 :)

现在先告别。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接