setTimeout 导致的浏览器假死

问题

   前几天,同事遇到一个浏览器假死的问题。就是浏览器在响应一个请求的时候,就突然不响应时间,进入假死状态,Cup也飙升到100%. 但是这个问题只出现在IE浏览器,chrome和Firefox等其他浏览器正常。

原因

  Js 代码里面,看着也没有什么耗时的操作和后台异步调用。没办法,只能从响应事件的最开始一步一步调查。经过一番调试之后,问题定位在setTimeout 函数。当把setTimeout 里面执行的函数去掉之后,立马就不会出现这种情况。查看setTimeout 里面调用的函数,发现里面JS中有一些的DOM操作,函数里面还进行了html的拼接。难道是这个原因导致的。于是网上查原因:当一段JS脚本长时间占用着处理机就会挂起浏览器的GUI更新,而后面的事件响应也被排在队列中得不到处理,从而造成了浏览器被锁定进入假死状态。说白了就是:浏览器无法在渲染页面的同时执行js。在setTimeout 函数里面,确实有一些拼接html 和操作dom 的情况。可能就是js在执行的时候,js代码里面又有一些拼接html 的操作。导致浏览器无法渲染页面,而js 里面在操作这个页面的内容。导致浏览器卡死。

浏览器的内核处理方式:

  浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。

  1. JavaScript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来然后加以处理,浏览器无论再什么时候都只有一个JS线程在运行JS程序。
  2. GUI 渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。
  3. 事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。

  明白了浏览器内核处理方式,就可以理解浏览器为什么会进入假死状态了,当一段JS脚本长时间占用着cpu 时间时,就会挂起浏览器的GUI更新,而后面的事件响应也被排在队列中得不到处理,从而造成了浏览器被锁定进入假死状态。另外JS脚本中进行了DOM操作,一旦JS调用结束就会马上进行一次GUI渲染,然后才开始执行下一个任务,所以JS中大量的DOM操作也会导致事件响应缓慢甚至卡死浏览器。

  这个文章写得更加透彻:http://www.nowamagic.net/librarys/veda/detail/787

setTimeout 导致的浏览器假死

时间: 2024-10-09 14:10:11

setTimeout 导致的浏览器假死的相关文章

浏览器假死

在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出"脚本运行时间过长"的提示框,如果出现这种情况说明你的脚本已经失控了,必须进行优化. 为什么会出现这种情况呢,我们先来看一下浏览器的内核处理方式: 浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程. JavaScript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来然后加以处理,浏览器无论再

火狐浏览器打开带flash的页面浏览器假死,崩溃

火狐浏览器打开带flash的页面浏览器假死,崩溃 今天打开页面时运行了flash插件,然后发现整个浏览器没有反应,浏览器未出现无响应提示,并且电脑内存,CPU都处于正常范围,在网上看了半天,大致原因是因为flash的安全沙箱技术,导致浏览器崩溃 解决方案 1.点击 菜单 中的 附加组件. 然后左侧选择 插件 . 然后在右侧 找到 Shockwave Flash.点击选项. 取消勾选 拦截骚扰与危险性的flash内容. 重启火狐即可. 2,手动更改,百度上的教程都是这种方法,效果与上面的方法一样,

(转)优化js脚本设计,防止浏览器假死

在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出“脚本运行时间过长“的提示框,如果出现这种情况说明你的脚本已经失控了,必须进行优化. 为什么会出现这种情况呢,我们先来看一下浏览器的内核处理方式: 浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程. JavaScript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来然后加以处理,浏览器无论再什么时候都

优化js脚本设计,防止浏览器假死

在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出"脚本运行时间过长"的提示框,如果出现这种情况说明你的脚本已经失控了,必须进行优化. 为什么会出现这种情况呢,我们先来看一下浏览器的内核处理方式: 浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程. JavaScript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来然后加以处理,浏览器无论再

jQuery Ajax同步参数导致浏览器假死怎么办

俗话说不作死就不会死,今天作死了一回,写了一个比较二逼的函数,遇到了同步Ajax引起的UI线程阻塞问题,在此记录一下. 事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则,我封装了一个名为getData的函数,它接收不同参数,只负责获取数据,然后把数据return.基本的逻辑剥离出来是这样的:  代码如下 复制代码 function getData1(){        var result;        $.ajax({            url : 'p.

win10下使用搜狗浏览器切换输入法导致浏览器假死解决方法

打开搜狗安装目录,例如E:\SogouExplorer\6.0.5.17804\wkdlls\PepperFlash  找到pepflashplayer.dll这个文件将其重命名即可.

js ajax同步请求造成浏览器假死的问题

一.问题的起因 今天做一个需求遇到了这么个情况,就是用户个人中心有个功能,点击按钮,可以刷新用户当前的积分,这个肯定需要使用到ajax的同步请求了,当时喀喀喀三下五除二写玩了,大概代码如下: /** * 异步当前用户积分 by zgw 20161216 * @return {[type]} [description] */ function flushIntegralSum() { //点击按钮刷新前修改按钮的文案,已经去掉点击事情,防止多次点击 $("#flushbutton").r

AjaxPro实现异步调用,解决浏览器假死及超时问题

平时使用AjaxPro的时候基本上非常easy var msg = UseClass.Method(argument).value; 由于后台响应比較慢,所以加了个"loading",然后后面调用AjaxPro //载入Loading $("#load").show(); //Ajax var msg = UseClass.Method(argument).value; //隐藏载入 <pre name="code" class="

DirectSound导致程序启动假死

错误代码:DirectSound.dll"正尝试在 OS 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起. 解决方案有设置配置文件的startrup节点 <startup useLegacyV2RuntimeActivationPolicy="true"> 如果提示 未处理System.TypeInitializationException 说明检查不到设备 需要查看设备驱动或启动虚拟录音设备 原文地