html5 WebWorkers 防止浏览器假死

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

在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出“脚本运行时间过长“的提示框,如果出现这种情况说明你的脚本已经失控了。

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

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

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

     3:事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待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等。多个线程间也是可以通过相同的方法进行数据传递。

     直接看代码:

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

     以前的做法:

复制代码
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webworkers--calculate</title>
</head>
<body>
<input id="num" name="num" type="text"/>
<button onclick = "calculate()">计算</button><br />
<div id="result" style="color:red;"></div>
<div id="time" style="color:red;"></div>
<script type="text/javascript" src="calculate.js"></script>
<script type="text/javascript">
function calculate(){
data1 = new Date().getTime();
var num = document.getElementById("num").value;
var val = parseInt(num,10);
var result =0;
for(var i =0; i<num;i++){
result += i;
}
data2 = new Date().getTime();
document.getElementById("result").innerHTML ="计算结果:"+result;
document.getElementById("time").innerHTML ="普通 耗时:"+ (data2 - data1)+"ms";
}
</script>
</body>
</html>
复制代码


    使用webWorkers以后:

    calculate.html

复制代码
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webworkers--calculate</title>
</head>
<body>
<input id="num" name="num" type="text"/>
<button onclick = "calculate()">计算</button><br />
<div id="result" style="color:red;"></div>
<div id="time" style="color:red;"></div>
<script type="text/javascript" src="calculate.js"></script>
<script type="text/javascript">
var worker = new Worker("calculate.js");
var data1 =0;
var data2 =0;
worker.onmessage = function(event){
var data = event.data;
data2 = new Date().getTime();
document.getElementById("result").innerHTML ="计算结果:"+data;
document.getElementById("time").innerHTML ="workers 耗时:"+ (data2 - data1)+"ms";
};
function calculate(){
data1 = new Date().getTime();
var num = document.getElementById("num").value;
var val = parseInt(num,10);
worker.postMessage(val);
}
</script>
</body>
</html>
复制代码

      calculate.js

复制代码
onmessage = function(event){
var num = event.data;
var result = 0;
for(var i = 0; i<num;i++){
result += i;
}
postMessage(result);
};
复制代码

     webWorker需要将代码放入web服务器中,如果使用的是localhost请用高版本的chrome浏览器打开,firefox浏览器在处理localhost的时候会出现“Could not get domain!”的错误,关于这个可以参考:https://bugzilla.mozilla.org/show_bug.cgi?id=682450

   

     对比上面的两种实现方式,当计算值达到100亿的时候,普通做法耗时已经很长,且一般会卡死了。

     

         webWorkers在Chrome15下的效果。 更正:getTime()返回的应该是毫秒(ms),而不是秒(s)。

          普通方法在Chrome15下的效果

 

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

目录
相关文章
|
Web App开发 移动开发 JavaScript
|
9天前
|
移动开发 前端开发 JavaScript
[HTML、CSS]细节与使用经验
本文总结了前端开发中的一些重要细节和技巧,包括CSS选择器、定位、层级、全局属性、滚轮控制、轮播等。作者以纯文字形式记录,便于读者使用<kbd>Ctrl + F</kbd>快速查找相关内容。文章还提供了示例代码,帮助读者更好地理解和应用这些知识点。
31 1
[HTML、CSS]细节与使用经验
|
10天前
|
移动开发 前端开发 JavaScript
[HTML、CSS]知识点
本文涵盖前端知识点扩展、HTML标签(如video、input、canvas)、datalist和details标签的使用方法,以及CSS布局技巧(如margin、overflow: hidden和动态height)。文章旨在分享作者的学习经验和实用技巧。
24 1
[HTML、CSS]知识点
|
1月前
|
前端开发 JavaScript 搜索推荐
打造个人博客网站:从零开始的HTML和CSS之旅
【9月更文挑战第32天】在这个数字化的时代,拥有一个个人博客不仅是展示自我的平台,也是技术交流的桥梁。本文将引导初学者理解并实现一个简单的个人博客网站的搭建,涵盖HTML的基础结构、CSS样式的美化技巧以及如何将两者结合来制作一个完整的网页。通过这篇文章,你将学会如何从零开始构建自己的网络空间,并在互联网世界留下你的足迹。
|
5天前
|
移动开发 JavaScript 前端开发
html table+css实现可编辑表格的示例代码
html table+css实现可编辑表格的示例代码
|
2天前
|
前端开发 JavaScript
用HTML CSS JS打造企业级官网 —— 源码直接可用
必看!用HTML+CSS+JS打造企业级官网-源码直接可用,文章代码仅用于学习,禁止用于商业
20 1
|
7天前
|
前端开发 JavaScript 安全
HTML+CSS+JS密码灯登录表单
通过结合使用HTML、CSS和JavaScript,我们创建了一个带有密码强度指示器的登录表单。这不仅提高了用户体验,还帮助用户创建更安全的密码。希望本文的详细介绍和代码示例能帮助您在实际项目中实现类似功能,提升网站的安全性和用户友好性。
16 3
|
17天前
|
JSON 移动开发 数据格式
html5+css3+js移动端带歌词音乐播放器代码
音乐播放器特效是一款html5+css3+js制作的手机移动端音乐播放器代码,带歌词显示。包括支持单曲循环,歌词显示,歌曲搜索,音量控制,列表循环等功能。利用json获取音乐歌单和歌词,基于html5 audio属性手机音乐播放器代码。
66 6
|
16天前
|
前端开发
HTML 样式- CSS3
内部样式表适用于单个文件的特别样式,通过&lt;head&gt;部分的&lt;style&gt;标签定义;外部样式表适用于多个页面,通过&lt;link&gt;标签引用外部CSS文件;&lt;style&gt;定义样式,&lt;link&gt;引用资源;已弃用的标签有&lt;font&gt;、&lt;center&gt;、&lt;strike&gt;,属性有color和bgcolor。

热门文章

最新文章