From 5affa3c0f61061ab6e8d7684322814b051cc7a0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20Gro=C3=9F?= Date: Sat, 10 Feb 2018 18:52:04 +0100 Subject: [PATCH 1/5] Limit Workers to max. avail. CPUs --- lib/ImageWorker.js | 66 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/lib/ImageWorker.js b/lib/ImageWorker.js index 743e1c9..79c19aa 100644 --- a/lib/ImageWorker.js +++ b/lib/ImageWorker.js @@ -3,15 +3,10 @@ import React, { Component } from 'react'; const webWorkerScript = ` + const handleResponse = () => response.blob(); self.addEventListener('message', event => { const url = event.data; - fetch(url, { - method: 'GET', - mode: 'no-cors', - cache: 'default' - }).then(response => { - return response.blob(); - }).then(_ => postMessage(url)); + fetch(url, { mode: 'no-cors' }).then(handleResponse).then(() => postMessage(url)); }) `; @@ -34,11 +29,44 @@ const wrappedComponent = WrappedComponent => props => { return ; }; +/** Have we initiated the worker pool already? */ +const workerPoolCreated = false; +const workerPool = []; + +function createWorkerPool() { + const blobURL = URL.createObjectURL( + new Blob([webWorkerScript], { type: 'application/javascript' }) + ); + for (let i = 0; i < window.navigator.hardwareConcurrency || 4; ++i) { + workerPool.push({ + worker: blobURL, + inUse: false, + i + }) + } +} + +/** Returns the next available worker. */ +function getNextWorker() { + for (let i = 0; i < workerPool.length; ++i) { + const worker = workerPool[i]; + if (!worker.inUse) { + worker.inUse = true; + return worker + } + } + // no free found, so we just return the first one + return workerPool[0]; +} + +/** Marks worker `index` as available. */ +function setFree(index: int) { + workerPool[index].inUse = false +} + + class ImageWorker extends Component { image: HTMLImageElement; - worker = new Worker(URL.createObjectURL( - new Blob([webWorkerScript], { type: 'application/javascript' }) - )) state = { isLoading: true, @@ -46,21 +74,27 @@ class ImageWorker extends Component { } constructor(props: ImageWorkerProps) { super(props); - this.worker.onmessage = (event: Object) => { - this.loadImage(event.data); - }; + this.image = null; + + if (!workerPoolCreated) { + createWorkerPool(); + } } componentDidMount() { - this.worker.postMessage(this.props.src); + const workerObj = getNextWorker(); + workerObj.worker.postMessage(this.props.src); + workerObj.worker.onmessage = (event: Object) => { + this.loadImage(event.data); + setFree(workerObj.index); + }; } componentWillUnmount() { - if (this.image) { + if (this.image !== null) { this.image.onload = null; this.image.onerror = null; } - this.worker.terminate(); } renderPlaceholder() { From 0ed703ae6db36d6a45a83c51e5a4e94f80fc81d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20Gro=C3=9F?= Date: Sat, 10 Feb 2018 21:09:47 +0100 Subject: [PATCH 2/5] Fix mistakes --- lib/ImageWorker.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/ImageWorker.js b/lib/ImageWorker.js index 79c19aa..cad4d9a 100644 --- a/lib/ImageWorker.js +++ b/lib/ImageWorker.js @@ -3,7 +3,7 @@ import React, { Component } from 'react'; const webWorkerScript = ` - const handleResponse = () => response.blob(); + const handleResponse = response => response.blob(); self.addEventListener('message', event => { const url = event.data; fetch(url, { mode: 'no-cors' }).then(handleResponse).then(() => postMessage(url)); @@ -39,7 +39,7 @@ function createWorkerPool() { ); for (let i = 0; i < window.navigator.hardwareConcurrency || 4; ++i) { workerPool.push({ - worker: blobURL, + worker: new Worker(blobURL), inUse: false, i }) @@ -60,7 +60,7 @@ function getNextWorker() { } /** Marks worker `index` as available. */ -function setFree(index: int) { +function setFree(index: number) { workerPool[index].inUse = false } @@ -77,17 +77,16 @@ class ImageWorker extends Component { this.image = null; if (!workerPoolCreated) { + workerPoolCreated = true; createWorkerPool(); } - } - componentDidMount() { const workerObj = getNextWorker(); - workerObj.worker.postMessage(this.props.src); workerObj.worker.onmessage = (event: Object) => { this.loadImage(event.data); setFree(workerObj.index); }; + workerObj.worker.postMessage(this.props.src); } componentWillUnmount() { From bd51edf3ce92dd96411c15f5a0c2b171493d21e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20Gro=C3=9F?= Date: Sat, 10 Feb 2018 21:12:28 +0100 Subject: [PATCH 3/5] Run eslint --fix --- lib/ImageWorker.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ImageWorker.js b/lib/ImageWorker.js index cad4d9a..3c8a9b6 100644 --- a/lib/ImageWorker.js +++ b/lib/ImageWorker.js @@ -42,7 +42,7 @@ function createWorkerPool() { worker: new Worker(blobURL), inUse: false, i - }) + }); } } @@ -52,7 +52,7 @@ function getNextWorker() { const worker = workerPool[i]; if (!worker.inUse) { worker.inUse = true; - return worker + return worker; } } // no free found, so we just return the first one @@ -61,7 +61,7 @@ function getNextWorker() { /** Marks worker `index` as available. */ function setFree(index: number) { - workerPool[index].inUse = false + workerPool[index].inUse = false; } From 962f74820c174b2388c740fcfdc6fa53efff8cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20Gro=C3=9F?= Date: Sat, 10 Feb 2018 21:42:16 +0100 Subject: [PATCH 4/5] Fix another two mistakes --- lib/ImageWorker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ImageWorker.js b/lib/ImageWorker.js index 3c8a9b6..6b3f3dc 100644 --- a/lib/ImageWorker.js +++ b/lib/ImageWorker.js @@ -30,7 +30,7 @@ const wrappedComponent = WrappedComponent => props => { }; /** Have we initiated the worker pool already? */ -const workerPoolCreated = false; +let workerPoolCreated = false; const workerPool = []; function createWorkerPool() { @@ -84,7 +84,7 @@ class ImageWorker extends Component { const workerObj = getNextWorker(); workerObj.worker.onmessage = (event: Object) => { this.loadImage(event.data); - setFree(workerObj.index); + setFree(workerObj.i); }; workerObj.worker.postMessage(this.props.src); } From 5ff39d0868c9314ef0b68dcfec2c1be09d200799 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20Gro=C3=9F?= Date: Sun, 11 Feb 2018 09:38:00 +0100 Subject: [PATCH 5/5] Style fixes --- lib/ImageWorker.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/ImageWorker.js b/lib/ImageWorker.js index 6b3f3dc..53869de 100644 --- a/lib/ImageWorker.js +++ b/lib/ImageWorker.js @@ -86,7 +86,7 @@ class ImageWorker extends Component { this.loadImage(event.data); setFree(workerObj.i); }; - workerObj.worker.postMessage(this.props.src); + workerObj.worker.postMessage(props.src); } componentWillUnmount() { @@ -103,9 +103,8 @@ class ImageWorker extends Component { return ; } else if (typeof placeholder === 'string') { return placeholder; - } else { - return null; } + return null; } loadImage = (url: string) => {