Inline Web Workers?

614 views
Skip to first unread message

Felix Halim

unread,
Oct 13, 2010, 12:40:07 AM10/13/10
to chromiu...@chromium.org
Currently, the only way to create a worker is via external Javascript file:

var worker = new Worker("worker.js");

It would be nice to be able to inline the "worker.js" inside HTML
(just like inline SVG).
Advantages:
- If you have N workers, you don't need N external Javascript files.
(Unlike CSS, you cannot automatically merge N Javascript workers into
one giant Javascript. It will break).
- If you have large JSON inside your HTML, and you want to pass it to
the workers there is extra serialization/de-serialization overhead.
The workers can get the data by itself via XHR, but it will cost
latency. If only the JSON data can be inlined inside inlined workers
inside the HTML, that would be the most efficient way to get the data
into the worker.

My goal is to be able to serve everything inside a single HTML file.
Inlining small things like CSS, JS, small images are very useful if
you only have a single HTML page.
However, for multiple (HTML) pages it may not be useful to inline..
but that's the developers' decision.


Btw, what's the conclusion for this thread:

http://groups.google.com/a/chromium.org/group/chromium-html5/browse_thread/thread/a254e2090510db39?hl=en

Felix Halim

Drew Wilson

unread,
Oct 13, 2010, 1:09:02 AM10/13/10
to Felix Halim, chromiu...@chromium.org
As an app developer, I'd have to agree with this. I don't know that "inlining" the javascript inside HTML is necessarily required, but it would be really nice if workers could use data:// URLs which are essentially the same thing. Unfortunately, data:// URLs are treated as their own domain, and cross-domain workers are explicitly prohibited by the HTML5 spec (the parent domain of a worker is currently derived from the origin of its script, and this mechanism would have to change to instead be derived from a parent document if we suddenly started allowing data URLs).

This issue has come up before in the various standards bodies (example: http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2009-October/023588.html), and I recall there was general agreement that this would be useful - I don't think it went anywhere as it was deemed premature to add that to the spec, but it's possible that we now have enough experience with the APIs to reopen that discussion.

BTW, at one point Opera supported data:// URLs in workers. Don't know if they ever took that out or not.

-atw


--
You received this message because you are subscribed to the Google Groups "Chromium HTML5" group.
To post to this group, send email to chromiu...@chromium.org.
To unsubscribe from this group, send email to chromium-html...@chromium.org.
For more options, visit this group at http://groups.google.com/a/chromium.org/group/chromium-html5/?hl=en.


Eric Uhrhane

unread,
Oct 13, 2010, 1:41:03 AM10/13/10
to Drew Wilson, Felix Halim, chromiu...@chromium.org
You could presumably manage it with a Blob url, but it's still not very nice:

Create a string that contains the JavaScript that you want the worker
to execute.
Use a BlobBuilder to create a Blob containing that string.
Use window.createBlobURL to get the url.
Create a worker using that url.

This'll work in Chrome as of version 8.

Drew Wilson

unread,
Oct 13, 2010, 12:57:34 PM10/13/10
to Eric Uhrhane, Felix Halim, chromiu...@chromium.org
Does this get past the same-domain check that Workers use to enforce that worker URLs share the same domain as the parent page?

-atw

Eric Uhrhane

unread,
Oct 13, 2010, 12:59:22 PM10/13/10
to Drew Wilson, Felix Halim, chromiu...@chromium.org
I haven't tested it, but I don't see why it wouldn't; blob URLs are
tied to the origin of the creating page.

Drew Wilson

unread,
Oct 13, 2010, 7:39:11 PM10/13/10
to Eric Uhrhane, Felix Halim, chromiu...@chromium.org
OK, I wrote a test and it seems to work. This is really very cool:

<html>
  <body>
    <div id="log"></div>
    <script>
      function log(str) {
        document.getElementById("log").innerHTML += str + "<br>";
      }
      var bb = new BlobBuilder();
      var script = "postMessage('ping');";
      bb.append(script);
      var url = window.createBlobURL(bb.getBlob());
      var w = new Worker(url);
      w.onmessage = function(event) {
        log("Received: " + event.data);
      }
    </script>
  </body>
</html>

Note that this only works if you load the HTML page over HTTP. Loading from a file doesn't work because we treat file:// URLs as a unique domain, so the blob URL isn't treated as same-domain with the window's domain.

Eric, how broadly are the blob APIs supported (are they on by default for webkit)? I'm thinking I might put some layout tests together to make sure this continues to work.

-atw

Felix Halim

unread,
Oct 13, 2010, 11:40:31 PM10/13/10
to Drew Wilson, Eric Uhrhane, chromiu...@chromium.org
Hmm, for complex script, this construct may help:

<html>
<body>
<script id="w1" type="text/html">
postMessage('ping');
// dump large inline data here
// complex scripts here
</script>

<div id="log"></div>
<script>
function log(str) {
document.getElementById("log").innerHTML += str + "<br>";
}
var bb = new BlobBuilder();

bb.append(document.getElementById('w1').innerText);


