Skip to content

lgarron/MagicWorker.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MagicWorker.js

Web workers are awesome because they allow you to run computations in a webpage without locking up the page. Most major browsers support it now, and there is good documentation and tutorials.

The Problem

Web workers don't work in every environment you might want, because of restrictions in Chrome:

  • Web workers work for sites on the internet.
  • Web workers work offline for sites using the offline application cache. However, this requires the user to visit the page and save the content, and is only available in that browser installation.
  • Opening a saved HTML file, e.g. by clicking on it in the OS file browser, does allow web workers, EXCEPT IN GOOGLE CHROME.

Chrome is wonderfully fast at some things, so it would be great if we could test and run "offline apps" that use web workers by opening oin any major browser them like normal files. However, trying to create a web worker using new Worker("file.js") in the usual way results in SECURITY_ERR: DOM Exception 18.

Usage

    1. Add MagicWorker.js to your project.
    1. Include MagicWorker.js in your webpage using a normal script tag, followed by each of your web worker files:

      <script src="MagicWorker.js"></script> <script src="change-this-to-your-worker-file-name.js"></script>
    1. Modify each web worker file by prepending the lines:

      (function(f) {if (typeof MagicWorker !== "undefined") { MagicWorker.register("change-this-to-your-worker-file-name.js", f); } else {f()}})(function() {

and appending the line:

    });

(Change "change-this-to-your-worker-file-name.js" to the name of the file.)

Caveats

  • Currently, each web worker code file must be self-contained. Any importScripts calls must be replaced with actual code if you want them to work offline. It might be reasonable to combine multiple web worker source files into one, which allows the code to interact by living in the same wrapper.

  • Not tested in Internet Explorer. Chrome, Firefox, Safari, and Opera all work (although the workaround is mainly for Chrome).

  • By default, the window's Worker object is replaced with the new MagicWorker wrapper. If you'd like to be able to use the original Worker object, remove the last line of MagicWorker.js, and replace only your desired calls to new Worker(...) with new MagicWorker(...).

How does it work?

It's possible to create an inline web worker by using a string containing source code instead of a file name. The trick lies in allowing the browser to create a web worker like usual (if possible), but fall back to a string if it fails.. There are many ideas for this that seem promising, but very few of them work.

It's possible to convert the web worker code into a string, but this is tedious, and requires having two versions of the code (unless you use eval). Chrome also has security measures that make it difficult to have a representation of code that can be run directly or as a string, but there are two generic ways to do it: place your source code in a script tag, or use the toString() function. Placing the source code in a script tag requires adding it to your HTML file, so I've opted for the latter. Thus, the full sequence for a web worker using MagicWorker.js is:

  • In the execution of the <script> tag, we create a wrapper function the our web worker.
  • Since we're not in a web worker environment, the function isn't executed.
  • A call to MagicWorker.create("file.js", workerCode) tries to create a web worker using the file name.
    • If this succeeds, the web worker creates the wrapper function and does execute it, immediately.
    • If we encounter a security exception with code 18, we try creating the web worker as follows:
      • Convert the function to a string using toString() to get its source code, then strip the anonymous wrapper function.
      • Create a blob from the string.
      • Creatie a temporary object URL for the blob.
      • Create a worker with the temporary URL.
      • (Set a timeout to release the temporary URL, for garbage collection.)

Resources

About

💻 Web workers in file:// pages for *all* browsers.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors