Reactjs, what are the benefits vs Blaze?

I’ve been trying out the recent React package for Meteor (react-meteor) and after going through the leaderboard example I started to wonder what the advantage of using react over blaze is. I realise there’s an already established library of components (which I’m yet to work out how to use with meteor), but other than that, what does react do that blaze doesn’t?

5 Likes

one big advantage that pushed me to use react in one of my project is very fast re-rendering.

The first rendering of a web page can be fast or slow, depending on the page. But successive re evaluation of the code by the browser are as slow as the first rendering with blaze.

With react, you only re evaluate the modified code.

Think a javascript library which renders images from a text (i.e.: mathematical graphics with mathjax). If you have 10 images, and change 1, with blaze you have to re-evaluate all of them (2-3 seconds), with react you only re-evaluate the changed one (200-300 milliseconds, one order of magnitude faster).

2 Likes

I thought blaze re-rendered only the diff. Are you sure about that?

I thought Blaze does only re-render a diff as well. But, the way that it re renders is different from React.

I’m sure MDG folks can talk more on this like @sashko @slava @avital

Blaze also works like react almost most of the cases when doing re rendering. That being said, sometime blaze is faster something react is faster. It’s based on the use case.

Blaze does not have so called virtual Dom.

React’s power is its component system.

5 Likes

React uses the virtual dom to do the diff of the whole dom tree. But it only touches the dom where it needs to. As far as I am aware, blaze only looks at the descendants of the node that the event was triggered on but does not utilize the virtual dom. In theory if dom operations weren’t so expensive, i’d think blaze would be faster. But react’s utilization of the virtual dom usually has it winning in rendering performance.

What really shines about react and frameworks like ember is their solid implementation of the component system. Being able to completely have isolated components and have components be able to communicate with the application using things like actions really helps setup and structure your applications in a nice, modular way. Ability to use ES6 modules for imports and exports and not have globals floating all over your application is also a major difference here. But any type of current integration of a front-end framework like react with meteor would still be unable to support the import and export functionality from ES6.

3 Likes

agreed with @Maaz and @arunoda - component system is the big advantage over blaze. the fact that all of the code required to render a portion of your view is encapsulated in one app is incredibly powerful and easy to work with.

like facebook engineers say in all their talks, it provides a high level of predictability to your app; that is awesome to work with.

But Meteors packages can also include html, css, javascript and they’re
much easier to use than having to browserify components from npm.

2 Likes

You can package your React components + assets with Meteor package system. Here an example React component packaged for Meteor

3 Likes

I haven’t used React with Meteor, so take my opinion with a grain of salt. My problem with React is that it essentially seems like an unnecessary framework, a stepping stone towards web components. But we already have the Web Components open standard, and Polymer has reached v1.0. Also, @mitar has released meteor-components.

From Why React is a terrible idea:

“Unlike Google, whose revenue largely depends on their search engine–which, in turn, depends on people using the Web for everything–Facebook has always benefited from being a walled garden. Put another way, Facebook doesn’t care if you use the Web, it only cares that you use Facebook.”

“Web components are the biggest leap forward for the Open Web in years…and, yet, we’re talking about React, a completely unnecessary framework.”

“Just by using new innovations like Web components, instead of work-arounds like React, you’re contributing to the success of the Open Web. You’re voting with your code.”

The virtual DOM is nice, but can be done separately. React Native is nice because Cordova doesn’t yet achieve the same level of performance and native look.

See also, If DOM’s performance improves to the point where it’s as fast as JavaScript, will the complexity of defining React components in a web app have been in vain?.

4 Likes

In my honest opinion, wait til the hype dies down to see if it’s actually worth it.

I think React’s virtual DOM has pretty nice benefits once you discover the reading DOM properties is often pretty costly because it might force the browser to do work. Blaze in this case when it is doing its diffing reads the state from DOM and then updates the changes. This makes it work nicely with 3rd party changes to the DOM because it is applying only changes which are needed to get it to the new reactively computed state.