var url = window.createBlobURL(bb.getBlob());
var w = new Worker(url);
w.onmessage = function(event) {
log("Received: " + event.data);
}
</script>
</body>
</html>


I think I can live with that :)


Felix Halim

Ivan Zuzak

unread,
Oct 14, 2010, 5:10:16 AM10/14/10
to Chromium HTML5
Whoa, seriously cool! This approach definitely needs more publicity
bumps.

Ivan

On Oct 14, 1:39 am, Drew Wilson <atwil...@chromium.org> wrote:
> OK, I wrote a test and it seems to work. This is really very cool:
>

Jeremy Orlow

unread,
Oct 14, 2010, 8:21:56 AM10/14/10
to Ivan Zuzak, Chromium HTML5
This is probably worth a blog post somewhere.  (Maybe Chromium blog...maybe as part of a larger post about blobs in general?)

J

Eric Bidelman

unread,
Oct 14, 2010, 1:29:36 PM10/14/10
to Jeremy Orlow, Ivan Zuzak, Chromium HTML5
Very cool! I'll also make sure this gets added to the html5rocks.com tutorial on workers.
--
Eric Bidelman
Developer Relations - Google
e.bid...@google.com

Rick Waldron

unread,
Oct 14, 2010, 4:17:43 PM10/14/10
to Chromium HTML5
When this was first proposed yesterday I worked out a basic demo for myself, today i added an example "data burn" and posted a gist on github.com


The only problem with this method is that it throws an error if you try to use importScripts()




Rick

Drew Wilson

unread,
Oct 14, 2010, 4:22:54 PM10/14/10
to Rick Waldron, Chromium HTML5
Interesting. Note this - from the spec for importScripts():

Attempt to fetch each resource identified by the resulting absolute URLs, from the entry script's origin, with the synchronous flag set.

Since the entry script's origin is something like blob://http://<domain name>, doing a relative fetch from that base URL won't work.

What if you supply an absolute URL for importScripts()?

-atw

Jian Li

unread,
Oct 14, 2010, 4:32:14 PM10/14/10
to Rick Waldron, Chromium HTML5
The exception is thrown because the imported script cannot be found. Please note that you're using blob URL and thus all the subsequent relevant URL parsing is based on this blob URL.

So if you pass a full URL to the imported script, the exception will go away.


On Thu, Oct 14, 2010 at 1:17 PM, Rick Waldron <waldro...@gmail.com> wrote:

Rick Waldron

unread,
Oct 14, 2010, 5:07:08 PM10/14/10
to Michael Nordman, Chromium HTML5
Confirmed, this works.

On Thu, Oct 14, 2010 at 4:32 PM, Michael Nordman <mich...@google.com> wrote:
I think if you give import scripts an absolute url, it should work.

On Thu, Oct 14, 2010 at 1:17 PM, Rick Waldron <waldro...@gmail.com> wrote:

Drew Wilson

unread,
Oct 18, 2010, 5:33:46 PM10/18/10
to Rick Waldron, Michael Nordman, Chromium HTML5
Following up on this (again) - the BlobBuilder solution doesn't quite work for SharedWorkers, because blob URLs seem to be always unique, and SharedWorkers rely on having a common URL to accomplish their sharing.

There's been recent talk about adding actual support for data URLs (allow them to inherit their parent pages origin for the purposes of workers) which should enable shared workers to work.

-atw

Michael Nordman

unread,
Oct 18, 2010, 6:05:07 PM10/18/10
to Drew Wilson, Rick Waldron, Chromium HTML5
Public blob urls are tied to the life of the context in which the url was created. I wonder if loading a context (sharedworker|frame) with the blob url should extend the life of that url to the life of the context in which the blob is loaded?

Drew Wilson

unread,
Oct 18, 2010, 7:40:29 PM10/18/10
to mich...@chromium.org, Rick Waldron, Chromium HTML5
I don't think it's a lifecycle issue - if I load a page in two different tabs, and each page builds a blob with the same content, they get different URLs. SharedWorkers require that both pages have the same URL.

-atw

Michael Nordman

unread,
Oct 18, 2010, 8:34:27 PM10/18/10
to Drew Wilson, Rick Waldron, Chromium HTML5
(from the 'right' address this time)

Interesting... I wouldn't have imagined that the system would recognize two different shared workers constructed as you describe as the same.  The case i was thinking of was pageA starts a sharedWorker, which pageB connects too (via the public url created by pageA)... then pageA goes away... now the shared worker can no longer be addressed via URL because that url got revoked when pageA exited... there's no way for pageC to find it.

I don't think the constraint of using HTTP urls to identify and load shared workers is too much of a constraint, but it would be nice to have a better answer.

Bauglir

unread,
Nov 8, 2010, 5:23:29 PM11/8/10
to Chromium HTML5
It stopped working!!!

I'm using Cromium 9.0.566.0 (64209), I've replaced createBlobURL with
createObjectURL
and the constuction of worker triggers
Uncaught TypeError: Cannot read property '1' of null
error....
This is so cool feature I hope this is some bug, not something done on
purpose

Brona

