Full-stack reactivity: opt-in or opt-out?

Loving all the polls around here recently, I thought I’d drop in one more.

What is the optimal situation for a web framework? Should your app start with everything being client/server reactive, and then you turn it off when you don’t need it (opt-out)? Or should your app start assuming non-reactive data, and then you add it in where you need it (opt-in)?

Let’s call out a few things:

  1. Reactivity is often more expensive to operate than not-reactivity
  2. Reactivity results in a better base user experience, but not always, since UI moving around unexpectedly isn’t great
  3. Not all backends support reactive features, but a good number do
  4. Reactivity often saves you from needing to manually update the UI via refetching data, speeding up initial dev time in most cases
  5. If you start building your app assuming full-stack reactivity, it might be really hard to get rid of it later even if that is an option, since you might have built your UI in a way that assumes that feature

So what do you think? I guess this isn’t really covered by a poll, so post a comment too!

  • Opt-in, off-by-default reactivity
  • Opt-out, on-by-default reactivity

0 voters

For reference, here are a few options that fit in the above categories:

  • Opt-out Meteor, Firebase
  • Opt-in GraphQL with subscriptions available, Redux with REST and an event stream

I’m curious what people think is best both for initial development time, and for long-term sustainability, etc.

Reactivity should be seen as an additional feature, and it’s a great feature. But I think the main reason is summed up here

Reactivity is an intensive resource sink, so having it off-by-default seems like the most reasonable solution for production-grade applications. The defaults should always tend to higher performance, with the option of introducing new features with ease. As the reactive community has seen, not all parts of a UI need to be synchronized in real-time. Reactivity is really useful for pushing real-time information about active events (notifications) to users (time-critical information), but a lot less important for things like: “If Alice changes the title of an old Post, Bob should see the changes to the title”. I might only need the latter case to update every 20 minutes, whereas the former case should be instantaneous. I think the more important question is how reactivity is achieved. For some situations, I need the instantaneous oplog-style reactivity, and in other cases some magnitude of polling will work fine.

Automated oplog-style reactivity is not always available, and it’s brittle to rely on standalone drivers for each possible reactive source. A more general solution might be to have the developer encode when certain subscriptions should update based on mutations made by them:

/*in some method call
UPDATE*/
Posts.update(postId, {$set:{title:newTitle}})
//RESYNC
//this will replace the role of the oplog, and can be used with any database
//this will resync the "title" field to anyone subscribed to these sub-defs:
Subscriptions.sync([{name:"posts"},{name:"posts-detail",params:postId}], {fields:{title:1}})

//oops I also forgot that my subscription "posts-title" depended on this... 
//sucks for me!

This should be an optimization in the same way that shouldComponentUpdate can be used in React to optimize rendering.

I think is it better to at least have a simple option for reactivity even if it comes in an op-out situation. But having the option with the choice to turn it on or off is more appealing because with this you can make adjustments as needed whether if it is for a business decision or for a design decision.

Full-stack electricity: opt-in or opt-out?

I think we can all agree that the world has moved away from candles and oil lamps to electrical lighting. The same is happening with the internet. We’re moving away from websites to reactive apps.

12 Likes

Bonus, this is basically exactly how Apollo GraphQL subscriptions work, beta release blog post coming tomorrow!

I’m not sure there could be any system that would be equally optimized for both. Inherently, one has to be the “base” experience, and the other will be an “add-on”.

I think the metaphor is pretty heavy-handed. I think a relevant metaphor would be something like the iPhone 7 headphone jack - should wireless headphones be an optional add-on, or a base requirement? Apple might be able to produce enough wireless headphones and adapters that it doesn’t really matter, but there are still some concerns there. Another similar thing is electric cars - they work, but still have less infrastructure than gas cars for the time being.

The Prius and hybrid was a pretty genius idea - a car that could take advantage of the efficiency of electricity, but also the infrastructure for gas-powered cars.

3 Likes

I think when I started out with Meteor, my thinking was that the reactivity would be worth the price. But scaling. So I think with default reactivity there can be a bit of buyers remorse if you code thinking that reactivity is a given. Ultimately though, scopes change and re-thinking reactivity is always a concern with Meteor. I think having reactivity off by default may force that issue sooner rather than later.

But I also think that this comes back to the whole idea of classic meteor. For a true MVP, reactivity isn’t a concern, so having it on by default is fine. But for production, forcing the issue early on makes more sense to me.

Yeah, I’m not saying this is how meteor should be, just interested in getting people’s ideas about the topic.

@sashko I am looking forward to that post. Please post the link to it on the forums if you can!

