JavaScript 在各个浏览器中执行的耐性_javascript技巧

IE:执行超过500W条JScript引擎语句出现提示。
Firefox:执行超过10秒出现提示。
Safari:执行超过5秒出现提示。
Opera:无论执行多久都不会出现提示,最有耐性。
Chrome:执行超过约8秒(估计值)出现提示。
注:当弹出类似alert的模式对话框的时候,是不计时。

在Web开发的时候,经常会遇到的一种情况就是浏览器提示脚本运行时间过长,停止还是继续,无论你选择什么,相信你都会想尽一切办法让这个对话框远离你的用户们。可你是否知道,这些不同的浏览器究竟是如何判断,哪些脚本处于“失控”状态么?本文作者,就从Internet Explorer、Firefox、Safari、Chrome和Opera五种浏览器,分析了这个情况出现的原因。

【原文标题】What determines that a script is long-running?
【原文作者】Nicholas C. Zakas

以下是对原文的翻译:

Web开发者经常遇到并必须及时处理的问题就是“提示脚本运行时间过长的提示框”(或者称为“失控脚本提示”),这些令人讨厌的对话框会在你的脚本 执行时间过长的时候出现。对于Web开发者的基本准则就是,无论什么时候,都不要让用户看到这些对话框,因为这会给人一种代码缺乏结构化的印象,更简单的 说,你的代码负担太重了。

用Brendan Eich(JavaScript的发明人)的话来讲,如果JavaScript运行的时间需要用秒来计算,一定是什么地方搞错了。我个人可以忍受的上限可 能更小一些,不论什么脚本,在任何时间、任何浏览器上执行,都不应该超过100毫秒。如果实际执行的时间长于这个底限,一定要将进程分解成若干更小的代码 段。

另外,其实很少有人真正意识到究竟是什么原因导致脚本在不同的浏览器中运行时间过长,连我自己都没有深究过。所以我决定坐下来好好研究一下,我们究 竟会在什么情况才会看到那个讨厌的对话框。判断脚本是否失控,无外乎就两种方法。一种是根据执行了多少条语句,一种是判断脚本执行花费的时间。各个浏览器 判断脚本失控的具体方法会有略微的不同。

Internet Explorer

Internet Explorer判断一个脚本是否失控,主要通过JScript引擎执行语句的总数来判断。默认情况下,这个上限是500万条语句,这个值是可以通过注册表修改的。当你的脚本执行的语句数量超过这个限制,你就会看到下面的窗口。

这个对话框提示:“这个页面上有一段脚本导致Internet Explorer运行缓慢,如果你继续运行,你的计算机可能会变为无响应状态”。要不是追求技术上的准确性,这样说确实有点过了。对话框有两个选项,要么 停止脚本执行,要么允许脚本继续运行。当这个对话框显示的时候,脚本已经被完全停止了。如果你选择继续运行脚本,就会重新计算当前执行的语句数,也就是 说,如果这个数值再次达到上限时,你会再次看到这个对话框。

Firefox

Firefox是根据脚本引擎持续执行代码的时间来判断一段脚本是否失控。默认的上限是10秒,可以通过about:config页面来修改这个值。这里需要注意的是,当弹出类似alert的模式对话框的时候,是不计时的。当浏览器执行脚本的时间达到这个上限,Firefox就会显示类似下面的对话框:

Firefox的对话框提示:“这个页面的一段脚本目前运行忙,或者这段脚本已经停止响应。你可以停止执行这段脚本,并在调试器中打开这段脚本,或 者保持这段脚本继续运行”。更清楚的描述了遇到的问题,并且没有IE说的那么恐怖。在这个对话框上可以执行三种操作:停止脚本执行、调试脚本或者让脚本继 续运行。和Internet Explorer一样,当运行脚本继续运行以后,对持续运行脚本时间的统计就会重置。调试脚本按钮,只有在你安装了Firebug,并在该页面激活了调试 的时候才会出现。执行调试脚本操作后,可以显示执行时间过长的代码段的具体位置。

Safari

Safari同样根据脚本引擎持续执行脚本的时间来判断,当我对Webkit的源代码进行反复研究后,发现默认的超时时间是5秒,一旦达到这个上限,就会给出下面的对话框提示:

对话框提示:“在页面url上的脚本让Safari失去响应,你是要继续运行脚本还是终止脚本”。同样的,对于用户来说,也不是什么可怕的提示。在Safari中,可以关闭失控脚本的检测功能。

Chrome

Chrome在跟踪技术上有点狡猾,失控脚本检测功能似乎和tab的事故控制(crash control)关联到一起。我仔细看了源代码,却没有找到具体的限制,但基本确定的是,这个限制是以时间为基础的,估计在10秒左右(要么是5秒,要么 是10秒,总要和Safari或者Firefox看齐么)。我正在联系Chrome项目组中的朋友,看看能不能得到确定的信息。尽管如此,如果网页中存在 失控的脚本,用户还是会看到下面的对话框:

毫无疑问,Chrome的提示比起其他浏览器来说,显得都更加严重。点击“Wait”按钮,脚本会继续运行,直到达到下一个上限为止,也可以点击“Kill pages”,直接关闭该页面在内存中的所有信息,并用一个空白页取而代之。

Opera

Opera的情况比较有趣:他貌似没有针对失控脚本的相应限制。我运行了几个很长的测试,甚至花了几分钟,而在这个过程中,浏览器一直可以正常响应,这很出我的意料之外。我不是很确定,对于现在的情况来说,这个方法是好是坏,但至少它生效了,不是么?