React on the other hand does not have to read from DOM anything, it just compares with virtual DOM and runs write operations to the real DOM to get it to the internal state. That means no forcing of DOM values just to update them a moment later. The downside is that if real DOM was changed by some 3rd party library (read jQuery) those changes might not be nicely merged with, but will probably just be overwritten because virtual DOM does not know anything about them.

So Blaze works well with 3rd party libraries which was its design goal when it was made, while React does not, which was also its design goal. Blaze didn’t ship with components but it ship with mostly all building blocks necessary to build components around it (views and templates) just people mostly do not use them as components and are using only the simple template approach which is good for small apps and to get you quickly do some things in Meteor, but becomes problematic as things grow. This is why I put some good patterns into a reusable package so that it is not necessary to manually use templates and views as components, but you have some help with that: https://github.com/peerlibrary/meteor-blaze-components

What would be interesting if somebody would add virtual DOM on top of Blaze. There is a stand-alone virtual DOM library and we could have something like #isolate again, which would mean that only Blaze is controlling that part of the DOM, so it can use virtual DOM and speed things up.

3 Likes

Probably this is why experiments with running Tracker flush at requestAnimationFrame seems to show promise. I am guessing that this is because browsers expect you to query DOM at that time so you do not trigger unnecessary additional DOM computations.

Polymer would be nice, but we are not in shadow DOM phase on all browsers. So any content in polymer component will be moved around to shadow part etc, making it hard to manage with Blaze templates atm while we run it in that shady DOM or how it is called.

And yes, you can create template local reactive variable, but ppl just polute Session and talk about no componetisation…

For me React’s way of organizing state and how that state gets propagated down to children makes it a slam dunk for complex apps.

With React, all child components can get their data via props. This means they’re essentially pure functions. They receive an input and they output a specific output (html). This makes them really easy to unit test and even easier to debug since they can only have a state and data should only be coming down one direction… just follow the data flow.

The way React structures a component seems odd at first. But it’s actually quite nice. Everything is in one place, logic, view code, etc… Once you start breaking them down into small bits the sweet spot for having it all in one file is nice (no 200 line files!).

With Blaze, by default the normal way of doing this is having data coming in from many outside places: Session, Router subscriptions, startup subscriptions in an autorun, etc… These all get sent into the template one way or another making it somewhat brittle after time. Managing state has traditionally been very difficult, though now we have Template subscriptions.

However you can still apply the React methodology to Blaze if you wanted to. A reactive dict. could stand in as parent state, and children Blaze templates could receive their data through a parent instead of each child reaching out and grabbing state/data.

Speed is the last on the list for me. Blaze is plenty fast. However Iron Router’s reactive re-running taxes it to death if you have too many reactive variables in a controller. Taking data out of the Router gave Blonk a huge speed boost.

10 Likes

Best quote here. For me it’s more of the application architecture that it promotes rather than virtual dom diffing or infinitesimal increases in rendering speed. For me it seems the bottleneck is usually the 100-200ms it takes the database to spit data back to the app over the internet, not the 10ms it takes the dom to draw the screen…

Putting all the ‘react DOM performance zomg’ stuff aside, I’m definitely feeling much more confident in my code when the state is explicitly managed as a single thing, and adding flux to that really does make things super easy to understand. Now I can pretty much look at anyone’s react project on github and quickly see exactly what is going on. Whereas with other frameworks it takes a lot more work to find where each variable is coming in, what gets set where and how that last template file consumes it. And with blaze there are many ways to solve the same problem, so everyone solves it their own way. With react there really is only one way, the single direction data flow.

Even in my own blaze code there used to be many head-scratching moments when I didn’t realize something was getting set somewhere else in my app and things should be working but aren’t… Working on new pieces of the app and then coming back to stuff I did weeks ago was causing lots of wasted time re-understanding what I did last time I was working on this section…

