├── .bowerrc ├── .editorconfig ├── .gitignore ├── .jshintrc ├── LICENSE ├── README.md ├── app ├── components │ ├── d3 │ │ ├── .bower.json │ │ ├── .gitattributes │ │ ├── CONTRIBUTING.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── bower.json │ │ ├── d3.js │ │ ├── d3.min.js │ │ └── package.js │ ├── font-fit │ │ ├── .bower.json │ │ ├── bower.json │ │ └── font-fit.js │ ├── fxos-mvc │ │ ├── .bower.json │ │ ├── bower.json │ │ ├── gulpfile.js │ │ └── mvc.js │ ├── gaia-component │ │ ├── .bower.json │ │ ├── bower.json │ │ └── gaia-component.js │ ├── gaia-fonts │ │ ├── .bower.json │ │ ├── bower.json │ │ ├── fonts │ │ │ ├── FiraSans-Bold.woff │ │ │ ├── FiraSans-BoldItalic.woff │ │ │ ├── FiraSans-Light.woff │ │ │ ├── FiraSans-LightItalic.woff │ │ │ ├── FiraSans-Medium.woff │ │ │ ├── FiraSans-MediumItalic.woff │ │ │ ├── FiraSans-Regular.woff │ │ │ └── FiraSans-RegularItalic.woff │ │ └── style.css │ ├── gaia-header │ │ ├── .bower.json │ │ ├── .jshintrc │ │ ├── bower.json │ │ ├── dist │ │ │ └── gaia-header.js │ │ └── gaia-header.js │ ├── gaia-icons │ │ ├── .bower.json │ │ ├── .jshintrc │ │ ├── bin │ │ │ └── report.js │ │ ├── bower.json │ │ ├── fonts │ │ │ └── gaia-icons.ttf │ │ ├── gaia-icons-embedded.css │ │ ├── gaia-icons.css │ │ └── gaia-icons.js │ ├── node-isnumber │ │ ├── .bower.json │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── index.js │ │ ├── package.json │ │ └── test │ │ │ └── index.js │ ├── node-stats-lite │ │ ├── .bower.json │ │ ├── .gitignore │ │ ├── .npmignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── examples │ │ │ └── dice.js │ │ ├── package.json │ │ ├── stats.js │ │ └── test │ │ │ └── index.js │ ├── regression-js │ │ ├── .bower.json │ │ ├── .gitignore │ │ ├── .npmignore │ │ ├── Gruntfile.js │ │ ├── bower.json │ │ ├── build │ │ │ └── regression.min.js │ │ ├── index.js │ │ ├── package.json │ │ ├── readme.md │ │ └── src │ │ │ └── regression.js │ └── threads │ │ ├── .bower.json │ │ ├── LICENSE │ │ ├── README.md │ │ ├── bower.json │ │ ├── index.js │ │ ├── lib │ │ ├── child-thread.js │ │ ├── client │ │ │ ├── index.js │ │ │ └── stream.js │ │ ├── emitter.js │ │ ├── manager.js │ │ ├── messenger.js │ │ ├── service │ │ │ ├── index.js │ │ │ └── stream.js │ │ ├── thread-global.js │ │ └── utils.js │ │ ├── package.json │ │ ├── threads.js │ │ └── threads.min.js ├── css │ └── app.css ├── img │ ├── creation-barchart.svg │ ├── creation-scatter-plot.svg │ ├── icon.svg │ ├── icons │ │ ├── 128.png │ │ ├── 16.png │ │ ├── 256.png │ │ ├── 32.png │ │ ├── 48.png │ │ ├── 512.png │ │ ├── 60.png │ │ ├── 64.png │ │ └── 90.png │ ├── latency-barchart.svg │ ├── latency-scatter-plot.svg │ ├── transfer-speed-barchart.svg │ └── transfer-speed-scatter-plot.svg ├── index.html ├── js │ ├── app.js │ ├── controllers │ │ ├── creation.js │ │ ├── home.js │ │ ├── latency.js │ │ ├── main.js │ │ └── message.js │ └── views │ │ ├── creation.js │ │ ├── home.js │ │ ├── latency.js │ │ └── message.js ├── manifest.webapp └── workers │ ├── creation-window │ ├── index.html │ └── script.js │ ├── creation-worker.js │ ├── latency-service.js │ ├── latency-shared-worker.js │ ├── latency-worker.js │ ├── message-service.js │ └── message-worker.js ├── bower.json ├── gulpfile.js └── package.json /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/components/" 3 | } 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is installed as part of the build script setup. 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [*.yml] 16 | indent_style = space 17 | indent_size = 2 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | TODO.md 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "devel": false, 4 | "esnext": true, 5 | "expr": false, 6 | "forin": false, 7 | "latedef": "nofunc", 8 | "newcap": true, 9 | "noarg": true, 10 | "nonew": false, 11 | "quotmark": "single", 12 | "undef": true, 13 | "unused": "vars", 14 | "strict": false, 15 | "laxcomma": false, 16 | "maxerr": 1000, 17 | "maxlen": 120, 18 | "proto": true, 19 | "browser": true, 20 | "node": true, 21 | "worker": true 22 | } 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![Web workers benchmark](https://raw.githubusercontent.com/gmarty/web-workers-benchmark/master/app/img/icons/32.png "Web workers benchmark") Web workers benchmark 2 | 3 | > Benchmark various aspects of Web workers. 4 | 5 | ## What? 6 | 7 | A technical, mobile first app to benchmark different aspects related to web workers: 8 | 9 | * Instantiation 10 | * Messaging latency 11 | * Transfer speed 12 | 13 | The following communication methods are used: 14 | 15 | * [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Worker/postMessage) 16 | * [BroadcastChannel](https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel/BroadcastChannel) 17 | * the [threads](https://github.com/gaia-components/threads) library 18 | 19 | ## Results 20 | 21 | Results measured on a Flame. 22 | 23 | ### Creation time 24 | 25 | ![Creation time](https://rawgit.com/gmarty/web-workers-benchmark/master/app/img/creation-barchart.svg) 26 | 27 | ![Creation time scatterplot](https://rawgit.com/gmarty/web-workers-benchmark/master/app/img/creation-scatter-plot.svg) 28 | 29 | ### Latency 30 | 31 | ![Latency](https://rawgit.com/gmarty/web-workers-benchmark/master/app/img/latency-barchart.svg) 32 | 33 | ![Latency scatterplot](https://rawgit.com/gmarty/web-workers-benchmark/master/app/img/latency-scatter-plot.svg) 34 | 35 | ### Transfer speed 36 | 37 | ![Speed transfer](https://rawgit.com/gmarty/web-workers-benchmark/master/app/img/transfer-speed-barchart.svg) 38 | 39 | ![Speed transfer scatterplot](https://rawgit.com/gmarty/web-workers-benchmark/master/app/img/transfer-speed-scatter-plot.svg) 40 | 41 | ## Compatibility 42 | 43 | While this app itself works cross-browser, the thread.js library requires an environment that 44 | supports the Broadcast Channel API (i.e. Firefox only currently). In the future, this may not be the 45 | case. It will then be possible to run this app in other browsers. 46 | -------------------------------------------------------------------------------- /app/components/d3/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d3", 3 | "version": "3.5.5", 4 | "main": "d3.js", 5 | "scripts": [ 6 | "d3.js" 7 | ], 8 | "ignore": [ 9 | ".DS_Store", 10 | ".git", 11 | ".gitignore", 12 | ".npmignore", 13 | ".spmignore", 14 | ".travis.yml", 15 | "Makefile", 16 | "bin", 17 | "component.json", 18 | "composer.json", 19 | "index.js", 20 | "lib", 21 | "node_modules", 22 | "package.json", 23 | "src", 24 | "test" 25 | ], 26 | "homepage": "https://github.com/mbostock/d3", 27 | "_release": "3.5.5", 28 | "_resolution": { 29 | "type": "version", 30 | "tag": "v3.5.5", 31 | "commit": "9628a923cb9df82058a4a2fcc8d415e45b6d5d2f" 32 | }, 33 | "_source": "git://github.com/mbostock/d3.git", 34 | "_target": "~3.5.5", 35 | "_originalSource": "d3" 36 | } -------------------------------------------------------------------------------- /app/components/d3/.gitattributes: -------------------------------------------------------------------------------- 1 | bower.json -diff merge=ours 2 | component.json -diff merge=ours 3 | d3.js -diff merge=ours 4 | d3.min.js -diff merge=ours 5 | package.js -diff merge=ours 6 | -------------------------------------------------------------------------------- /app/components/d3/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | **Important:** these GitHub issues are for *bug reports and feature requests only*. Please use [StackOverflow](http://stackoverflow.com/questions/tagged/d3.js) or the [d3-js Google group](https://groups.google.com/d/forum/d3-js) for general help. 4 | 5 | If you’re looking for ways to contribute, please [peruse open issues](https://github.com/mbostock/d3/issues?milestone=&page=1&state=open). The icebox is a good place to find ideas that are not currently in development. If you already have an idea, please check past issues to see whether your idea or a similar one was previously discussed. 6 | 7 | Before submitting a pull request, consider implementing a live example first, say using [bl.ocks.org](http://bl.ocks.org). Real-world use cases go a long way to demonstrating the usefulness of a proposed feature. The more complex a feature’s implementation, the more usefulness it should provide. Share your demo using the #d3js tag on Twitter or by sending it to the [d3-js Google group](https://groups.google.com/d/forum/d3-js). 8 | 9 | If your proposed feature does not involve changing core functionality, consider submitting it instead as a [D3 plugin](https://github.com/d3/d3-plugins). New core features should be for general use, whereas plugins are suitable for more specialized use cases. When in doubt, it’s easier to start with a plugin before “graduating” to core. 10 | 11 | To contribute new documentation or add examples to the gallery, just [edit the Wiki](https://github.com/mbostock/d3/wiki)! 12 | 13 | ## How to Submit a Pull Request 14 | 15 | 1. Click the “Fork” button to create your personal fork of the D3 repository. 16 | 17 | 2. After cloning your fork of the D3 repository in the terminal, run `npm install` to install D3’s dependencies. 18 | 19 | 3. Create a new branch for your new feature. For example: `git checkout -b my-awesome-feature`. A dedicated branch for your pull request means you can develop multiple features at the same time, and ensures that your pull request is stable even if you later decide to develop an unrelated feature. 20 | 21 | 4. The `d3.js` and `d3.min.js` files are built from source files in the `src` directory. _Do not edit `d3.js` directly._ Instead, edit the source files, and then run `make` to build the generated files. 22 | 23 | 5. Use `make test` to run tests and verify your changes. If you are adding a new feature, you should add new tests! If you are changing existing functionality, make sure the existing tests run, or update them as appropriate. 24 | 25 | 6. Sign D3’s [Individual Contributor License Agreement](https://docs.google.com/forms/d/1CzjdBKtDuA8WeuFJinadx956xLQ4Xriv7-oDvXnZMaI/viewform). Unless you are submitting a trivial patch (such as fixing a typo), this form is needed to verify that you are able to contribute. 26 | 27 | 7. Submit your pull request, and good luck! 28 | -------------------------------------------------------------------------------- /app/components/d3/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2015, Michael Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * The name Michael Bostock may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, 21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 24 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /app/components/d3/README.md: -------------------------------------------------------------------------------- 1 | # Data-Driven Documents 2 | 3 | 4 | 5 | **D3.js** is a JavaScript library for manipulating documents based on data. **D3** helps you bring data to life using HTML, SVG and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation. 6 | 7 | Want to learn more? [See the wiki.](https://github.com/mbostock/d3/wiki) 8 | 9 | For examples, [see the gallery](https://github.com/mbostock/d3/wiki/Gallery) and [mbostock’s bl.ocks](http://bl.ocks.org/mbostock). 10 | -------------------------------------------------------------------------------- /app/components/d3/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "d3", 3 | "version": "3.5.5", 4 | "main": "d3.js", 5 | "scripts": [ 6 | "d3.js" 7 | ], 8 | "ignore": [ 9 | ".DS_Store", 10 | ".git", 11 | ".gitignore", 12 | ".npmignore", 13 | ".spmignore", 14 | ".travis.yml", 15 | "Makefile", 16 | "bin", 17 | "component.json", 18 | "composer.json", 19 | "index.js", 20 | "lib", 21 | "node_modules", 22 | "package.json", 23 | "src", 24 | "test" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /app/components/d3/package.js: -------------------------------------------------------------------------------- 1 | // Package metadata for Meteor.js. 2 | 3 | Package.describe({ 4 | name: "d3js:d3", // http://atmospherejs.com/d3js/d3 5 | summary: "D3 (official): A JavaScript visualization library for HTML and SVG.", 6 | version: "3.5.5", 7 | git: "https://github.com/mbostock/d3.git" 8 | }); 9 | 10 | Package.onUse(function(api) { 11 | api.versionsFrom(["METEOR@1.0"]); 12 | api.addFiles("d3.js", "client"); 13 | }); 14 | -------------------------------------------------------------------------------- /app/components/font-fit/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "font-fit", 3 | "main": "font-fit.js", 4 | "version": "0.3.1", 5 | "authors": [ 6 | "Wilson Page " 7 | ], 8 | "license": "MIT", 9 | "ignore": [ 10 | "**/.*", 11 | "node_modules", 12 | "bower_components", 13 | "test", 14 | "README.md", 15 | "index.html", 16 | "package.json" 17 | ], 18 | "homepage": "https://github.com/gaia-components/font-fit", 19 | "_release": "0.3.1", 20 | "_resolution": { 21 | "type": "version", 22 | "tag": "v0.3.1", 23 | "commit": "07a497519b335a3d86a66268f990d8844b83d517" 24 | }, 25 | "_source": "git://github.com/gaia-components/font-fit.git", 26 | "_target": "~0.3.0", 27 | "_originalSource": "gaia-components/font-fit" 28 | } -------------------------------------------------------------------------------- /app/components/font-fit/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "font-fit", 3 | "main": "font-fit.js", 4 | "version": "0.3.1", 5 | "authors": [ 6 | "Wilson Page " 7 | ], 8 | "license": "MIT", 9 | "ignore": [ 10 | "**/.*", 11 | "node_modules", 12 | "bower_components", 13 | "test", 14 | "README.md", 15 | "index.html", 16 | "package.json" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /app/components/font-fit/font-fit.js: -------------------------------------------------------------------------------- 1 | ;(function(define){define(function(require,exports,module){ 2 | 'use strict'; 3 | 4 | /** 5 | * Simple logger. 6 | * 7 | * @return {Function} 8 | */ 9 | var debug = 0 ? console.log.bind(console) : function(){}; 10 | 11 | /** 12 | * Global canvas cache. 13 | * 14 | * @type {Object} 15 | */ 16 | var cache = {}; 17 | 18 | /** 19 | * Default min/max font-size. 20 | * 21 | * @type {Number} 22 | */ 23 | var MIN = 16; 24 | var MAX = 24; 25 | 26 | /** 27 | * The number of pixels to subtract from 28 | * the given `config.space` to ensure 29 | * HTML text doesn't overflow container. 30 | * 31 | * Ideally we would use 1px, but in some 32 | * cases italicised text in canvas is ~2px 33 | * longer than the same text in HTML. 34 | * 35 | * http://bugzil.la/1126391 36 | * 37 | * @type {Number} 38 | */ 39 | var BUFFER = 3; 40 | 41 | /** 42 | * Get the font-size that closest fits 43 | * the given space with the given font. 44 | * 45 | * Config: 46 | * 47 | * - {String} `text` The text string 48 | * - {String} `font` Font shorthand string 49 | * - {Number} `space` Width (px) to fit the text into 50 | * - {Number} `min` Min font-size (px) (optional) 51 | * - {Number} `max` Max font-size (px) (optional) 52 | * 53 | * @param {Object} config 54 | * @return {Object} {fontSize,overflowing,textWidth} 55 | */ 56 | module.exports = function(config) { 57 | debug('font fit', config); 58 | var space = config.space - BUFFER; 59 | var min = config.min || MIN; 60 | var max = config.max || MAX; 61 | var text = trim(config.text); 62 | var fontSize = max; 63 | var textWidth; 64 | var font; 65 | 66 | do { 67 | font = config.font.replace(/\d+px/, fontSize + 'px'); 68 | textWidth = getTextWidth(text, font); 69 | } while (textWidth > space && fontSize !== min && fontSize--); 70 | 71 | return { 72 | textWidth: textWidth, 73 | fontSize: fontSize, 74 | overflowing: textWidth > space 75 | }; 76 | }; 77 | 78 | /** 79 | * Get the width of the given text 80 | * with the given font style. 81 | * 82 | * @param {String} text 83 | * @param {String} font (CSS shorthand) 84 | * @return {Number} (px) 85 | */ 86 | function getTextWidth(text, font) { 87 | var ctx = getCanvasContext(font); 88 | var width = ctx.measureText(text).width; 89 | debug('got text width', width); 90 | return width; 91 | } 92 | 93 | /** 94 | * Get a canvas context configured 95 | * to the given font style. 96 | * 97 | * @param {String} font 98 | * @return {CanvasRenderingContext2D} 99 | */ 100 | function getCanvasContext(font) { 101 | debug('get canvas context', font); 102 | 103 | var cached = cache[font]; 104 | if (cached) { return cached; } 105 | 106 | var canvas = document.createElement('canvas'); 107 | canvas.setAttribute('moz-opaque', 'true'); 108 | canvas.setAttribute('width', '1px'); 109 | canvas.setAttribute('height', '1px'); 110 | debug('created canvas', canvas); 111 | 112 | var ctx = canvas.getContext('2d', { willReadFrequently: true }); 113 | ctx.font = font; 114 | 115 | return cache[font] = ctx; 116 | } 117 | 118 | /** 119 | * Trim leading, trailing 120 | * and excess whitespace. 121 | * 122 | * @param {String} text 123 | * @return {String} 124 | */ 125 | function trim(text) { 126 | return text.replace(/\s+/g, ' ').trim(); 127 | } 128 | 129 | });})(typeof define=='function'&&define.amd?define 130 | :(function(n,w){'use strict';return typeof module=='object'?function(c){ 131 | c(require,exports,module);}:function(c){var m={exports:{}};c(function(n){ 132 | return w[n];},m.exports,m);w[n]=m.exports;};})('font-fit',this)); 133 | -------------------------------------------------------------------------------- /app/components/fxos-mvc/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fxos-mvc", 3 | "version": "0.0.5", 4 | "homepage": "https://github.com/fxos/mvc", 5 | "license": "MPL", 6 | "main": "mvc.js", 7 | "ignore": [ 8 | "**/.*", 9 | "example", 10 | "node_modules", 11 | "package.json", 12 | "README.md", 13 | "test" 14 | ], 15 | "_release": "0.0.5", 16 | "_resolution": { 17 | "type": "version", 18 | "tag": "v0.0.5", 19 | "commit": "4f9ed9c5f9ad591730548afd82d5d1f34c70c0c3" 20 | }, 21 | "_source": "git@github.com:fxos/mvc.git", 22 | "_target": "*", 23 | "_originalSource": "git@github.com:fxos/mvc.git" 24 | } -------------------------------------------------------------------------------- /app/components/fxos-mvc/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fxos-mvc", 3 | "version": "0.0.5", 4 | "homepage": "https://github.com/fxos/mvc", 5 | "license": "MPL", 6 | "main": "mvc.js", 7 | "ignore": [ 8 | "**/.*", 9 | "example", 10 | "node_modules", 11 | "package.json", 12 | "README.md", 13 | "test" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /app/components/fxos-mvc/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var merge = require('gulp-merge'); 3 | var concat = require('gulp-concat'); 4 | var to5 = require('gulp-6to5'); 5 | 6 | /** 7 | * converts javascript to es5. 8 | */ 9 | gulp.task('to5', function () { 10 | try { 11 | return merge( 12 | gulp 13 | .src([ 14 | './node_modules/observe-shim/lib/observe-shim.js', 15 | './node_modules/observe-utils/lib/observe-utils.js' 16 | ]) 17 | .pipe(concat('shim.js')), 18 | gulp 19 | .src('./mvc.js') 20 | .pipe(to5({ 21 | modules: 'amd' 22 | }).on('error', function(e) { 23 | console.log('error running 6to5', e); 24 | }) 25 | ) 26 | ) 27 | .pipe(concat('mvc.js')) 28 | .pipe(gulp.dest('./dist/')); 29 | } catch(e) { 30 | console.log('Got error in 6to5', e); 31 | } 32 | }); 33 | 34 | gulp.task('default', ['to5']); 35 | -------------------------------------------------------------------------------- /app/components/fxos-mvc/mvc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Model 3 | */ 4 | export class Model { 5 | constructor(properties) { 6 | properties = properties || {}; 7 | 8 | for (var key in properties) { 9 | this[key] = properties[key]; 10 | } 11 | 12 | this.observableProperties = {}; 13 | 14 | Object.observe(this, (changes) => { 15 | changes.forEach((change) => { 16 | var handlers = this.observableProperties[change.name]; 17 | if (handlers) { 18 | handlers.forEach((handler) => { 19 | handler(change); 20 | }); 21 | } 22 | }); 23 | }); 24 | } 25 | 26 | on(property, handler) { 27 | if (typeof handler !== 'function') { 28 | return; 29 | } 30 | 31 | if (!this.observableProperties[property]) { 32 | ObserveUtils.defineObservableProperties(this, property); 33 | this.observableProperties[property] = []; 34 | } 35 | 36 | this.observableProperties[property].push(handler); 37 | } 38 | } 39 | 40 | /** 41 | * View 42 | */ 43 | var events = {}; 44 | 45 | export class View { 46 | constructor(options) { 47 | options = options || {}; 48 | 49 | for (var key in options) { 50 | this[key] = options[key]; 51 | } 52 | 53 | if (!this.el) { 54 | this.el = document.createElement('div'); 55 | } 56 | } 57 | 58 | /** 59 | * Initializes an instance with the specified controller. 60 | * 61 | * @param {Controller} controller 62 | * @return {View} 63 | */ 64 | init(controller) { 65 | this.controller = controller; 66 | 67 | return this; 68 | } 69 | 70 | /** 71 | * Renders the layout wrapper for the template. 72 | * 73 | * @param {Template} Inner template 74 | * @return {String} Rendered layout with template 75 | */ 76 | layout(template) { 77 | return template; 78 | } 79 | 80 | /** 81 | * Render the default template. 82 | */ 83 | render(params) { 84 | var innerHTML = ''; 85 | 86 | if (params) { 87 | if (typeof params === 'object') { 88 | for (var index in params) { 89 | var param = params[index]; 90 | innerHTML += this.template(param); 91 | } 92 | } else { 93 | for (let i = 0; i < params.length; i++) { 94 | var param = params[i]; 95 | innerHTML += this.template(param); 96 | } 97 | } 98 | } else { 99 | innerHTML = this.template(); 100 | } 101 | 102 | this.el.innerHTML = this.layout(innerHTML); 103 | } 104 | 105 | /** 106 | * Override to provide a function that returns the template string. 107 | * 108 | * @return {String} 109 | */ 110 | template() { 111 | return ''; 112 | } 113 | 114 | /** 115 | * Finds a single child element using the specified selector. 116 | * 117 | * @param {String} query 118 | * @return {Element | null} 119 | */ 120 | $(selector) { 121 | return this.el.querySelector(selector); 122 | } 123 | 124 | /** 125 | * Finds all child elements using the specified selector. 126 | * 127 | * @param {String} query 128 | * @return {NodeList} 129 | */ 130 | $$(selector) { 131 | return this.el.querySelectorAll(selector); 132 | } 133 | 134 | /** 135 | * 136 | * 137 | */ 138 | on(type, selector, handler, scope) { 139 | var controller = this.controller; 140 | scope = scope || this.el; 141 | 142 | if (!events[type]) { 143 | events[type] = []; 144 | window.addEventListener(type, delegateHandler, true); 145 | } 146 | 147 | events[type].push({ 148 | selector: selector, 149 | handler: handler, 150 | controller: controller, 151 | scope: scope 152 | }); 153 | } 154 | 155 | /** 156 | * 157 | * 158 | */ 159 | off(type, selector, handler) { 160 | if (!events[type]) { 161 | return; 162 | } 163 | 164 | events[type] = events[type].filter((delegate) => { 165 | if (typeof handler === 'function') { 166 | return delegate.selector !== selector || 167 | delegate.handler !== handler; 168 | } 169 | 170 | return delegate.selector !== selector; 171 | }); 172 | } 173 | } 174 | 175 | /** 176 | * Forward an event based on the target's `[data-action]` attr to the controller. 177 | * e.g. "click" on a ` 11 | 14 | 17 | `; 18 | 19 | export default class HomeView extends View { 20 | constructor(options) { 21 | this.graph = {}; 22 | 23 | super(options); 24 | } 25 | 26 | init(controller) { 27 | super(controller); 28 | 29 | this.render(); 30 | 31 | this.on('click', 'button', (evt) => { 32 | controller.setActiveController(evt.target.className); 33 | }); 34 | } 35 | 36 | template() { 37 | return template; 38 | } 39 | 40 | setActive(active) { 41 | this.el.classList.toggle('active', active); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/manifest.webapp: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Web workers benchmark", 3 | "short_name": "Workers benchmark", 4 | "version": "0.0.1", 5 | "description": "Benchmark various aspects of Web workers", 6 | "launch_path": "/index.html", 7 | "orientation": "portrait", 8 | "icons": { 9 | "16": "/img/icons/16.png", 10 | "32": "/img/icons/32.png", 11 | "48": "/img/icons/48.png", 12 | "60": "/img/icons/60.png", 13 | "64": "/img/icons/64.png", 14 | "90": "/img/icons/90.png", 15 | "128": "/img/icons/128.png", 16 | "256": "/img/icons/256.png", 17 | "512": "/img/icons/512.png" 18 | }, 19 | "developer": { 20 | "name": "Guillaume Marty", 21 | "url": "http://gu.illau.me/" 22 | }, 23 | "type": "certified" 24 | } 25 | -------------------------------------------------------------------------------- /app/workers/creation-window/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/workers/creation-window/script.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | window.addEventListener('message', function(evt) { 4 | evt.source.postMessage(0, evt.origin); 5 | }); 6 | -------------------------------------------------------------------------------- /app/workers/creation-worker.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BROADCAST_CHANNEL_SUPPORT = 'BroadcastChannel' in self; 4 | var channel = BROADCAST_CHANNEL_SUPPORT ? new BroadcastChannel('creation') : {}; 5 | 6 | onmessage = function() { 7 | postMessage(0); 8 | }; 9 | 10 | channel.onmessage = function() { 11 | channel.postMessage(0); 12 | }; 13 | -------------------------------------------------------------------------------- /app/workers/latency-service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | importScripts('../../components/threads/threads.js'); 4 | 5 | threads.service('latency-service') 6 | .method('ping', function() { 7 | return 0; 8 | }); 9 | -------------------------------------------------------------------------------- /app/workers/latency-shared-worker.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BROADCAST_CHANNEL_SUPPORT = 'BroadcastChannel' in self; 4 | var channel = BROADCAST_CHANNEL_SUPPORT ? new BroadcastChannel('latency') : {}; 5 | 6 | onconnect = function(evt) { 7 | var port = evt.ports[0]; 8 | 9 | port.onmessage = function() { 10 | port.postMessage(0); 11 | }; 12 | 13 | port.start(); 14 | }; 15 | -------------------------------------------------------------------------------- /app/workers/latency-worker.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BROADCAST_CHANNEL_SUPPORT = 'BroadcastChannel' in self; 4 | var channel = BROADCAST_CHANNEL_SUPPORT ? new BroadcastChannel('latency') : {}; 5 | 6 | onmessage = function() { 7 | postMessage(0); 8 | }; 9 | 10 | channel.onmessage = function() { 11 | channel.postMessage(0); 12 | }; 13 | -------------------------------------------------------------------------------- /app/workers/message-service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | importScripts('../../components/threads/threads.js'); 4 | 5 | threads.service('message-service') 6 | .method('ping', function(obj) { 7 | return obj; 8 | }); 9 | -------------------------------------------------------------------------------- /app/workers/message-worker.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const BROADCAST_CHANNEL_SUPPORT = 'BroadcastChannel' in self; 4 | var channel = BROADCAST_CHANNEL_SUPPORT ? new BroadcastChannel('message') : {}; 5 | 6 | onmessage = function(evt) { 7 | postMessage(evt.data); 8 | }; 9 | 10 | channel.onmessage = function(evt) { 11 | channel.postMessage(evt.data); 12 | }; 13 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-workers-benchmark", 3 | "version": "0.0.1", 4 | "authors": [ 5 | "Guillaume Marty " 6 | ], 7 | "description": "Benchmark various aspects of Web workers.", 8 | "keywords": [ 9 | "web worker", 10 | "worker", 11 | "latency" 12 | ], 13 | "license": "MIT", 14 | "private": true, 15 | "ignore": [ 16 | "**/.*", 17 | "node_modules", 18 | "bower_components", 19 | "test", 20 | "tests" 21 | ], 22 | "dependencies": { 23 | "fxos-mvc": "git@github.com:fxos/mvc.git", 24 | "threads": "git@github.com:gaia-components/threads.git#master", 25 | "node-stats-lite": "git@github.com:brycebaril/node-stats-lite.git#~1.0.3", 26 | "node-isnumber": "git@github.com:brycebaril/node-isnumber.git", 27 | "gaia-header": "gaia-components/gaia-header#~0.8.1", 28 | "gaia-fonts": "gaia-components/gaia-fonts#~0.2.1", 29 | "d3": "~3.5.5", 30 | "regression-js": "~1.2.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | /** 2 | * IMPORTANT: This file is installed into the app directory as part of the 3 | * npm install fxos-build process. Please do not try to modify this file 4 | * or create additional build steps without checking with the team first. 5 | * 6 | * For any build system feature requests or bugs, please open 7 | * an issue in the fxos-build project: https://github.com/fxos/build/issues 8 | */ 9 | 10 | var gulp = require('gulp'); 11 | 12 | var buildModules = __dirname + '/node_modules/fxos-build/node_modules/'; 13 | var concat = require(buildModules + 'gulp-concat'); 14 | var to5 = require(buildModules + 'gulp-6to5'); 15 | var jshint = require(buildModules + 'gulp-jshint'); 16 | var zip = require(buildModules + 'gulp-zip'); 17 | var del = require(buildModules + 'del'); 18 | var runSequence = require(buildModules + 'run-sequence'); 19 | var webserver = require(buildModules + 'gulp-webserver'); 20 | 21 | const APP_ROOT = './app/'; 22 | const DIST_ROOT = './dist/'; 23 | const DIST_APP_ROOT = './dist/app/'; 24 | 25 | /** 26 | * runs jslint on all javascript files found in the app dir. 27 | */ 28 | gulp.task('lint', function () { 29 | // Note: To have the process exit with an error code (1) on 30 | // lint error, return the stream and pipe to failOnError last. 31 | return gulp.src([ 32 | './app/js/**/*.js', 33 | '!./app/js/components/**/*.js' 34 | ]) 35 | .pipe(jshint()) 36 | .pipe(jshint.reporter('default')) 37 | .pipe(jshint.reporter('fail')); 38 | }); 39 | 40 | /** 41 | * copies necessary files for the 6to5 amd loader to the app. 42 | */ 43 | gulp.task('loader-polyfill', function () { 44 | return gulp.src(['./node_modules/fxos-build/app_files/loader_polyfill/*.js']) 45 | .pipe(concat('initapp.js')) 46 | .pipe(gulp.dest(DIST_APP_ROOT + 'js')); 47 | }); 48 | 49 | /** 50 | * Copy all non-js directory app source/assets/components. 51 | */ 52 | gulp.task('copy-app', function() { 53 | return gulp.src([ 54 | APP_ROOT + '**', 55 | '!' + APP_ROOT + 'js/**/*.js' // do not copy js 56 | ]) 57 | .pipe(gulp.dest(DIST_APP_ROOT)); 58 | }); 59 | 60 | /** 61 | * converts javascript to es5. this allows us to use harmony classes and modules. 62 | */ 63 | gulp.task('to5', function () { 64 | var files = [ 65 | APP_ROOT + 'js/**/*.js', 66 | ]; 67 | 68 | try { 69 | return gulp.src(files) 70 | .pipe(to5({ 71 | modules: 'amd' 72 | }).on('error', function(e) { 73 | console.log('error running 6to5', e); 74 | }) 75 | ) 76 | .pipe(gulp.dest(DIST_APP_ROOT + 'js/')); 77 | } catch(e) { 78 | console.log('Got error in 6to5', e); 79 | } 80 | }); 81 | 82 | /** 83 | * Packages the application into a zip. 84 | */ 85 | gulp.task('zip', function () { 86 | return gulp.src(DIST_APP_ROOT) 87 | .pipe(zip('app.zip')) 88 | .pipe(gulp.dest(DIST_ROOT)); 89 | }); 90 | 91 | /** 92 | * Runs travis tests 93 | */ 94 | gulp.task('travis', ['lint', 'loader-polyfill', 'to5']); 95 | 96 | /** 97 | * Build the app. 98 | */ 99 | gulp.task('build', function(cb) { 100 | runSequence(['clobber'], ['loader-polyfill', 'copy-app'], ['to5', 'lint'], cb); 101 | }); 102 | 103 | /** 104 | * Watch for changes on the file system, and rebuild if so. 105 | */ 106 | gulp.task('watch', function() { 107 | gulp.watch([APP_ROOT + '**'], ['build']); 108 | }); 109 | 110 | gulp.task('webserver', function() { 111 | gulp.src('dist/app') 112 | .pipe(webserver({ 113 | port: process.env.PORT || 8000, 114 | host: process.env.HOSTNAME || 'localhost', 115 | livereload: false, 116 | directoryListing: false, 117 | open: false 118 | })); 119 | }); 120 | 121 | /** 122 | * The default task when `gulp` is run. 123 | * Adds a listener which will re-build on a file save. 124 | */ 125 | gulp.task('default', function() { 126 | runSequence('build', 'webserver', 'watch'); 127 | }); 128 | 129 | /** 130 | * Remove the distributable files. 131 | */ 132 | gulp.task('clobber', function(cb) { 133 | del('dist/', cb); 134 | }); 135 | 136 | /** 137 | * Cleans all created files by this gulpfile, and node_modules. 138 | */ 139 | gulp.task('clean', function (cb) { 140 | del([ 141 | '.bowerrc', 142 | '.editorconfig', 143 | '.git/hooks/pre-commit', 144 | '.jshintrc', 145 | 'dist/', 146 | 'app/components', 147 | 'node_modules/', 148 | 'gulpfile.js' 149 | ], cb); 150 | }); 151 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "web-workers-benchmark", 3 | "version": "0.0.1", 4 | "description": "Benchmark various aspects of Web workers.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/gmarty/web-workers-benchmark.git" 12 | }, 13 | "keywords": [ 14 | "web worker", 15 | "worker", 16 | "latency" 17 | ], 18 | "author": "Guillaume Marty ", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/gmarty/web-workers-benchmark/issues" 22 | }, 23 | "homepage": "https://github.com/gmarty/web-workers-benchmark", 24 | "devDependencies": { 25 | "fxos-build": "^0.5.0", 26 | "gulp": "^3.8.11" 27 | } 28 | } 29 | --------------------------------------------------------------------------------