现在的位置: 首页 > 综合 > 正文

Chrome浏览器中的JavaScript多线程—WebWorker

2014年09月05日 ⁄ 综合 ⁄ 共 1589字 ⁄ 字号 评论关闭

  浏览器中的JavaScript是单线程执行的,如果遇到重量级的计算任务时,一般需要运行很长时间,这样就会造成UI任务来不及响应,带来不好的用户体验。那么如何在JavaScript中使用多线程来解决这类问题呢?HTML5引入了新的Web Worker API,它让一段JavaScript程序运行在主线程之外的另外一个线程或进程中。Chrome对Web Worker API也有了基本的支持,在Android平台上虽然还存在缺陷,但是不影响基本使用。

先介绍一下Web Worker的基本知识

Web Worker有两种,一种是常见的Dedicated Worker,在JavaScript中简写为Worker,例如:var worker = new Worker(“source/worker.js”); 该例中worker.js就运行在另外一个线程中,无论计算任务有多重都不会直接阻塞主线程中的UI。另外一种是SharedWorker,它在浏览器中只有一个运行实例,允许所有的页面共享使用。关于Web Worker更多的介绍,请参考W3C的API文档http://dev.w3.org/html5/workers/

现在大家可能会问,现在引入了多线程,那如何保证Worker线程和主线程的同步呢?如果Worker线程和主线程同时修改了页面中的某个节点,岂不是会产生脏数据?这个不用担心,因为Worker线程不能直接访问和操作页面中的DOM属性,如果Worker线程需要访问页面中的某个DOM节点,必须通过postMessage API发消息给主线程,主线程在收到消息后获取页面中的某个DOM节点的属性,再通过postMessage的方式回传给Worker线程,这样就避免了上述问题。

下面介绍一下WebWorker在Chrome中的实现

Chrome浏览器使用的是多进程架构,即Browser进程和Render进程,一般情况下,打开一个页面时,浏览器就为其分配一个进程,称为Render进程,Blink(以前的WebKit)就运行在Render进程中,当然了JavaScript也就运行该进程中,我们称WebKit和JS运行的线程为渲染线程。

Worker(Dedicated Worker)只属于某个页面,不会和其他页面的Render进程共享,所以Chrome在Render进程中创建一个新的线程来运行Worker中的JavaScript程序。

  对于SharedWorker来说,情况就发生了变化,由于SharedWorker是浏览器所有页面共享的,不能采用与Worker同样的方式实现,因为它不隶属于某个Render进程,可以为多个Render进程共享使用,所以Chrome浏览器为SharedWorker单独创建一个进程来运行JavaScript程序,在浏览器中每个相同的JavaScript只存在一个SharedWorker进程,不管它被创建多少次。

由于Chrome需要为SharedWorker创建新的进程,在Android平台上就会存在一些困难,因为Android毕竟是嵌入式平台,Android Chrome对创建的进程所做了限定,假设限定9个进程,如果进程总数达到了9,就意味着用户不能再打开新的标签页了。如果浏览器创建了太多的SharedWorker进程,那么用户或许根本连第二个标签页都打不开了。另外SharedWorker的优先级该如何确定,比前台的标签页优先级小?或者比后台的标签页优先级大?如果访问SharedWorker的标签页都在后台,优先级会变成怎样?如果访问SharedWorker的某个标签页在前台,其优先级又该如何设定?这些因素足以说明Android平台的特殊性,所以据写文章为止,在Android平台上SharedWorker仍然处在讨论阶段,Chrome
M30不支持该API。

抱歉!评论已关闭.