How to set up efficient Bubble Conditions

Follow me:

Did you know that the order in which you set up your Bubble Conditions affect how well they will perform? In Bubble.io, a Condition is any expression that you set up to provide a yes/no answer, whether you’re doing it on an Element or in a Workflow.

A typical Condition placed on an Element would be to keep it hidden or visible based on some state of the User for example:

Bubble conditions used to hide a group when the User is not logged in.
This Group will only be visible if the Current User is logged in.

You can of course also place the same Condition on a Workflow or Action:

Bubble conditions used to stop a Workflow from running if the User is not logged in.
This workflow will only run if the Current User is logged in

From a performance perspective these two types of Bubble conditions (on elements and in workflows) behave a bit differently: any condition you place on an element will be processed as soon as the element loads – usually when the page loads. Bubble Conditions placed on a workflow or action on the other hand will run when you execute it (unless you deliberately separate the condition and the workflow to speed up your app using process spreading).

No matter where you place it though, there’s a simple physical matter at hand here: some kind of data needs to be processed somehow in order for Bubble to return a yes or no value. That process can sometimes be so fast as to the user not perceiving any delay at all (like the examples above), and other times they’ll bring up the blue loading bar that we all know and love.

Processes like that can happen on the client or on the server, and the latter is often a cause of delay. Let’s look at what that means.

Server-side vs client-side in Bubble conditions

Showing the difference between client-side and server-side in Bubble.io

Conditions happening server-side

The easiest way to check if a condition will need to query the server is to ask the following two questions:

  1. Does the condition rely on information in the database?
  2. Has that information been loaded yet or not?

Any time you ask Bubble to check something in the database you’ll experience a slight delay. Your browser sends the request to Bubble’s server, the request is fulfilled and the results are sent back. Alas, even if the information travels through state-of-the-art interoptic cables at about a speed of 300 000 km/s (186 000 mi/s), it’s not infinite after all.

So for the first question, we need to determine if we’re touching the database. Let’s set up a condition like the one below:

Setting up a condition using the Do a Search for expression in Bubble.io
We’re asking Bubble to search for something in the database, and that needs to be done on the server: we’re gonna see a slight delay.

Since we’re performing a search, we’re telling Bubble to “please check my database using these rules, and send the result back to me”. We’re clearly relying on information on the server here, and can expect a delay.

For the second question, we need to know if the information has already been loaded. How can we tell? We’ll need to ask the question: have we referenced this information anywhere at an earlier point? Take a look at the example below:

Setting up a Condition in the Bubble workflow editor.
In this case, the information is already loaded when the button is clicked. We’re not getting rid of the delay, but moving it.

In this example, we’re also asking Bubble to check some data in the database for us, again obviously needing information from the server. But, there’s a key difference here: since we’re asking about information that’s already loaded into the Parent element, we don’t need to ping the server again. Voila – the delay is gone. It’s worth noting here though: it’s not actually gone: we’ve just moved it. Bubble loads the information on page load, and when we run our condition, it’s already available to us. This way of thinking about when information loads is the cornerstone of process spreading.

But as always, there are caveats: what if we make a slight change to our condition:

Setting up a Condition in the Bubble workflow editor relying on the name of the Current User.
Now Bubble needs to access a sub-thing (User) of the Parent Group’s thing (Product) – again we need to ping the server and the delay is back.

Now we’re asking Bubble to reference the Parent Group’s thing (Product) – all good so far – but then we’re asking form information stored on another sub-Thing (User). This information has not been loaded, and we’re back to having to ping the server for it. What if we reference the Current User:

Condition in the Bubble editor depending on the name of the Current User.
In this example we also depend on data stored in the database, but the data stored on the Current User is always loaded on page load so it’s already available to us.

In this example, the logic tells us that we have to access the database to fetch this information: but we happen to know that information about the Current User is always loaded on page load. If you’re interested in learning more about the exact information Bubble loads on page load, check out our book The Ultimate Guide to Bubble Performance.

