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

一个浏览器至少存在三个线程:js引擎线程(处理js)、GUI渲染线程(渲染页面)、浏览器事件触发线程(控制交互)。

JavaScript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来然后加以处理,浏览器无论再什么时候都只有一个JS线程在运行JS程序。

GUI 渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。

事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。

了解了浏览器的内核处理方式就不难理解浏览器为什么会进入假死状态了,当一段JS脚本长时间占用着处理机就会挂起浏览器的GUI更新,而后面的事件响应 也被排在队列中得不到处理,从而造成了浏览器被锁定进入假死状态。另外JS脚本中进行了DOM操作,一旦JS调用结束就会马上进行一次GUI渲染,然后才 开始执行下一个任务,所以JS中大量的DOM操作也会导致事件响应缓慢甚至真正卡死浏览器,如在IE6下一次插入大量的HTML。而如果真的弹出了“脚本 运行时间过长“的提示框则说明你的JS脚本肯定有死循环或者进行过深的递归操作了。

现在如果遇到了这种情况,我们可以做的不仅仅是优化 代码,html5的webWorkers提供了js的后台处理线程的API,它允许将复杂耗时的单纯js逻辑处理放在浏览器后台线程中进行处理,让js线 程不阻塞UI线程的渲染。这个线程不能和页面进行交互,如获取元素、alert等。多个线程间也是可以通过相同的方法进行数据传递。

直接看代码:

例子:用户输入一个数字,进行加法运算(+=)

以前的做法:


  1. <!DOCTYPE HTML> 
  2. <html lang="en"> 
  3. <head> 
  4.     <meta charset="UTF-8"> 
  5.     <title>webworkers--calculate</title></head> 
  6. <body> 
  7.     <input id="num" name="num" type="text"/> 
  8.     <button onclick = "calculate()">计算</button><br /> 
  9.     <div id="result" style="color:red;"></div> 
  10.     <div id="time" style="color:red;"></div> 
  11.     <script type="text/javascript" src="calculate.js"></script> 
  12.     <script type="text/javascript">        function calculate(){  
  13.             data1 = new Date().getTime();  
  14.             var num = document.getElementById("num").value;  
  15.             var val = parseInt(num,10);  
  16.             var result =0;  
  17.             for(var i =0; i<num;i++){  
  18.                 result += i;  
  19.             }  
  20.             data2 = new Date().getTime();  
  21.             document.getElementById("result").innerHTML ="计算结果:"+result;  
  22.             document.getElementById("time").innerHTML ="普通 耗时:"+ (data2 - data1)+"ms";  
  23.         }  
  24.     </script> 
  25. </body> 
  26. </html> 

使用webWorkers以后:

calculate.html


  1. <!DOCTYPE HTML> 
  2. <html lang="en"><head> 
  3.     <meta charset="UTF-8"> 
  4.     <title>webworkers--calculate</title> 
  5. </head> 
  6. <body> 
  7.     <input id="num" name="num" type="text"/> 
  8.     <button onclick = "calculate()">计算</button><br /> 
  9.     <div id="result" style="color:red;"></div> 
  10.     <div id="time" style="color:red;"></div> 
  11.     <script type="text/javascript" src="calculate.js"></script> 
  12.     <script type="text/javascript"> 
  13.         var worker = new Worker("calculate.js");  
  14.         var data1 =0;  
  15.         var data2 =0;  
  16.         worker.onmessage = function(event){  
  17.                 var data = event.data;  
  18.                 data2 = new Date().getTime();  
  19.                 document.getElementById("result").innerHTML ="计算结果:"+data;  
  20.                 document.getElementById("time").innerHTML ="workers 耗时:"+ (data2 - data1)+"ms";  
  21.             };  
  22.          function calculate(){  
  23.             data1 = new Date().getTime();  
  24.             var num = document.getElementById("num").value;   
  25.            var val = parseInt(num,10);  
  26.             worker.postMessage(val);  
  27.         }  
  28.     </script> 
  29. </body> 
  30. </html> 

calculate.js


  1. onmessage = function(event){  
  2.     var num = event.data;  
  3.     var result = 0;  
  4.     for(var i = 0; i<num;i++){  
  5.         result += i;  
  6.     }  
  7.     postMessage(result);  
  8. }; 

webWorker需要将代码放入web服务器中, 如果使用的是localhost请用高版本的chrome浏览器打开,firefox浏览器在处理localhost的时候会出现“Could not get domain!”的错误,关于这个可以参考:https://bugzilla.mozilla.org/show_bug.cgi?id=682450 对比上面的两种实现方式,当计算值达到100亿的时候,普通做法耗时已经很长,且一般会卡死了。

开发:防止浏览器假死的方法-html5">
webWorkers在Chrome15下的效果

更正:getTime()返回的应该是毫秒(ms),而不是秒(s)。

如下图所示:


普通方法在Chrome15下的效果

可见webWorkers在未来的web应用中还是非常有价值的。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索线程
, 浏览器
, 队列
, 事件
, 引擎
, js事件
, js浏览器
, html js 事件
, 处理
, js处理
, js事件处理程序
, js处理大量数据
, JS操作符
JS引擎
html5、html5教程、html5开发工具、html、html5是什么,以便于您获取更多的相关知识。

时间: 2024-11-30 15:56:03

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

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

在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出"脚本运行时间过长"的提示框,如果出现这种情况说明你的脚本已经失控了. 一个浏览器至少存在三个线程:js引擎线程(处理js).GUI渲染线程(渲染页面).浏览器事件触发线程(控制交互). JavaScript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来然后加以处理,浏览器无论再什么时候都只有一个JS线程在运行JS程序. GUI 渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某

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浏览器.可能在兼容性方

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

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

setTimeout 导致的浏览器假死

 问题   前几天,同事遇到一个浏览器假死的问题.就是浏览器在响应一个请求的时候,就突然不响应时间,进入假死状态,Cup也飙升到100%. 但是这个问题只出现在IE浏览器,chrome和Firefox等其他浏览器正常. 原因 Js 代码里面,看着也没有什么耗时的操作和后台异步调用.没办法,只能从响应事件的最开始一步一步调查.经过一番调试之后,问题定位在setTimeout 函数.当把setTimeout 里面执行的函数去掉之后,立马就不会出现这种情况.查看setTimeout 里面调用的函数,发

ajax同步页面假死解决方法

问题描述 ajax同步页面假死解决方法 $.when(AreaBWSet(urlStr,jsonSetting,settingType)).then(successFunc,failureFunc); 这段代码总是进不到then里,求大神指教. //向服务器端同步发送请求数据 function AreaBWSet(urlStr,jsonSetting,settingType) { var defer = $.Deferred(); $.ajax({ type: "POST", url:

Win8自带IE10浏览器假死

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

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

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

ie8浏览器打开没有响应,假死解决方法

2003系统IE8.0 浏览器经常出现问题.假死崩溃,建议换浏览器就不要回答了,这个系统很多浏览器不支持的 图 解决方法: 一.将安全等级设置到最低的 中 二.管理加载项 中把不重要的加载全部禁止掉 三.可以到→工具"-→Internet选项"-→高级"选项卡,找到→重置"选项,把浏览器重置一遍,不行就重新安装一次浏览器. 建议采用以下方法: 1.彻底清楚浏览器缓存(使用CCleaner)以及注册表冗余. 2.毛豆防火墙或者D+设置将安装的插件添加为信任(具体方法为