gif.js icon indicating copy to clipboard operation
gif.js copied to clipboard

Slow speed on WebKit Browsers

Open semprom opened this issue 11 years ago • 10 comments

Hi. When using Firefox the rendering proccess is very fast, but when using wekbit browser ( Chrome or Opera ) the speed is way slower. Why is that and is there something we can do about it?

Thanks.

semprom avatar Apr 05 '14 16:04 semprom

What's the differences you are seeing, and how many workers are you using and what are the specs of the machine you are testing with? My initial tought is that it could be something related to the datatransfer between worker and the main thread, webkit should be faster since it's just passing a reference. But that could be what is wigging out :)

jnordberg avatar Apr 09 '14 00:04 jnordberg

On Chrome it rendered the gif for 50 secods. On Firefox for 13 secods .. Big difference. On Chrome it starts good and somewhere half the way it slows down. My PC is Dual Core AMD Athlon 4800+. I am using 2 workers on both browsers.

semprom avatar Apr 10 '14 20:04 semprom

Sounds like a code optimizer issue, somewhere along the line chrome gives up and uses "slow" javascript. We would need to find what code it fails to optimize and fix that

jnordberg avatar May 12 '14 21:05 jnordberg

For reference https://github.com/petkaantonov/bluebird/wiki/Optimization-killers

jnordberg avatar Jun 25 '14 12:06 jnordberg

I'm seeing this as well, I just built master and it's insanely slow on Chrome now. 0.1.6 was not slow though.

esprehn avatar Aug 19 '14 04:08 esprehn

@esprehn master has dithering support which was merged in, unfortunately that patch uses a much slower color lookup alg. That's why I haven't released a new version yet. I was planning on rewriting parts of that code before releasing a new version

jnordberg avatar Aug 27 '14 09:08 jnordberg

Fwiw, you can work around the slowdown problem by simply respawning the webworker after 10-ish frames (each) in Chrome. That seems to resolve the problem for me anyways.

pvdz avatar Oct 07 '14 20:10 pvdz

I'm seeing this right now in a bad way -- we're talking a fifteen to twenty seconds on Firefox versus several minutes on Chrome.

Any chance it's related to canTransfer here?

lostfictions avatar Feb 23 '15 01:02 lostfictions

Hello friends, I spent the weekend digging into the Chrome performance issue so I figured I'd give you all an update. This is a separate issue from the dithering issue.

I discovered the following:

  • Firefox and Safari perform as expected
  • Not related to canTransfer or postMessage() transfer efficiency
  • Chrome web workers will begin to slow down by about 10X after they have "chugged through" enough code or data. In my tests on my Macbook Pro & Chrome 45, a given worker would pass the threshold after rendering about 5 frames if the frame size was >= 720x1200.
  • Profiling a Chrome worker showed that NeuQuant.contest was taking the majority of the time during these slow downs.

I tried overly optimizing contest() in a few ways, and also tried porting the entire thing to pure javascript and compiling together with closure ADVANCED OPTIMIZATIONS, but couldn't fix the slow downs.

The hack fix that I was trying to avoid ended up being a simple re-creation of workers after N frames. Here is the code I have in JavaScript. My project is running on the raw javascript so I don't have it in coffee, but someone could easily patch this into gif.worker.coffee lines 103-109 if it's not too much of a hack.

var worker;
console.log("spawning worker " + i);
worker = new Worker(_this.options.workerScript);
worker.framesProcessed = 0;
var onmessage = function(event) {
    _this.activeWorkers.splice(_this.activeWorkers.indexOf(worker), 1);
    worker.framesProcessed++;
    // Re-create worker every 4 frames for big frames in chrome, since each worker starts to go
    // incredibly slow after about 5 frames
    if (browser.name === 'chrome' && event.data.width * event.data.height > 400 * 400 && worker.framesProcessed >= 4) {
        worker.terminate();
        worker = new Worker(_this.options.workerScript);
        worker.framesProcessed = 0;
        worker.onmessage = onmessage;
    }
    _this.freeWorkers.push(worker);
    return _this.frameFinished(event.data);
};
worker.onmessage = onmessage;
return _this.freeWorkers.push(worker);

dylanwenzlau avatar Sep 14 '15 05:09 dylanwenzlau

Since this seems to depend on the amount of data processed, with larger images resulting in slowdowns earlier in the render process, it sounds like this is an issue with leaking memory within the workers and/or Chrome's garbage collector not kicking in properly.

Others have reported similar issues with Web Workers and Chrome, albeit back in 2014: http://stackoverflow.com/questions/24708649/why-does-web-worker-performance-sharply-decline-after-30-seconds

mike-jumper avatar Nov 12 '15 01:11 mike-jumper