0

I am building a chrome extension and getting datas from a webpage(a list with 20 elements and hundreds of pages ) through my injected script.

This injected script is sending the datas via chrome storage to the background script.

The background script is calculating an array. Then sending the result to my content script where a mutation observer is waiting for an event where it’s using the calculated array.

I am sending all these data’s around by chrome.local.storage.set / get.

Because so there are so many different specs around, my mutation observer has an timeout of 1second for every loaded page / mutation because else the data’s are loaded to slow and it still has the data’s from the page before.

Is there a faster way sending these data’s around besides the chrome storage ?

Injected.js

//Gettig Datas before as constant players
const payload = {
                    PlayerList: players.map(player => {
                        return {
                            ID: player.id, //resource Id
                            Price: player.bin // Price
                        };
                    }),
                };
                var payload2 = Object.values(payload);
                chrome.runtime.sendMessage(extId, {type: 'GetPlayerList', data: payload2});

background.js

chrome.runtime.onMessageExternal.addListener(
function (request, sender, sendResponse) {
    if (request.type === "GetPlayerList") {
            var playertest = request;
            var playertest2 = playertest.data[0];
            var playerbase = chrome.storage.local.get("datafut", function (data) {
                playerbase = data.datafut;

                var data = mergeArrays(playertest2, playerbase);
                chrome.storage.local.set(
                    {
                        playerDataListCurrent: data
                    });
                console.log(mergeArrays(playertest2, playerbase));
            })
        }
});
function mergeArrays(playertest2, playerbase) { //Calculate an array
by filter the IDs from a 30Element Array and a 500Element Array}

mergeArrays function: array

content.js

 var s = document.createElement('script'); 
s.src =        chrome.extension.getURL('injected.js'); 
s.dataset.variable = JSON.stringify(chrome.runtime.id); 
s.asnyc = false; (document.head ||      
document.documentElement).appendChild(s); s.onload = function () { s.remove(); }; 


var observeTransferList = new MutationObserver(function (mutations) {
        mutations.forEach(function (mutation) {
            mutation.addedNodes.forEach(function (node) {
                if (node.nodeType === 1 && node.matches(".has-auction-data")) {
                $(node).css("height", "28");
                setTimeout(() => {
                    var playerDataListCurrent;
                    chrome.storage.sync.get(function (items) {
                        platform = items.platform;
                        discountprice = items.discountprice;
                        average = parseInt(items.average);
                        percentage = parseInt(items.percentage);
                        if (percentage === 0) {
//Data get
                            chrome.storage.local.get(function (items) {
                                    playerDataListCurrent = items.playerDataListCurrent;

                                    for (i = 0; i < playerDataListCurrent.length; i++) {
                                        //DO STUFF
                  }
                })
             }, 1000); // Timeout for unknown delay. Else its sometimes getting datas from array calculated before

            }
        });
    });

});
Red_Baron
  • 140
  • 1
  • 9
  • 1) It's unclear why you use the background script: you can do the calculations in the content script. 2) "injected" is vague as it applies to at least two things in extensions architecture so you should show how exactly you inject it. 3) using a timeout to prevent race conditions is usually a hack that means the overall approach is wrong in itself; an example of a correct approach is to use Promise wrappers and Promise.all. – wOxxOm May 27 '20 at 12:00
  • 1. Edited Post. 2. chrome.runtime.onMessageExternal.addListener not wokring at content.js 3. Need to look into – Red_Baron May 27 '20 at 13:28
  • 1
    Ah, a page context script can communicate with the content script directly by using CustomEvent, [example](https://stackoverflow.com/a/19312198). If you're worried about it being less secure then it's not - both can be intercepted *easily* and both can be guarded by installing your own spoofed handler. – wOxxOm May 27 '20 at 13:52
  • The question is: Is this really faster sending it directly to the content script? Besides I dont think the promise wrappers works with the mutation observers. – Red_Baron May 27 '20 at 13:54
  • 1
    It's *much faster* because it uses structured cloning within the same physical OS process instead of JSON stringification + parsing and two cross-process hops. As for Promise, it can be used anywhere a setTimeout is used, you'll simply have to use a global (or outer scope) variable to construct the Promise, but it's an extensive topic on how to organize asynchronous processing properly. It's just that using a timeout for the operations shown in the question is wrong, the only case it might make sense is if you're waiting for something external (if you don't control it). – wOxxOm May 27 '20 at 13:57
  • @wOxxOm what about creating a function that only listens to the playerDataListCurrent on change and then processing with " //do stuff"? Promise seems a bit to complicated / bulky for this. – Red_Baron May 27 '20 at 18:08
  • Once you embrace the concept, Promise is a simple and basic thing, especially if used with the modern await/async syntax. Of course you can use a callback too, just not setTimeout please... – wOxxOm May 27 '20 at 18:57
  • I want to get rid of timeout, ofc! Okay then I need to to get into it. If I understand it correctly, you can combine the observer with a Promise? Like: Dom object changed, but variable not - > do not do anything. Dom changed, variable gives callback due to Promise - > do stuff – Red_Baron May 27 '20 at 19:04
  • A Promise would be suitable for something that resolves once and then you disconnect the observer. A callback is for unlimited calls. I just don't know what your code does, so my advice about Promise may be incorrect. – wOxxOm May 27 '20 at 19:12
  • Using a direct caller to the content script did a amazing job! My extension is so much faster now, thanks! – Red_Baron May 29 '20 at 19:36

0 Answers0