And then with things like setting my own propTypes which warns me if I forget to pass something the component needs is just awesome. It really helps my coding experience later on when I might forget exactly how this component was originally written.

2 Likes

I am thinking about re-writing these material design basic elements into meteorhacks:flow-components.
Would you like something like that to use instead of hacking React/Angular/Polymer to cooperate with Blaze ?

2 Likes

I would be a bit wary on flow-components. They’re pretty new and no indication how long they’re be supported. Also the ramp up period for other devs to understand what’s going on will be a bit tough.

If you’re interested in React, there are material design components here that you can just drop in:

http://material-ui.com

Also it’s really not a hack to include React. Blaze can setup up a static page with a div container and then you can render in the top react parent component.

Or I just use a thin wrapper than takes car of mouting/unmounting like this:

<template name='Feed'>
  <div class="feed">
    <div class="container">

      <div class="col-25">
        <!-- see lib/blaze_adapter for this render helper -->
        {{> ReactComponent type="ParamsExample" }}
      </div>

      <div class="col-50">
        {{> ReactComponent type="CreatePost" }}
        {{> ReactComponent type="FeedData" }}
      </div>

      <div class="col-25">
        {{> TrendingPosts}}
      </div>

    </div>
  </div>
</template>

Full example here

2 Likes

I actually did a POC of this:

and it works really well. There’s no diffing, it just queues DOM updates (from Blaze) virtually and dequeues to the real DOM in a requestAnimationFrame loop with a time limit. It’s written for famous-views to make sure that Blaze can’t block an animation frame.

I haven’t mentioned it before since I haven’t had any more time to work on it and it obviously doesn’t cover all cases… some thought would be necessary to (as you say) decide if we should allow the user to manipulate the real DOM and/or provide a more complete virtual DOM, and to decide what level of optimization we’d like, if any.

The repo is just a simple Meteor app with a replacement blaze in the packages folder (which pretty much has just one addition, a new file called virtual-dom.js, and the templating package, with just a 1 line change to use the virtual-dom too).

1 Like

tl;dr React makes dealing with change and handing state in large apps simple.


It’s not immediately clear when working on a small app with no changes over time. I’ve built several React apps, two in production and one that has a lot of complex state. I’ve also built a complex app with Blaze. Both have had a chance to ‘rot’ and obtain technical debt. Here’s my rundown on the differences.

When data is coming in at all directions and jQuery is manipulating your template HTML without your knowledge it can turn into spaghetti quickly.

Speed differences don’t matter that much

React may be faster in some cases but Blaze is fast. The virtual DOM may save your bacon if you have a lot of heavy animations. However most of us don’t have that problem.

More Predictable

It’s not Blaze’s fault but normally your data in Meteor is coming in from many places, Router subscriptions, startup subscriptions, Session, etc… There is no way of declaring what your templates need. However we recently have gained Template subscriptions and moving subs out of the router is catching on.

In React a top level parent component is the entry point. It gathers data and pushes it down through each child. Children don’t reach out and get data, parents pass it to them. They should be pure functions that take params (via HTML props) and output an HTML string depending on what the props look like. In Blaze children typically reach out and grab data from Session or MiniMongo. They can even have other jQuery bits mess with their HTML which can lead to bugs. This is the big difference.

Unit testable

Because pure components either take a param (from HTML props) or have their own private internal state, they are very easy to unit test (even without Meteor/Velocity running). It’s hard to TDD Blaze views, so much that I don’t test them at all and cover them with brittle acceptance tests.

Markup in your JS isn’t a big deal

Your templates are heavily coupled to your template JS logic. Putting them in separate files only separates the technology used (HTML/JS). The whole point of the 90’s ‘no HTML in JS’ is that it was hard to maintain if you have some HTML strings in the JS and most in an HTML file. JSX is just sugar for createElement calls. You can still create divs with those calls if you really wanted to. Having the whole template in the render allows for very high cohesion. By breaking down your views into many components your render methods won’t be very large.

16 Likes