Skip to content
14paxton edited this page Aug 10, 2023 · 2 revisions

title: WebWorker
permalink: ReactNotes/WebWorker
category: ReactNotes
parent: ReactNotes
layout: default
has_children: false
share: true
shortRepo:

  • reactnotes
  • default


Table of contents {: .text-delta } 1. TOC {:toc}



Abstracted WebWorker

set content security policy if needed in index.html

  
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; worker-src 'self' blob:;/>      

worker builder file

//worker-builder.js      
export default class WorkerBuilder extends Worker {  
    constructor(worker) {  
        super(worker);  
        const code = worker.toString();  
        const blob = new Blob([`(${code})()`]);  
        return new Worker(URL.createObjectURL(blob));  
    }  
}      

handle worker messaging file

//ppt.worker.js      
// eslint-disable-next-line import/no-anonymous-default-export      
export default () => {  
    // eslint-disable-next-line no-restricted-globals      
    self.onmessage = (message) => {  
        postMessage("rebuild-ppt");  
    };  
};      

using working in compoenent

//use relative path from document baseURL      
// can be set in jsconfig.js      
//{      
/*  "compilerOptions": {      
 "baseUrl": "src"      
 },      
 "include": ["src"]      
 }      
 */  
  
import Worker from "containers/pptx/util/ppt.worker"  
  
const myWorker = new WorkerBuilder(Worker);  
  
  
export const MyWorkerComponent = () => {  
  
    useEffect(() => {  
        myWorker.postMessage("table-resize")  
  
    }, []);  
  
    useEffect(() => {  
        if (window.Worker) {  
            myWorker.onmessage = (message) => {  
                //do work      
            };  
        }  
    }, []);  
  
}      

Self Contained WebWorker

// worker.js      
// import api from "./testModule";      
// eslint-disable-next-line no-restricted-globals      
const workercode = () => {  
    // eslint-disable-next-line no-restricted-globals      
    self.onmessage = function (event) {  
        // self.importScripts("./testModule"); // eslint-disable-line no-restricted-globals      
        // eslint-disable-line no-restricted-globals      
        const {data} = event  
        if (data === "table-resize") {  
            // self.postMessage(api.message()); // eslint-disable-line no-restricted-globals      
            self.postMessage("rebuild-ppt")// eslint-disable-line no-restricted-globals      
        }  
    };  
};  
  
let code = workercode.toString();  
code = code.substring(code.indexOf("{") + 1, code.lastIndexOf("}"));  
  
const blob = new Blob([code], {type: "application/javascript"});  
const worker_script = URL.createObjectURL(blob);  
  
module.exports = worker_script;  
  

used in a context

export function TalentGridPPTXProvider({value, children}) {  
    const {setLoadingExportData, isCached, setIsCached} = value  
    const myWorker = useMemo(function () {  
        return new Worker(worker_script)  
    }, []);  
  
    const handleMessage = (event) => {  
        if (event.data.hasOwnProperty("show_more")) {  
            if (!isCached) setLoadingExportData(true)  
  
            if (myWorker) myWorker.postMessage("table-resize")  
        }  
    }  
  
    useEffect(() => {  
        window.addEventListener("message", handleMessage);  
  
        return () => {  
            window.removeEventListener("message", handleMessage);  
  
            //make sure webworker is released when component unmounts      
            console.log("terminate worker")  
            if (myWorker) myWorker.terminate()  
        };  
    }, [])  
  
};  

resources

Clone this wiki locally