Conditions happening client-side

The client is the User’s computer, tablet or phone. Let’s set up another Condition as an example:

Condition in Bubble checking if a specific Element is visible or not.
Bubble doesn’t have to speak with the server here – this is all happening client-side.

In this example, we’re not asking for anything from the database. The element we’re asking about is already loaded, and Bubble obviously knows whether its visible or not, since…. well, it is.

So this Bubble Condition will be processed purely client-side and will be lightning-fast.

The order in which Bubble Conditions are evaluated

In regular programming (or indeed in mathematics), the order of operations is a set of rules that tells us which procedures to perform first in order to correctly evaluate a given expression. This is sometimes called or operator precedence or order of precedence. For example, in mathematics multiplication has a higher precedence than addition, and this is why 5 + (3 × 6) = 23 and not (5 + 3) x 6 = 48. Your teacher imprinted this in your brain sometime during your school years, and you keep that knowledge around to snugly be able to correct someone in a forum discussion once every few years.

Now throw that out of the window.

Bubble evaluates expressions purely from left to right, regardless of any other kind of precedence you might expect, and there’s currently no way to use parentheses to override it. This left-to-right thinking also applies to the order of multiple conditions on one element: left-to-right naturally leads to top-to-bottom, meaning that the last condition in a list will override any one conditions on top of it.

Back to single Bubble Conditions with multiple steps: In July 2021, they made an interesting change to how multi-step Conditional expressions are evaluated: Bubble used to go through all steps in the expression, regardless if it was really necessary or not.

From that change on, Bubble’s engine stops checking the expression as soon as it’s found a definite yes / no answer. Using and/or operators to bind together several steps in a Condition leads us to the following logic:

A and B, but A is false → return false and do not evaluate B.
A or B, but A is true → return true, and do not evaluate B

Bubble’s forum post explaining the change.

What does this mean for us? Well, since we now know that some Bubble Conditions take longer to evaluate than others (especially when they require server queries), and we also know that Bubble stops checking an expression if it already has a definite answer, we can draw the lesson that the order in which we set up our Conditions matter. Take a look at the Condition below:

multi step condition slow bubble
In many cases, Bubble really only has to check one of these conditions, since the or operator means we only need one yes.

Here we’re asking Bubble to first query our database (server-side operation) and then we’re checking an Element’s visibility (client-side operation). Since we’re binding the two steps together with an or operator, it means that as long as the first step returns the value we want, Bubble doesn’t need to check the second step. In our example here, we can exploit that fact to get a performance gain simply by switching the order of the steps:

multi step condition fast
By placing the client-side condition first we can speed this calculation up in cases where the Group’s visibility gives us the answer we’re looking for.

If the first step in this expression returns the value we want, Bubble skips the second step and never needs to query the database at all.

With a very small change, we’ve improved the performance of our app ever so slightly – and as we teach in the book: performance is a war of a thousand battles.

Leave a comment if you have questions or feedback, and if this tutorial helped you out, you can consider buying me a coffee or becoming a supporter. For more in-depth and advanced learning about important no-code topics you can also check out our Bubble.io books.

Support the site and keep it free ❤️

I love tech startups and the Bubble community, and have made it my mission to try and create content that’s valuable, easy to follow and entertaining.

Creating content next to full-time consulting work is time-consuming; if you’d like to support it and keep the site free for everyone, please consider buying me a coffee or becoming a supporting member.

Buy Me A Coffee

Follow me:
Bubble.io books

Learn Bubble the right way

Our professional Bubble books teach you how to plan, structure and build your applications right from the start.

5-star review stars

More Posts

Leave A Reply

Your email address will not be published. Required fields are marked *


Email icon

Useful articles and tips

Join the mailing list to get guides, opinions and articles on Bubble, no-code, automation and the tech industry.

We don't share your email address with anyone, and you can unsubscribe at any time.

You have successfully subscribed