一些建议

无论你的用户使用什么浏览器,都不应该在任何时候看到类似的提示。在你的网站或者Web应用程序作为产品发布之前,做一些常规的性能测试是非常有必要的。在这方面有很多工具可以加以利用,比如Firebug's profiler(只支持Firefox)、YUI Profiler (支持全部浏览器)或者Internet Explorer 8's Profiler。 你应该毫不犹豫地将那些执行时间超过100毫秒的脚本找出来,哪怕这些脚本只是在某些浏览器上运行不畅,这些脚本包含了一些需要执行很长时间的代码段,而 这些代码应该通过性能检测工具进行重新评估。确保你不是使用Chrome作为测试的底线,因为Chrome在执行JavaScript的速度上比其他浏览 器要高出一个数量级(和Firefox 3.1还有最新的WebKit Nightly相当)。最好使用Internet Explorer作为测试的底线,然后再测试其他浏览器,因为无论什么时候,IE的JavaScript引擎都是最慢的,当在IE上修复问题以后,十有八 九在其他浏览器上也可以正常运行了。

时间: 2024-04-20 02:28:45

JavaScript 在各个浏览器中执行的耐性_javascript技巧的相关文章

JAVASCRIPT IE 与 FF中兼容问题小结_javascript技巧

png透明 AlphaImageLoaderfilter:progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=bEnabled,sizingMethod=sSize,src=sURL) enabled:可选项.布尔值(Boolean).设置或检索滤镜是否激活.true:默认值.滤镜激活.false:滤镜被禁止.sizingMethod:可选项.字符串(String).设置或检索滤镜作用的对象的图片在对象容器边界内的显示方式.cro

JavaScript实现获取dom中class的方法_javascript技巧

本文实例讲述了JavaScript实现获取dom中class的方法.分享给大家供大家参考.具体实现方法如下: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <script> function getClass(node,classname) { if(node.getEle

javascript实现获取浏览器版本、操作系统类型_javascript技巧

代码很简洁,功能很实用,这里就不多废话了,直接给大家奉上代码: /** * Created by Administrator on 15-1-12. */ function BroswerUtil() { } BroswerUtil = { //检测浏览器版本 getBrowserVersion: function () { var agent = navigator.userAgent.toLowerCase(); var arr = []; var Browser = ""; va

setTimeout函数兼容各主流浏览器运行执行效果实例_javascript技巧

目前这个setTimeout可以很好地兼容IE6,7,8,9以及谷歌浏览器Chrome,火狐浏览器FireFox,苹果浏览器Safari,Opera. setTimeout是一个很不错的函数,网站页面前端工程师经常将其用于几秒后执行的动作.setTimeout这个JS内置函数其用法也很简单,下面是setTimeout()的函数说明以及用法详解和实例.示例代码: setTimeout()的作用是指定在多少毫秒后执行一个JS函数或者表达式代码 setTimeout的用法.语法.参数:setTimeo

js获取元素在浏览器中的绝对位置_javascript技巧

JavaScript中提供获取HTML元素位置的属性: HTMLElement.offsetLeft HTMLElement.offsetHeight 但 是需要注意的是,这两个属性所储存的数值并不是该元素相对整个浏览器画布的绝对位置,而是相对于其父元素位置的相对位置,也就是说这两个数值得到的是以其 父元素左上角为(0,0)点从而计算出的数值.那么如何得到一个HTML元素的绝对位置呢,可以用以下函数: 复制代码 代码如下: //获取元素的纵坐标 function getTop(e){ var o

利用javascript实现web页面中指定区域打印_javascript技巧

最近做到了web页面课程表打印时,上网找了一些资料,最后使用了下面的方法实现了我需要的功能.将需要打印的课程表的table放入div标签中,然后指定出需要打印的区域,最后调用window.print打印指定内容. 示例代码(代码中有些内容已省略) 复制代码 代码如下: function preview() {    bdhtml = window.document.body.innerHTML;    sprnstr = "<!--startprint-->";    ep

Javascript获取background属性中url的值_javascript技巧

前言 最近在做项目的时候遇到一个问题,需要获取一个动态预览的图片的地址,这其实不是什么问题,主要是该图片的路径是写在css的background-img属性中的,于是决定要用js获取它的url中的内容,下面给大家分享解决的方法,有需要的朋友们下面来看看. var avatar = $("#image-preview").css("backgroundImage"); alert(avatar); 获取的是包含url("xxx.jpg")形式的值,

用JS在浏览器中创建下载文件_javascript技巧

但受限于浏览器,很多情况下我们都只能给出个链接,让用户点击打开->另存为.如下面这个链接: 复制代码 代码如下: <a href="file.js">file.js</a> 用户点击这个链接的时候,浏览器会打开并显示链接指向的文件内容,显然,这并没有实现我们的需求.HTML5中给a标签增加了一个download属性,只要有这个属性,点击这个链接时浏览器就不在打开链接指向的文件,而是改为下载(目前只有chrome.firefox和opera支持). 下载时会

js获取控件位置以及不同浏览器中的差别介绍_javascript技巧

复制代码 代码如下: //获取坐标位置 function getpos(e) { var t=e.offsetTop; var l=e.offsetLeft; var height=e.offsetHeight; while(e=e.offsetParent) { t+=e.offsetTop; l+=e.offsetLeft; } } 假设 obj 为某个 HTML 控件. obj.offsetTop 指 obj 距离上方或上层控件的位置,整型,单位像素. obj.offsetLeft 指 o