Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are angular $broadcast and $on expensive?

I've been told that using angular events can be expensive (I've been unable to verify this)

Any calls to $broadcast and $on should be 'wrapped' with a factory or service to inject into their corresponding components to preserve performance?

Again I'd rather use $on and listen directly to the events being fired rather than creating a factory that in essence is just going to register functions to call when it receives the event - lets call this a dispatcher.

Please note that it's not just one component (directives) listening to 'some-event' there will be a variety of components listening to this event.

Example dispatcher:

angular.module('app').factory('dispatcher', ['$rootScope', function ($rootScope) {

    var registeredFns = [ ];

    $rootScope.$on('some-event', function (evt, msg) { 
        _.each(registeredFns, function (fn) {
            fn.apply(null, msg);
        });
    });

    return {
        onSomeEvent: function (fn) {
            registeredFns.push(fn);
        }
    };
});

And inject it where I need it - maybe a directive, maybe a controller where ever it doesn't matter.

like image 819
Nate-Wilkins Avatar asked Nov 27 '13 15:11

Nate-Wilkins


People also ask

What is $emit $broadcast and $on in AngularJS?

Broadcast: We can pass the value from parent to child (i.e parent -> child controller.) Emit: we can pass the value from child to parent (i.e.child ->parent controller.) On: catch the event dispatched by $broadcast or $emit .

What is $broadcast in AngularJS?

$broadcast() as well as $emit() allow you to raise an event in your AngularJS application. The difference between $broadcast() and $emit() is that the former sends the event from the current controller to all of its child controllers. That means $broadcast() sends an even downwards from parent to child controllers.

What does scope emit do?

Scope(s) can be used to propagate, dispatch event to the scope children or parent. $emit - propagates the event to parent. $broadcast - propagates the event to children.

What is scope emit in AngularJS?

$emit() allows you to raise an event in your AngularJS application. It sends an event upwards from the current controller to all of its parent controllers. From the syntax point-of-view, a typical call to $emit() will look like this: $scope. $emit("MyEvent",date);


1 Answers

They're not expensive at all... but they're potentially expensive if they're misused (like anything else in life - this sounds like the start of a good joke!)

It's important to understand what's actually happening in here, and the code is actually pretty straightforward. If you call $emit(), it just does a for() loop across the array of registered listeners and calls each one. It does this on the scope you first call it on, and then walks "up" each parent until it hits $rootScope.

There's a little bit of extra code to handle things like stopPropagation, but otherwise that's it.

$broadcast does something similar, but in the opposite direction: it does this for() loop but then goes through every child scope. That's a super important difference, because if you do a $rootScope.$broadcast() and you have a lot of ngRepeats and directives floating around, you could be doing a huge amount more work than you expect - even if none of those scopes listen for this event, Angular still has to go through them all to figure that out.

Your fastest use-case if you want to do the fastest possible test in jsPerf or similar would be to use $rootScope.$emit() and $rootScope.$on(). That will give you a single-scope test for basic message passing and you can go from there.

like image 54
Chad Robinson Avatar answered Sep 29 '22 14:09

Chad Robinson