I am working on a chrome extension that takes images from a website and tries to predict the objects in those images. I am using tensorflow.js pre-trained MobileNet model for making predictions.
As part of my initial setup, I was able to pass messages between my contentScript and background script using port-messaging. However, once I import the MobileNet model in my background script, the background becomes non-responsive and even console.logs() are not showing up in the devtools.
Manifest.json
...
"host_permissions": ["https://www.dawn.com/"],
"permissions": ["storage", "tabs"],
"options_page": "options.html",
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["https://www.dawn.com/"],
"js": ["contentScript.js"]
}
]
...
Background.js
const mobilenet = require("@tensorflow-models/mobilenet");
async function genPrediction(img) {
const model = await mobilenet.load();
const predictions = await model.classify(img);
return predictions;
}
chrome.runtime.onConnect.addListener(function (port) {
port.onMessage.addListener(function (msg) {
console.log("msg: ", msg);
if (msg.type === "get_model_prediction") {
genPrediction(msg.img).then((response) => {
port.postMessage({ response });
});
}
});
});
contentScript.js
var chromeRuntimePort = chrome.runtime.connect();
chromeRuntimePort.onDisconnect.addListener(() => {
console.log("runtime is disconnected");
chromeRuntimePort = undefined;
});
// when using the port, always check if valid/connected
function postToPort(msg) {
if (chromeRuntimePort) {
chromeRuntimePort.postMessage(msg);
} else {
console.log("runtime is not defined");
}
}
let images = document.images;
postToPort({msg: "get_ml_predictions", images: images});
The MobileNet model is 254KB on disk but it depends on tensorflow library which is 60 MB on disk, and my packaged extension in dev mode is 12.5 MB. Could it be that the imported library is too big to require in the background script? Are there any best practices for requiring modules in background scripts that I should be following? Any help will be much appreciated!
Note: I am using webpack to package my extension.