`
darrenzhu
  • 浏览: 804157 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

消除IE stop running this script弹出框

阅读更多

问题描述和分析:

最近用ExtJS开发的代码在IE8里面跑时, IE跳出了stop running this script的提示, 提示如下:
Stop running this script?
A script on this page is causing your web browser to run slowly. If it continues to run, your computer might become unresponsive.

当然有些提示可能如下:

A script on this page is causing Internet Explorer to run slowly. If it continues to run, your computer may become unresponsive. Do you want to abort the script?

你可以点击"YES"或"NO",点击"NO",IE会继续执行脚本,执行结果跟没有弹出这个框的结果是一样的,点击"YES", IE停止执行脚本,这时候看到状态肯定是不正常的,如果用户都理解原理,并且每次都选择"NO",那么我们就不需要做任何修改了. 但这肯定是不可能的.

咋一看时, 以为肯定是程序的性能慢得IE自己都受不了了,所以跳个框出来,希望用户手动停止, 我的第一反映当然也是这样. 但是奇怪的是我在一台运行速度很快的电脑上, 2秒左右IE也跳出了这个信息, 这就让我困惑不已了,虽然2秒不算短,但是基于web技术的程序代码执行时间超过2秒的应该是可以接受的, 于是google了一下, 看到IE support team 提出的一个解决方案, 参考链接为:http://support.microsoft.com/kb/175500,
里面明确解析如下:

As of Internet Explorer 4.0 and later versions, the time-out is no longer a fixed value based on Windows messages. Internet Explorer now tracks the total number of executed script statements and resets the value each time that a new script execution is started, such as from a timeout or from an event handler, for the current page with the script engine. Internet Explorer displays a "long-running script" dialog box when that value is over a threshold amount. Internet Explorer doesn’t check on each instruction to see if it is over the limit. Periodically the script engine polls Internet Explorer with the number of statements executed and Internet Explorer checks if that is over the limit. Because of this mechanism, it is possible to execute more than the default limit without the dialog if the entire script execution finishes before the script engine polls Internet Explorer.

大致意思是: 从IE4.0的版本开始, 这个'long-running script'的弹出框其实并不是由于你的代码执行的时间超过了一个预先设定的值,而是周期性的检查IE执行的代码总行数是否超过了一个预设的值(这个值可以通过注册表修改),如果超过了就会弹出上面所说的框.

这个设计相当有意思,意味着就算你的代码在1秒钟内执行完成了,但是如果这1秒钟之类执行过的语句行数超过了这个预设的固定值,IE还是会弹出这个stop running script的框,这显然会让我们很困惑. 因为速度这么快,还跳出了这个框,难道要我们的代码不耗时间?

说实话,我看完这段解释后,还是不愿意接受这个观点, 只好自己实验一把了.

实验一,本实验代码会跳出stop running this script框,代码如下:

<html>
	<head>
		<title>IE Long Running Script Issue</title>
	</head>
	<body>
		Statements Execution Number: <span id='outputTxt'>0</span>	
		<script type='text/javascript'>		
			function exceedExectutionStatmentsLimit(){
				var i=0, str='', output=document.getElementById('outputTxt');
				for(; i<5000000; i++){
					str=str+i;
					if(i % 100000 ===0){
						output.innerHTML=i;
					}
				}
				output.innerHTML=i;
			}			
			exceedExectutionStatmentsLimit();
		</script>
	</body>
</html>


用IE打开上面的html页面,会跳出stop...的框,选择yes后,页面输出为
Statements Execution Number: 1700000
这里暂时不解释这个输出,下面会有解释

实验二,本实验IE不会跳出stop running this script框,虽然本代码的执行时间超过了上面的代码

<html>
	<head>
		<title>IE Long Running Script Issue</title>
	</head>
	<body>
		Statements Execution Number: <span id='outputTxt'>0</span>
		<script type='text/javascript'>
			function AvoidLongRunningScriptMessageDisplay(){
				var i=0, str='', output=document.getElementById('outputTxt');
				
				(function () {
				    for (; i < 9000000; i++) {
								str+=i;
				        // Every 100,000 iterations, take a break
				        if (i % 100000 == 0) {
				        		output.innerHTML=i;
				            // Manually increment `i` because we break
				            i++;
				            // Set a timer for the next iteration 
				            window.setTimeout(arguments.callee);
				            break;
				        }
				    }
				})();				
			}
			AvoidLongRunningScriptMessageDisplay();
		</script>
	</body>
</html>


页面输出为Statements Execution Number: 8900000


所以至少得出一个结论,IE官方的解释的确是言行一致,弹出框的跳出只与执行过的代码总行数有关,与其执行耗费的时间无关.


那么接下来有两个问题:
1)代码执行行数的限制是多少;
代码执行行数的限制是多少, 这个值是在注册表里面可修改的,默认是500万行, 当然你可以修改成更大,这样你也能阻止IE跳出stop running this script框,但显然
你只能解决你的IE,其他人的电脑注册表没修改过的话,还是会跳出来的,所以这个方案并不好.关于如何修改本文开头的解决方案3)已经给出了答案.

另外需要注意的是,事实上IE不会每执行一条语句就会检查是否总共执行过的代码行数是否超出了限制,这样显然很耗性能也不明智,IE会周期性的去检查,所以如果你
碰巧在IE来检查时没有超过限制,而不检查时超过了限制,你也不会看到stop script弹出框,当然这就跟中奖一样,看你运气了.

2)代码执行的总行数是怎么计算的;
a) 使用setTimeout调用的函数, 函数里面的代码使用的是一个新的计数器
b) 事件处理函数理的代码使用的也是一个新的计算器
c) 除此之外使用的是同一个计数器,很显然,如果你的代码既没有setTimeout也没有是用
    event handler,那么很容易让计数器超过阀值


另外实验一中点了yes后,为什么输出的是Statements Execution Number: 1700000, 而不是500万呢,那是因为for循环了还有其他的代码,输出的是170万,
但是实际执行的已经有500万了.

如果你还是不相信上面的结论,那么可以用简单的方式,用程序生成500万行左右的javascript语句,看看是否真是500万行会跳出框,我给出了java代码的实现,

有兴趣你可以试一下,但提前预告一些,如果你生成了500万行语句,整个html文件大概有80M大,请做好心理准备,只怕目前你还没有运行过如此大的网页,你的IE
很容易死掉,电脑也可能会变慢,另外下面代码使用的是jdk1.7,

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class GenerateJavascriptCodeForTesting {

	public static void main(String[] args) {
		Path outPut=Paths.get("c:\\tmp\\jsTest.html");
		List<String> content = new ArrayList<String>();
		content.add("<html><head><title>IE Long Running Script Issue</title></head><body><span id='outputTxt'>0</span><script type='text/javascript'>");
		content.add("function exceedExectutionStatmentsLimit(){var i=0, str='', output=document.getElementById('outputTxt');");
		int i=0;
		for(;i<6000000;i++){//try 4000000, 5000000, 6000000 and see whether the stop running script message will be shown up
			content.add("str+="+i+";");
			if(i%100000==0){
				content.add("output.innerHTML="+i+";");
			}
		}
		content.add("output.innerHTML="+i+";}");
		content.add("exceedExectutionStatmentsLimit();");
		content.add("</script></body></html>");
		try {
			Files.write(outPut, content, Charset.forName("UTF-8"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

}



解决方案:

首先特别提出一点, 触发事件并执行事件处理函数是一个同步过程,不是异步过程. 可以参考我的另一篇文章:http://darrenzhu.iteye.com/blog/2029822

1. setTimeout
使用setTimeout将大量代码分开执行,每个setTimeout会使用一个新的代码行数计数器,这样你的代码就会减少弹出"Stop running script ..."窗口的机会. 当然很多时候,我们并不会碰到该问题,毕竟500万行代码不是个小数目,不过程序命中的概率比你中500万的彩票显然要容易得多.

2. 通过事件
把你的代码放到事件处理函数里面, 当然事件可以是系统的事件如mouseover, click, 也可以是你自定义和手动触发的. 事件机制为什么能解决这个问题,是因为IE的代码计数器对事件处理函数里面的代码重新计数,已经跟当前控制流的代码计数器分开了.

我更倾向于用事件机制来解决, 因为用setTimeout,你必须指定一个时间,时间设置得不管有多么短,都会有延迟,而事件不会有延迟,当你触发了事件,立马会去执行事件处理函数.

3. 修改注册表, 至于为什么可以通过修改注册表解决这个问题,请看下文的解释
要修改IE4 - IE8的time-out的值,按如下方式操作:
1)运行Regedit32.exe, 找到下面这一项
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Styles
如果Styles这一项不存在, 你可以创建这一个项

2)创建一个类型为DWORD的键值"MaxScriptStatements", 并且设置它的值为你需要的脚本代码总函数, 如果你不知道设置多少合适, 你可以将其设置成0xFFFFFFFF, 这样就可以避免IE弹出"Stop running Script ..."的框.

默认Styles这一项是不存在的, 这个时候默认的弹出time-out框的代码总函数限制是500万行, 当然是针对IE4 - IE8来说.
分享到:
评论
1 楼 luedipiaofeng 2014-10-10  
good

相关推荐

    jquery弹出框样式

    本文将深入探讨如何利用jQuery创建美观的弹出框样式,以提升用户体验。 首先,让我们理解“弹出框”的概念。在网页设计中,弹出框是一种常见的用户界面元素,用于在不离开当前页面的情况下显示额外信息或交互功能。...

    QQ弹出框

    在Windows桌面应用开发中,创建一个类似于QQ弹出框的效果是一项常见的需求,特别是在C# Winform环境下。这种弹出框通常具有吸引用户注意力的特点,同时又不会过于突兀,通过淡入淡出动画来增强用户体验。本文将详细...

    C# 桌面弹出窗体,右下角弹提示框

    这通常通过“弹出窗体”或者“提示框”来实现,它们可以在不打断用户主界面工作流程的情况下,提供一种轻量级的交互方式。在本主题中,我们将深入探讨如何使用C#在桌面应用的右下角实现类QQ的弹框提示功能。 首先,...

    泡沫弹出框式的侧边导航菜单

    ### 泡沫弹出框式的侧边导航菜单:深入解析 在现代网页设计中,导航菜单作为用户界面的重要组成部分,其美观与功能性直接影响着用户体验。本文将深入探讨一种独特的导航菜单设计——“泡沫弹出框式的侧边导航菜单”...

    C#仿QQ弹出消息框的实现

    在C#编程中,模拟QQ弹出消息框是一项常见的需求,尤其在开发具有用户交互性的桌面应用程序时。本文将详细讲解如何使用C#实现一个类似于QQ的弹出消息框,包括窗体的动画效果,如向上弹出、向下降落以及渐变透明消失。...

    jquery实现多风格消息弹出框插件jGrowl下载

    **jQuery实现多风格消息弹出框插件jGrowl详解** 在Web开发中,消息提示框是用户交互的重要组成部分,用于向用户提供反馈信息。jGrowl是一款基于jQuery的轻量级插件,它允许开发者轻松地创建具有多种样式的弹出通知...

    uniapp 仿微信的右边下拉选择弹出框的实现代码

    在本文中,我们将深入探讨如何使用uniapp框架实现一个仿微信风格的右边下拉选择弹出框。这个组件主要用于提供用户交互,展示一系列可选项,如搜索、门店查询、货号查询等。以下是对实现这一功能的代码进行的详细解析...

    start-stop-daemon

    -w|--chdir &lt;dir&gt; change the work directory to 'dir' -u|--user |&lt;uid&gt; stop processes owned by this user -n|--name &lt;process-name&gt; stop processes with this name -s|--signal &lt;signal&gt; signal to send ...

    【JavaScript源代码】vue自定义弹框效果(确认框、提示框).docx

    本实例展示了如何在Vue项目中实现一个自定义的弹框组件,该组件可以根据传入的`type`参数来区分是确认框还是提示框。 首先,我们看到组件的模板部分,使用了Vue的`&lt;template&gt;`标签来定义组件的结构。在这个模板中,...

    jquery js 效果,弹出提示框

    本教程将详细讲解如何利用jQuery实现一个类似Discuz论坛系统的右下角弹出提示框效果。 首先,让我们理解jQuery的核心概念。jQuery库通过一个简洁的语法,使得DOM操作变得简单易行。例如,`$(selector).action()`...

    ThrottleStop_9.2_heat_throttletsop_源码

    ThrottleStop的主要目标是消除由于过热导致的CPU降频现象,从而提升电脑的工作效率。 在描述中提到的"throttle stop"是指电脑系统中的一个机制,即当CPU温度过高时,系统为了防止硬件损坏,会自动降低处理器的运行...

    ThrottleStop使用方法

    ThrottleStop是一款专门为笔记本电脑设计的工具,它允许用户调整CPU的节流设置,从而实现超频或优化电源管理。这款软件尤其适用于那些希望提升性能或者解决CPU过热问题的用户。本文将详细介绍ThrottleStop的使用方法...

    ThrottleStop_9.3.zip

    logo.png是ThrottleStop的图标,简洁而直观,一眼就能识别出这个强大的性能调整工具。 ReadMe.txt是软件的说明文档,通常包含了一些安装、使用和注意事项。对于初次接触ThrottleStop的用户来说,这是一个重要的参考...

    VM虚拟机Ubuntu系统打开报错A start job is running for Create Volatile Files and Directories(no limit)解决方案

    报错是因为虚拟机的磁盘用完了,想要正常启动需要进入recovery模式,进去把不需要的文件删除,然后才你那个正常启动。 1.重启Ubuntu,随机长按shift进入grub菜单,或等待grub菜单出现 2.选择Advanced options for ...

    winForm 窗体动态弹出

    本教程将深入探讨如何在WinForm中实现窗体的动态弹出和渐隐效果,为你的程序增添一丝独特魅力。 首先,我们需要理解WinForm窗体的基本操作。一个WinForm窗体是由多个控件(如按钮、文本框等)组成的,它们可以通过...

    交通标志stop检测数据集stop-traffic-data.rar

    1. 图像分类:数据集的核心任务是图像分类,即识别出图像中的交通标志是“STOP”标志。 2. 计算机视觉:涉及图像预处理(如归一化、灰度化、二值化)、特征提取(如边缘检测、颜色直方图、SIFT、HOG等)和模型训练...

    ThrottleStop v6.0 汉化

    ThrottleStop v6.0 汉化版是一款专为CPU性能优化设计的软件,尤其适合那些希望精细控制自己电脑性能的用户。该工具能够帮助用户深入调整CPU的工作状态,从而实现性能提升或降低功耗的目标。对于笔记本用户来说,这款...

    BBands_Stop_v1_BAR.rar_BBands_Stop_v1_bandsstop_bbands stop_不漂移_

    BBands_Stop_v1_BAR.rar 文件包含的是一个名为 "BBands_Stop_v1_BAR.ex4" 的MT4(MetaTrader 4)指标,这个指标基于著名的布林带(Bollinger Bands)理论,结合了停损概念,帮助交易者识别市场趋势并提供交易信号。...

Global site tag (gtag.js) - Google Analytics