Meteor Guide Regarding Blaze

Continuing the discussion from But Does Meteor Scale?:

@sashko @tmeasday

1 Like

I guess you need to think about two things when making these kind of performance optimizations (and it’s not always obvious; which is one of the downsides of Blaze/Tracker):

  1. How the reactive source (in this case this entire helper) will change
  2. What reactive contexts are using it, and how expensive it is to re-run them.

In this case, the ways the helper can change are:

  1. The list itself changes
  2. The # of requested items changes
  3. The count subscription goes ready
  4. The number of items in the list changes
  5. The items go out of sync with the visible items (hasChanges === true)

None of those things is going to happen very often (unless people are like crazily adding to the list), so I would probably not be concerned about mixing their reactivity up together.

The caveat to that is if something lower down the component tree was very expensive to render. In such a case you might want to control the re-rendering of that object so that it didn’t re-render unnecessarily if the number of list items changed, for instance. Passing the count in as a function would be one way to do that.

It’s a pity that Blaze doesn’t have the equivalent to shouldComponentUpdate, that would make it easier to not have to do these kind of optimizations high up the render tree.

4 Likes

Yeah another big benefit would be tracking changes to each template argument individually. We got a lot closer to that with the new {{#let}} syntax, which tracks each variable individually, but never got to making that work with template args - that would be my top vote for next core Blaze feature.

Honestly I think Handlebars’ specific semantics are just not a good syntax for reactivity. It wasn’t a problem for static templates, but the whole concept of the data context for example really messes you up when you need to be in control. If I were working on Blaze 2, the first thing I would do is remove data context, the second is make this always the template instance, and the third is get rid of event maps and do the React-style onClick events. Then actually I think it would be really nice to use!

6 Likes

Should be easy to make things more React-like - it’s just an implementation difference, remember? :smile:

joking aside, is it very unlikely MDG will make these changes to Blaze or maybe accept them as pull requests?

Can’t help but think of manuel:viewmodel when I read you, more or less takes care of all three problems. :smile:

2 Likes

Me too. Whenever I see people asking what and how to achieve something with Blaze, I see ViewModel already has the elegant solution(s) where pure Blaze need to twist so much to achieve the same. I always wonder why MDG doesn’t recommend ViewModel officially …

@sashko is there any reason NOT to use ViewModel when working with Blaze? Would that be performance or something else?

3 Likes

I’ve always wondered the same, I’ve been using it in my latest app and it is just fantastic!

I guess I just have a few differences in opinion with the author about how these things should work. In my ideal world Blaze 2 would be less magical so that it would be easier to tell where your data was coming from.

When I talked to a few people about why they were switching to React (and often off of Meteor entirely!) back in the day when React was still a small thing, the first thing people said was they were having a really hard time figuring out why their views were re-rendering.

While I think viewmodel makes it easier to do a lot of great stuff with a lot less code, I don’t think it brings an easier way to keep track of your app’s state changes and might actually make it more difficult since components are reactively updating things up and down the tree.

But some of the changes in particular are really really great.

1 Like

(sorry for the long answer)

I can’t really pinpoint where we disagree on what makes state management easy.

Here’s where I’m coming from with ViewModel:

Components should be isolated. I like to be able to drop or pluck them as I please without worrying of breaking some other part of the app. To me, the best way of achieving this is for every component to manage its own state. I find it hard to manage components when their state is somewhere else. And I don’t like to worry about leaving “orphan pieces of state” somewhere else. Because of that I prefer my components to live in their own bubble. With ViewModel every component is in charge of its own state.

That said, there are components which are tightly coupled with one another. Developers shouldn’t be penalized for working with a parent/child relationship which is coupled by nature. I don’t see the value in making developers run around to do what’s effectively this.parent().doSomething() (passing callbacks and whatnot). So instead being dogmatic about keeping everything separate, ViewModel recognizes those situations and provides an easy mechanism for dealing with parent/child relationships.

There is a third situation where components are independent in almost every way except for a small part. An example of this is a component with a list of items and two others showing information regarding the selected item. ViewModel provides a clean and simple way to deal with this situation: You create a shared container with the item selection, and then each component has the option to opt in and share the container with other components. The effect is similar to what you get with Redux, minus the ceremonies.

Sharing a property allows you to isolate the parts where the components aren’t fully in charge of their own state. The concept is similar to isolating the parts of your code which have side effects in functional programming. It may not be obvious but it also isolates components themselves. That’s because as far as each component is concerned, they own the property. So you can modify or remove any component that shares a property and the others are non the wiser.

The final situation is when you’re outside your normal app and you want to communicate with your normal components. For example if you have a widget that wasn’t created by a view model, you can pierce boundaries and get a hold of specific components so the widget can work with the rest of your app. This is dangerous and should be avoided but again, developers shouldn’t be penalized when they encounter situations like this. So ViewModel has an easy way to interact with components anywhere on the app.

Let me know if there’s anything I should clarify.

btw, I’ve tried to avoid using the term “view model” here since too many people don’t understand the concept and simply jump into their own conclusions.

6 Likes

Thanks for the reply.

Yes I agree understanding when reactivity do its work is not easy sometimes. But I think it’s also the great benefit brought by Meteor. That makes many works much easier (or magical) unless you start to work with things that have dependency / order.

To me, ViewModel doesn’t seem to make things more complex, it’s just inheriting Meteor’s natural behaviour.

Actually, I just learn not long ago that I could choose to work non-reactively like something = this.someprop.value in VM. That allows me to have much better control with the states. Probably this should be highlighted in the doc.

2 Likes

I haven’t followed up on it recently, but doesn’t blaze-plus provide a solution to help control reactivity and what gets rerendered? It’s been awhile since I looked at it, but if I remember correctly, it essentially wraps each property thats gets passed into a trmplate inside of a function for you.

1 Like

Can you then promote Blaze Components?

Aren’t Blaze Components those less magical in-between world?

I am really sad that not ViewModel nor Blaze Components are even mentioned in the guide. Why is that? When you started guide you said that guide will present common community projects how to achieve things. For view, you only talk about pure Blaze. None of community projects which many apps are using are mentioned:

Why is this so? I am really asking from the heart. Because it does pain one to invest so much time into Meteor ecosystem and not get even a link. I think all guide sections should start with something like:

Community developed this and this package to address some of things in this section. (And then list of packages with short description of their main points.) In this guide we will present for educational purposes how you implement those features directly, with only core Meteor primitives. But in serious apps you should probably use one of those packages.

Because I really do not know who at this point uses Blaze without any extra package (and here I am talking about various alternative reactive variables, subscription handlers, blaze plus, template extension, etc.).

2 Likes

That’s a good question actually - how could we find out how popular these extensions are? And which ones are best? How do we pick between view model and blaze components, for example?

I do not think we should really decide this. I think all those packages have their merits, different people prefer different styles. And also more exposure would help them get more feedback, which would benefit all in the longer term because through time we might discover new ideas, which are even better than current state of the art (React).

So, as I mentioned, list some of those main ones. Something like I had done at the end of the Blaze Components README. With all the length of the Guide content I do not think it would take too much work for one screen of those.

Also, if you would really be cool you would provide some way in the guide that all those packages could show how you would implement this in them. So users could switch and see. Similarly how I implemented language switcher in the tutorial. So in this way guide would be not guide to the Meteor, but guide to the Meteor ecosystem. Which is what you want.

So people could switch between packages and decide which one the prefer. There, for same problems, same content.

3 Likes

I’m with mitar. There should be a way to let people know they’re not restricted to the Blaze way of doing things. Maybe a section called “Packages that compliment Blaze” with links to the documentation and YouTube introduction (that will take care of the problem of updating the description).

Which ones to include? The guide already has links to packages and I don’t think they were chosen based on a hard and fast formula. They were probably chosen using “common sense”. Either way, the same criteria can be used to figure out which ones to include on the list.

It pains me to see people struggle with session variables, global objects, reactive-vars, reactive-dicts, template instance variables, etc. I just want to tell them they don’t need any of that with ViewModel. It’s not that ViewModel magically hides the complexity, it’s that all those things just aren’t needed with ViewModel’s way of doing things (a pattern which shall remain nameless since it has a horrible initialism).

And then there’s stuff like template communication, parent/child relationships, creating controls, automatic state save across hot code pushes, saving state to the URL, etc.

6 Likes

This! Double this!

I see so many posts on forums and tickets people having issues and I am like, why oh why. This is all already solved. I feel like salesman when I then propose to use Blaze Components. But I do not really care. It can be also some other project. Just do not suffer if it is not necessary anymore. People have had this issues before and found ways to address them. Use that.

2 Likes

I’m not even an author of one of these packages and I still feel like salesman when I tell people on Gitter/Slack/Irc/Forums “I don’t have such problems because I use this and this package”.

Being able to tell them “the guide mentions that you can use it too” would be great.

Do you think it would be a disservice to developers if the first thing they have to do when using Blaze is decide between ViewModel and Blaze Components?

2 Likes

For now, first thing they do is do the official tutorial, then go to forums/IRC/gitter/slack and start asking questions, because they either feel something is missing or they have some problems.

Even now, when guide is available for everyone, people come and ask if there’s an alternative to using Sessions. I believe Meteorchef’s article about ReactiveVars is still one of the most popular articles about Meteor ever, I see it recommended to new Meteor devs all the time.

Then still people have issues with that. They want to be able to directly use helper in a helper, or helper in an event. I tell them that I don’t have such issues, because I never use any Session or ReactiveVar with manuel:viewmodel. And for those who prefer to use ReactiveVar, there’s a cool alternative package reactive-field by Mitar. I saw people using reactive-class which provides some cool features too.

I switched to manuel:viewmodel when ViewModel2 became a thing (which I think partially happened thanks to great job by Dalgard with both his Viewmodel and Jade packages), but before I was using Blaze Components for a long time and checking out Flow Components, Blaze 2 and Template Extension, each of them giving me something cool and helping me to broaden my perspective on how to write and structure my Blaze code.

Having one solution to recommend is the optimal thing, of course, I see your point.

But the advantage a dev gets using any of them is still worth having to spend the time to decide.

Perhaps we, the community, could spend more time writing tutorials for such packages, to make them more popular and to lessen the load of work that the authors of them, such as Aldeed, Manuel or Mitar have.

3 Likes