Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an easy way to run Firebase in a web worker?

I have a single page React application which consists of many files, bundled with gulp/browserify.

Firebase javascript is embedded in this bundle.

I'd like to know if there is an easy way to run certain Firebase operations on another worker thread ?


What I have tried :

Setting up a worker and sending the Firebase object, or instance, via worker.postMessage(xxx). In both cases, it throws an error which says the object cannot be cloned. Example bellow with the Firebase object.

var blobURL = URL.createObjectURL(new Blob([ '(',
    (function() {
        var onmessage = function(event) {
            var FB = new event.data.Firebase('my firebase URL');
            // Here, some Firebase operations
            // ...
        };
    }).toString(),
')()' ], { type: 'application/javascript' }));
var postViewedWorker = new Worker(blobURL);
URL.revokeObjectURL(blobURL);

[... later on ...]

postViewedWorker.postMessage({Firebase: Firebase, ...otherParams});

In the above example, the Worker works (haha) until I try to pass Firebase.


What I would like to avoid :

Setting two completely different bundles, one with the main application, and one dedicated to all Firebase operations, with a helper lib to send operations from one another.


Note : The reason behind this question is because my UI is slowed by Firebase operations. For example, I have a list of items displayed on a page, and when I scroll, each time an item is visible, the view count of this object is updated with Firebase. The page scrolling is smooth without those operations, and becomes jerky when I add them.

Edit: Also, I consistently get the following warning : Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience.

like image 520
Pandaiolo Avatar asked Sep 27 '22 07:09

Pandaiolo


1 Answers

Easy, depends on your values for easy. Possible, definitely.

I used microdom to get it working. Here's a rough/dirty version, bundle as makes sense to you.

In your worker:

importScripts("http://raw.github.com/tmpvar/microdom/master/microdom.min.js");
var window = microdom('<html></html>');
var document = window;
importScripts("https://cdn.firebase.com/js/client/2.4.2/firebase.js");

var ref = new Firebase(input.firebase_endpoint);
// This ref now works, authenticates, etc.  You can use .notify() to pass info to the main thread, etc.

ref.on("value", function(snapshot) {
    output.notify(snapshot.val());
});
like image 118
skoczen Avatar answered Nov 15 '22 04:11

skoczen