@awatson1978 What you propose is a grand long term vision, for sure, and is surely the way forward. Electricity comes at a cost which may not be available to everyone. I tend to not use the lights if there’s sunlight. For me, electricity is something to be “turned on when I need it”, not something to be “turned off when I don’t need it”. We continue to live in a world where electricity is used only when it’s affordable. Reactivity, like electricity, may not be affordable for everyone. Why would MDG build a product that limits its user base? People react opposite to the direction of greatest change. If MDG doesn’t provide a suitable product for the many, they won’t be able to provide a product for the few. In a world with effectively infinite computational resources, of course everyone would default to Reactivity, which is simply better than non-reactivity. But since we don’t have infinite resources, the definition of “better” must be changed.

4 Likes

Increased dev speed and better user experience are the most important factors to me.

2 Likes

What costs (performance, financial) are you willing to deal with to get these?

I think like most Meteor users I don’t have a scaling problem yet. I understand it can be different for the biggest Galaxy customers.

1 Like

Interesting question, most parts of our apps use Meteors reactivity (f.e. if a user adds something to a collection). But I would prefer an opt-in model, because reactivity can end in unwanted behavior or performance issues. With an opt-in model I have to think about if I do really need reactivity for this part of my app. Think this would be a better solution than enable it for everything.

1 Like

As long as it is easy to opt in. Something like collection.find().reactive() that enables the reactivity. If it is a trial to opt in, then I’d rather have it default reactive.

3 Likes

Also same opinion as @rubenpa
As long as reactivity can be enabled relatively easy, I would prefer opt-in, since it’s easier to start coding and testing non-reactive modules. Later on, whenever you make sure evrything is working you can simply change queries to be reactive, and improve your tests easily.

1 Like

I like how it is…
Is there any reason to bother with that choice?
Its quite easy to disable reactivity once needed.

If process changes it will be easy to enable it.
So, whats the matter?

1 Like

I think that is an excellent counter argument.

Now then… since you’re willing to take the analogy seriously, would you also agree that when a house is wired up that it’s common to leave the circuit breakers on? When we turn off the lights in a room, we don’t do so by going into the basement and turning off each circuit breaker. We turn on/off the light in the room that we need; or we turn an appliance on/off. So, in that sense, the potential for electricity through the entire house is always on. We only opt-out of the potential and turn off the circuit breakers when doing renovations or when closing the house down for the season.

I bring this all up, because architecturally, there’s a difference between opting in/out of the endpoint (the template/component) versus opting in/out of the infrastructure potential (the pub/sub/minimongo). Maybe template reactivity should be opt-in; but client side caching? Wouldn’t having that be opt-in be similar to telling homeowners that they have to flip circuit breakers to turn on lights?

8 Likes

More or less, I was referring to a system as a whole that would give you the choice to choose your reactive parts. I am enjoying the quality that Apollostack/Graphql brings into my development phase. Though on the other hand, Meteor’s opt-out is better that having to manually emit events to all connected clients.

I prefer the opt-out, on-by-default reactivity and here is my opinion on it:

I think generally speaking people want fast and responsive experiences, and reactivity by default drops the cost of implementing such behavior. Developers are spared from wiring and making decisions on whether a feature should be reactive or not…and I think many entrepreneurs will welcome one less decision and leaning on the safer side of a better customer experience. This is consistent with your statement 4 and to some extent 2.

But yeah that would generally result in a more complex underlying system…the automatic gearbox of a car is much more complex then the manual one and some might prefer the manual gearbox since they’ve much more control over the engine…but really, how many people still drive manual nowadays?

6 Likes

Reactivity is a double edged sword, and is certainly not a guarantee for customer UX.

Do you mean developer’s own UX while developing with Meteor? Or do you mean monetary implementation costs, and resource costs? Wouldn’t we need to consider both?

Reactivity done naively can easily make the experience slow and completely unresponsive, as can be seen on many posts here and on stack overflow. Eventually, the developer will have to go in and make fine-grained tweaks if they’ve been throwing reactivity at every data source they send.

2 Likes

Hello Streemo,

I meant developer experience…and it seems that you made a distinction between a more pleasant experience for a developer and the cost of the product. But the way I see it, is that a simpler experience is less decisions, which spares some cognitive cycles to make business decisions instead of tweaking a feature that end user expects by default.

I personally didn’t experience those issues, but let us assume it’s true. If your automatic gear implementation is glitchy then you don’t go back to manual, your just try to improve it.

Your main counter argument is that if reactivity is implemented naively then the system might under perform in the future… this might be true with the current state of technology ( although luckly I’ve not seen it yet to complain about it) but can we assume for the sake of argument that this never happens i.e. your system always performs with reactivity, then let me ask you this: are there any other reasons why you want to turn reactivity off from user(end user that is) experience? and if yes, can you give a concrete example?