On Oct 14, 6:29 pm, Eric Bidelman <ericbidel...@chromium.org> wrote:
> Very cool! I'll also make sure this gets added to the
> html5rocks.comtutorial on workers.
>
>
>
>
>
>
>
>
>
> On Thu, Oct 14, 2010 at 5:21 AM, Jeremy Orlow <jor...@chromium.org> wrote:
> > This is probably worth a blog post somewhere.  (Maybe Chromium blog...maybe
> > as part of a larger post about blobs in general?)
>
> > J
>
> > On Thu, Oct 14, 2010 at 2:10 AM, Ivan Zuzak <izu...@gmail.com> wrote:
>
> >> Whoa, seriously cool! This approach definitely needs more publicity
> >> bumps.
>
> >> Ivan
>
> >> On Oct 14, 1:39 am, Drew Wilson <atwil...@chromium.org> wrote:
> >> > OK, I wrote a test and it seems to work. This is really very cool:
>
> >> > Note that this only works if you load the HTML page over HTTP. Loading
> >> from
> >> > a file doesn't work because we treat file:// URLs as a unique domain, so
> >> the
> >> > blob URL isn't treated as same-domain with the window's domain.
>
> >> > Eric, how broadly are the blob APIs supported (are they on by default
> >> for
> >> > webkit)? I'm thinking I might put some layout tests together to make
> >> sure
> >> > this continues to work.
>
> >> > -atw
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "Chromium HTML5" group.
> >> To post to this group, send email to chromium-ht...@chromium.org.
> >> To unsubscribe from this group, send email to
> >> chromium-html5+unsubscr...@chromium.org<chromium-html5%2Bunsubscr...@chromium.org>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/a/chromium.org/group/chromium-html5/?hl=en.
>
> >  --
> > You received this message because you are subscribed to the Google Groups
> > "Chromium HTML5" group.
> > To post to this group, send email to chromium-ht...@chromium.org.
> > To unsubscribe from this group, send email to
> > chromium-html5+unsubscr...@chromium.org<chromium-html5%2Bunsubscr...@chromium.org>
> > .
> > For more options, visit this group at
> >http://groups.google.com/a/chromium.org/group/chromium-html5/?hl=en.
>
> --
> Eric Bidelman
> Developer Relations - Google
> e.bidel...@google.com

Drew Wilson

unread,
Nov 8, 2010, 6:06:13 PM11/8/10
to Bauglir, Chromium HTML5
The following still works just fine for me in 9.0.572.0 dev:

<html>
 <body>
   <div id="worker_script" style="display:none">
       postMessage('dedicated-worker ping');
       // dump large inline data here
       // complex scripts here
   </div>

   <div id="shared_worker_script" style="display:none">
     var count = 0;
     onconnect = function(e) {
       count++;
       e.ports[0].postMessage('shared-worker ping: ' + count);
     }
   </div>

   <div id="log"></div>
   <script>
     function log(str) {
       document.getElementById("log").innerHTML += str + "<br>";
     }
     var url = getBlobForScript('worker_script');
     log("dedicated url: " + url);
     var w = new Worker(url);
     w.onmessage = function(event) {
       log("Received: " + event.data);
     }

     url = getBlobForScript('shared_worker_script');
     log("shared url: " + url);
     var sw = new SharedWorker(url, 'shared');
     sw.port.onmessage = function(event) {
       log("Received: " + event.data);
     }

     function getBlobForScript(id) {
       var bb = new BlobBuilder();
       bb.append(document.getElementById(id).innerText);
       return window.createObjectURL(bb.getBlob());
     }
   </script>
 </body>
</html>


To post to this group, send email to chromiu...@chromium.org.
To unsubscribe from this group, send email to chromium-html...@chromium.org.

Bauglir

unread,
Nov 9, 2010, 9:00:24 AM11/9/10
to Chromium HTML5
Hi,
I've been able to find out the problem: I had "Debug" checked in
Developer tools for Workers.
Error occured there, in debuging, which prevented script to work.

B.
> > <chromium-html5%2Bunsubscr...@chromium.org<chromium-html5%252Bunsubscr...@chromium.org>
>
> > > >> .
> > > >> For more options, visit this group at
> > > >>http://groups.google.com/a/chromium.org/group/chromium-html5/?hl=en.
>
> > > >  --
> > > > You received this message because you are subscribed to the Google
> > Groups
> > > > "Chromium HTML5" group.
> > > > To post to this group, send email to chromium-ht...@chromium.org.
> > > > To unsubscribe from this group, send email to
> > > > chromium-html5+unsubscr...@chromium.org<chromium-html5%2Bunsubscr...@chromium.org>
> > <chromium-html5%2Bunsubscr...@chromium.org<chromium-html5%252Bunsubscr...@chromium.org>
>
> > > > .
> > > > For more options, visit this group at
> > > >http://groups.google.com/a/chromium.org/group/chromium-html5/?hl=en.
>
> > > --
> > > Eric Bidelman
> > > Developer Relations - Google
> > > e.bidel...@google.com
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Chromium HTML5" group.
Reply all
Reply to author
Forward
0 new messages