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

时间: 2024-09-20 04:22:57

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

java map中写入的数据量大,入库也慢导致浏览器假死

问题描述 java map中写入的数据量大,入库也慢导致浏览器假死 由于前台要选中8000行左右的记录,提交后写入到map中,然后再从map中取出后插入到相应的表中,这时非常费时.目前插入操作也是指提交,但是提交后,目前浏览器经常会碰到假死的现象,大家有好的办法解决吗? 解决方案 你的设计有问题,批量选择,在界面上应该提供单独的设计,不是展示全部8000的记录,而是允许用户根据字段的范围来选择,界面上用可以懒惰加载和预览的方式呈现数据. 解决方案二: 数据要进行分页操作,分批插入,分批显示 解决

HTML 5 Web开发:防止浏览器假死的方法

一个浏览器至少存在三个线程:js引擎线程(处理js).GUI渲染线程(渲染页面).浏览器事件触发线程(控制交互). JavaScript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来然后加以处理,浏览器无论再什么时候都只有一个JS线程在运行JS程序. GUI 渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行.但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保

IE浏览器假死的解决办法

最近笔者电脑经常会遇到IE浏览器假死的现象,有的时候打开几个网页中途就假死了,怎么操作都没反应.另外点击QQ面板中的进入QQ空间或者微博多数时候也没有任何反应出现了典型的IE假死现象.对于IE假死现象其实笔者并不多见,此类问题往往比较蹊跷,系统各方面也未发现有问题,那么IE假死该怎么办呢?以下编辑介绍一下个人的解决办法. IE假死的解决办法 1)首先排除病毒因素 如果电脑经常会出现IE假死的情况,首先我们进行的是对电脑进行全盘扫描,排除病毒破坏干扰. 2)升级IE浏览器 排除病毒干扰后,我们再来

360浏览器假死的解决方法

1.造成360浏览器假死的情况一般是兼容性的问题.解决方法就是先将360浏览器的进程在任务管理器上结束掉.因为假死可能直接关闭360会卡死的情况,所有在任务管理器上找到360se.exe进程将其结束即可.如图所示: 2.然后可以在网上下载一些清理软件,比如360安全卫士,然后对电脑系统清除一些垃圾文件,打开360安全卫士,点击[一键清理]即可完成操作了.只需要一键就清除了哦.如图所示: 3.上面将360进程结束之后,然后再将360浏览器卸载掉,重新在官方下载最新版本的360浏览器.可能在兼容性方

Sring mvc +mybatis部署tomcat导致tomcat启动假死

问题描述 Sring mvc +mybatis部署tomcat导致tomcat启动假死 mybatis如果出现如下错误会导致tomcat假死并且等待很长时间才报错,错误信息不准确,导致tomcat栈溢出,修改了tomcat内存参数之后,错误原因可以看出来,但是tomcat终端一直报错,停不下来,求解Spring公共配置 <!-- 使用annotation 自动注册bean, 并保证@Required.@Autowired的属性被注入 --> <context:component-scan

IE浏览器假死问题的解决办法

1)首先排除病毒因素 如果电脑经常会出现IE假死的情况,首先我们进行的是对电脑进行全盘扫描,排除病毒破坏干扰. 2)升级IE浏览器 排除病毒干扰后,我们再来介绍下其他的解决办法,如果我们安装的浏览器版本过低,比如是IE6浏览器,可能会导致一些网页的兼容问题,建议大家升级到IE8浏览器试试,以前也遇到过IE浏览器经常会卡死的情况,但是升级浏览器版本后明显好多了. 3)清理一些垃圾IE插件 如今很多软件安装都会默认安装一些垃圾插件,这对浏览器稳定性容易造成破坏,解决办法是清理一些不常用的IE插件,清

Win8自带IE10浏览器假死

自微软上周发布Win8以来,不少网友都将自己的系统升级到Win8,虽然Win8在正式发布前经历无数次的测试,但百密终有一疏,网友们总是能发现各种各样的小问题. 近日就有网友称,Win8系统自带的IE10浏览器经常出现问题,就像是假死一样地,偶尔无响应,或者是打开网页或者进行任何操作都奇慢无比.当时没有太在意,因为用的是一台旧电脑,性能不怎么样,以为是偶发的正常的性能问题.可是,随着最近在网上看视频的次数越来越多(最近Win8.Surface都发布了嘛,好多视频呢~),发现这个问题越来越突出,越来

FusionCharts Free 导致的页面假死

问题描述 在IE8下测试,使用FusionChartsFree的页面加载时会有很明显的假死现象(就是卡主不动),求哪位有大神路过帮下忙 解决方案 解决方案二:...如果这个BUG解决不了年都不好过啊求大神指路

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

事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则,我封装了一个名为getData的函数,它接收不同参数,只负责获取数据,然后把数据return.基本的逻辑剥离出来是这样的:    代码如下 复制代码 function getData1(){        var result;         $.ajax({             url : 'p.php',             async : false,             success: fu