Niet the Dark Absol
Niet the Dark Absol

Reputation: 324790

Limitations of Web Workers

Please bear in mind that I have never used Web Workers before and I'm having some trouble wrapping my head around them.

Here's an explanation of a simplified version of what I'm doing.

My page has links to various files - some are text, some are images, etc. Each file has an image showing a generic file icon.

I want the script to replace each generic icon with a preview of the file's contents.

The script will request the file from the server (thereby adding it to the cache, like a preloader), then create a canvas and draw the preview onto it (a thumbnail for images, an excerpt of text for text files, a more specific icon for media files...) and finally replace the generic icon's source with the canvas using a data URL.

I can do this quite easily. However, I would prefer to have it in the background so that it doesn't interfere with the UI while it's working.

Before I dive right in to this, I need to know: can Workers work with a canvas, and if so how would I create one? I don't think document.createElement('canvas') would work because Workers can't access the DOM, or am I misunderstanding when all the references I've found say they "can't access the DOM"?

Upvotes: 12

Views: 10334

Answers (3)

Larry
Larry

Reputation: 395

So as others have stated, you cannot access the DOM, or do any manipulations on the DOM from a web worker. However, you can outsource some of the more complete calculations on the web worker. Then once you get your return message from the web worker inside of your main JS thread, you can extract the values you need and use them on the DOM there.

This may be unrelated to your question, but you mentioned canvas so i'll share this with you.

if you need to improve the performance of drawling to canvas, I highly recommend having two canvas objects. One that's rendered to the UI, the other hidden. That way you can build everything on the hidden canvas, then draw the hidden canvas on the displayed one. It may not sound like it will do much if anything, but it will increase performance significantly.

See this link for more details about improving canvas performance.

Upvotes: 2

vitaly goji
vitaly goji

Reputation: 256

Another (frustrating) limitation of Web Workers is that it can't access geolocation on Chrome. Just my two cents.

Upvotes: 2

jfriend00
jfriend00

Reputation: 708036

You cannot access the DOM from web workers. You cannot load images. You cannot create canvas elements and draw to them from web workers. For now, web workers are pretty much limited to doing ajax calls and doing compute intensive things. See this related question/answer on web workers and canvas objects: Web Workers and Canvas and this article about using webworkers to speed up image manipulation: http://blogs.msdn.com/b/eternalcoding/archive/2012/09/20/using-web-workers-to-improve-performance-of-image-manipulation.aspx

Your simplest bet is to chunk your work into small chunks (without web workers) and do a chunk at a time, do a setTimeout(), then process the next chunk of work. This will allow the UI to be responsive while still getting your work done. If there is any CPU consuming computation to be done (like doing image analysis), this can be farmed out to a web worker and the result can be sent via message back to the main thread to be put into the DOM, but if not, then just do your work in smaller chunks to keep the UI alive.

Parts of the tasks like loading images, fetching data from servers, etc... can also be done asynchronously so it won't interfere with the responsiveness of the UI anyway if done properly.

Here's the general idea of chunking:

function doMyWork() {
    // state variables
    // initialize state
    var x, y, z;

    function doChunk() {
        // do a chunk of work
        // updating state variables to represent how much you've done or what remains

        if (more work to do) {
            // schedule the next chunk
            setTimeout(doChunk, 1);
        }

    }
    // start the whole process
    doChunk();
}

Upvotes: 11

Related Questions