皇上,还记得我吗?我就是1999年那个Linux伊甸园啊-----24小时滚动更新开源资讯,全年无休!

前端高性能计算之一:WebWorkers

最近做一个项目,里面涉及到在前端做大量计算,直接用 js 跑了一下,大概需要 15s 的时间, 也就是用户的浏览器会卡死 15s,这个完全接受不了。

虽说有 V8 这样牛逼的引擎,但大家知道 js 并不适合做 CPU 密集型的计算,一是因为单线程,二是因为动态语言。我们就从这两个突破口入手,首先搞定“单线程”的限制,尝试用 WebWorkers 来加速计算。

什么是 WebWorkers

简单说,WebWorkers 是一个 HTML5 的新 API,web 开发者可以通过此 API 在后台运行一个脚本而不阻塞 UI,可以用来做需要大量计算的事情,充分利用 CPU 多核。

大家可以看看这篇文章介绍 https://www.html5rocks.com/en/tutorials/workers/basics/,  或者 对应的中文版

The Web Workers specification defines an API for spawning background scripts in your web application. Web Workers allow you to do things like fire up long-running scripts to handle computationally intensive tasks, but without blocking the UI or other scripts to handle user interactions.

可以打开 这个链接 自己体验一下 WebWorkers 的加速效果。

现在浏览器基本都 支持 WebWorkers 了caniuse-webworkers

Parallel.js

直接使用 WebWorkers 接口还是太繁琐,好在有人已经对此作了封装:Parallel.js

注意 Parallel.js 可以通过 node 安装:

不过这个是在 node.js 下用的,用的 node 的 cluster 模块。如果要在浏览器里使用的话, 需要直接应用 js:

然后可以得到一个全局变量,ParallelParallel 提供了 mapreduce 两个函数式编程的接口,可以非常方便的进行并发操作。

我们先来定义一下我们的问题,由于业务比较复杂,我这里把问题简化成求 1-1,0000,0000 的和,然后在依次减去 1-1,0000,0000,答案显而易见: 0! 这样做是因为数字太大的话会有数据精度的问题,两种方法的结果会有一些差异,会让人觉得并行的方法不可靠。此问题在我的 mac pro chrome61 下直接简单地跑 js 运行的话大概是 1.5s(我们实际业务问题需要 15s,这里为了避免用户测试的时候把浏览器搞死,我们简化了问题)。

代码比较简单,我这里说几个刚用的时候遇到的坑。

  • require 所有需要的函数

比如在上诉代码中用到了 sum,你需要提前 require(sum),如果 sum 中由用到了另一个函数 f,你还需要 require(f),同样如果 f 中用到了 g,则还需要 require(g),直到你 require 了所有用到的定义的函数。。。。

  • 没法 require 变量

我们上诉代码我本来定义了 N1,但是没法用

  • ES6 编译成 ES5 之后的问题以及 Chrome 没报错

实际项目中一开始我们用到了 ES6 的特性:数组解构 。本来这是很简单的特性,现在大部分浏览器都已经支持了,不过我当时配置的 babel 会编译成 ES5,所以会生成代码 _slicedToArray,大家可以 在线上 Babel 测试 ,然后 Chrome 下面始终不 work,也没有任何报错信息,查了很久,后来在 Firefox 下打开,有报错信息:

看来 Chrome 也不是万能的啊。。。

大家可以在 此 Demo 页面 测试, 提速大概在 4 倍左右,当然还是得看自己电脑 CPU 的核数。 另外我后来在同样的电脑上 Firefox55.0.3(64 位)测试,上诉代码居然只要 190ms!!!在 Safari9.1.1 下也是 190ms 左右。。。

Refers

转自 http://web.jobbole.com/92790/

分享到:更多 ()