问题

   前几天,同事遇到一个浏览器假死的问题。就是浏览器在响应一个请求的时候,就突然不响应时间,进入假死状态,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 导致的浏览器假死的更多相关文章

  1. async:false同步请求,浏览器假死

    // 异步请求导致数据错乱 // function get_num(){ // $("input[name='monitor']").eq(1).attr('checked',tr ...

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

    在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出“脚本运行时间过长“的提示框,如果出现这种情况说明你的脚本已经失控了,必须进行优化. 为什么会出现这种情况呢,我们先来看一下浏览器的内 ...

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

    在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出"脚本运行时间过长"的提示框,如果出现这种情况说明你的脚本已经失控了,必须进行优化. 为什么会出现这种情况呢,我们 ...

  4. java线程基础巩固---多Product多Consumer之间的通讯导致出现程序假死的原因分析

    在上一次中已经实现一个生产者与消费者的初步模型(http://www.cnblogs.com/webor2006/p/8413286.html),但是当时只是一个生产者对应一个消费者,先贴下代码: p ...

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

    俗话说不作死就不会死,今天作死了一回,写了一个比较二逼的函数,遇到了同步Ajax引起的UI线程阻塞问题,在此记录一下.   事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的 ...

  6. jQuery Ajax async=>false异步改为同步时,导致浏览器假死的处理方法

    今天做一个需求遇到了这么个情况,就是用户个人中心有个功能,点击按钮,可以刷新用户当前的积分,这个肯定需要使用到ajax的同步请求了,当时喀喀喀三下五除二写玩了,大概代码如下: /** * 异步当前用户 ...

  7. html5 WebWorkers 防止浏览器假死

    在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出“脚本运行时间过长“的提示框,如果出现这种情况说明你的脚本已经失控了. 一个浏览器至少存在三个线程:js引擎线程(处理js).GUI渲 ...

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

    一.问题的起因 今天做一个需求遇到了这么个情况,就是用户个人中心有个功能,点击按钮,可以刷新用户当前的积分,这个肯定需要使用到ajax的同步请求了,当时喀喀喀三下五除二写玩了,大概代码如下: /** ...

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

    平时使用AjaxPro的时候基本上非常easy var msg = UseClass.Method(argument).value; 由于后台响应比較慢,所以加了个"loading" ...

随机推荐

  1. MyBatis_ibatis和mybatis的区别【转】

    1. ibatis3.*版本以后正式改名为mybaits,它也从apache转到了google code下:也就是说ibatis2.*,mybatis3.*. 2. 映射文件的不同 ibatis的配置 ...

  2. Region的周长, 面积与紧凑程度

    Perimeter 边界长度. 计算方式跟边界的表示方式有关 Area 包含的点的个数 Compactness 两种常用的计算方式 \(\frac {perimeter^2}{area}\). cir ...

  3. C#-WinForm-进程、线程

    进程:一个程序就是一个进程,也有可能一个程序需要多个进程来支持的情况,比如QQ 点击按钮打开记事本,静态方法 public partial class Form3 : Form { public Fo ...

  4. mac下搭建java开发环境:eclipse+tomcat+maven

    一.安装eclipse 直接下载 二.安装JDK 下载mac版专用的jdk1.7,地址如下:http://jdk7.java.net/macportpreview/, 确认java使用的版本:开一个终 ...

  5. 「c++小学期」实验题目及代码

    面向对象编程的C++,和平时做题用的C++还是有差距的.实验的题目都是小题目,就都做一下吧.(没放代码的为要验收的 实验一 简单C++程序设计 1.  猜价格游戏 编写C++程序完成以下功能: (1) ...

  6. C语言与套接字

    我们已经知道如何使用I/O与文件通信,还知道了如何让同一计算机上的两个进程进行通信,这篇文章将创建具有服务器和客户端功能的程序 互联网中大部分的底层网络代码都是用C语言写的. 网络程序通常有两部分组成 ...

  7. 使用Oracle的审计功能记录连接数据库登录失败的用户信息

    最近公司有一个项目,用的oracle数据库,整天出现用户被锁的情况,后来百度查了一下,说是用户登录连续出错10次就会被锁住.于是想记录一下看看到底是哪个人在扫数据库的密码.百度了很久才找到方法,下面分 ...

  8. [poj2446]Chessboard

    Description 给定一个m×n的棋盘,上面有k个洞,求是否能在不重复覆盖且不覆盖到洞的情况下,用2×1的卡片完全覆盖棋盘. Input 第一行有三个整数n,m,k(0<m,n<=3 ...

  9. Leetcode 376. Wiggle Subsequence

    本题要求在O(n)时间内求解.用delta储存相邻两个数的差,如果相邻的两个delta不同负号,那么说明子序列摇摆了一次.参看下图的nums的plot.这个例子的答案是7.平的线段部分我们支取最左边的 ...

  10. Leetcode 226. Invert Binary Tree

    Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 class Solution(object): ...