You have given life to a fantastic idea by developing your brand new Bubble app, you went into beta testing, Oh! The users love the idea but there is an issue, the app is running painfully slow.
Ugh! We all hate slow things.
You’re cursing Bubble.io under your breath, Your friend tells you “it’s probably because you don’t have many servers dedicated to your app, just upgrade to a better plan”.
Seriously, you need new friends. Your app can be slow due to many reasons. So let’s consider other factors first, before spending 10x more money on server capacity.
Here is a list of things you can do to make your app faster and get an optimized bubble app.
Let’s have a look at them one at a time and make intelligent decisions
The “Constraints” in bubble searches work on the “AND” logic meaning, you only get the items fulfilling all the constraints (of course we have the exception of “ignore empty constraints”). Sometimes we need to add additional filters to the search results.
Let’s take an example, your application allows users to book spiritual appointments as either “one-on-one” or “grouped”. You need to display all the users to a spiritual doctor, who is both in one-on-one and grouped sessions…
Your noob approach would be applying the filter after searching…
Ah well, this reminds me of something…
So let me guide you, on how should you approach this…
Simply use “intersect” to handle it. Search for all appointments of type one-on-one attendees and intersect those with Search for all appointments of type grouped attendees
Similarly, if you face a situation with filters again where you need all the users which belong to one or the other type replace intersect with “merge”
A small but important step for an optimized bubble app.
Now we know filters are bad but what’s the worst of filters “the advanced filters”, friendly advice avoid it at all costs.
Let’s take the same example as before if you approach it the noob way, here is how the bubble will see it… first search all the users, and second check all the searched users one by one to filter out the ones which satisfy the advanced query (which is already a costly one).
The first step is not that costly since bubble searches the database like a tree, which is pretty fast compared to other searches. The second step is the one that piles up the cost. How? You ask… Consider this the search returns 10,000 records, now step two is saying “hey bubble parse through all 10,000 of them one at a time and check if they satisfy the condition”.
The result is an extremely slow search and frustrated customers.
Let’s say, expanding the above example we now add “activities” and “activity rooms. Now we have activities in each appointment and each activity has a list of rooms.
You want to display all the available rooms for an appointment to the user. What you use looks something like this
“A search within a search”
What is essentially happening here is that the system is looking for rooms and while looking for rooms it is looking for activities that belong to the current appointment hence a nested search.
To put it simply in numbers if we have 3 activities in total with 2 rooms each for the current appointment, how the system will search is by iterating over one room at a time and then iterating over all three activities. The total of 3 * 2 = 6 iterations. Now imagine you have hundreds of rooms and hundreds of activities, your system is gonna slow down searching here.
How can you cater to such cases? Simple, find the node and attach it to all of its children and grandchildren. Meaning linking the rooms with appointments.
The repeating group itself takes some time to load and display the records and if we use searches inside each cell it will multiply the time complexity of the search.
The best way to avoid this is to design your database in such a way that it doesn’t come to this. Use relations among the tables and make sure that the important information is available across each table.
Although bubble.io uses indexed-based searches over the entire app. Yes, I accept that index-based searches are fast but when it comes to workflow actions and events, if we put a search expression inside a conditional it takes some time to evaluate that condition to a “yes” or “no” as bubble.io has to perform the search using provided constraints and based on the result, it carries out the action or doesn’t.
Like the one shown below
An effective method to speed up this process is to replace the search expression in conditionals with a group placed on the page and give it the source type of the data item you want. Now use the data source of that group in the conditionals.
You will note a huge difference in load time between both approaches.
Most of the time the page load speed and the app optimization are dependent on the amount of data being loaded on the page initially. It is rather a small and skippable thing but it leaves a great impact on the system.
A naive approach would be to load a large amount of data, say 300 or more rows on page load and it loads the system resulting in a slower application.
Now what’s the solution, I bet most of you have already seen it in many web applications. Let me put it in easy words for you.
Whenever we have a list to display on the page load, try either loading limited records, the best I will say 25 at a time, and then use extended vertical scrolling or use pagination i.e., display a limited number of records on a single page.
Congratulations! You are one step closer to an optimized bubble app.
The system handles the application images, by rendering the images/videos in real time the larger the image/video the more time it takes to render.
Also, whatever services you use for your application, it has a limit on storage capacity. So, if you have a lot of images/videos, there is a high chance that the limit would be reached real quick.
Most of the services have a limit of MBS/GBS for a single file upload, to handle that smartly always compress your files.
If you have thousands of elements (inputs, groups, images, images, etc) meaning, thousands of lines of code. Now, adding one line doesn’t seem like a huge change, but eventually, you’ll see that the page is loading slower, the scrolling may become choppy and it all seems… sluggish. Every single element that you add to the page has to have a size, position, and styling, computed by the browser before everything is rendered on the screen.
So make sure you use the elements smartly.
Since the page codebase doesn’t only consist of elements on the page: every workflow and action that you have in the workflow editor will also be a part of the total weight of that page.
Be sure you don’t have stale workflows there.
If you have your elements looking like this
Your page is gonna have to make a serious effort to load up here. All of the styles that you define like this are a part of inline CSS. Having more and more of these are gonna end up increasing the size of your CSS file resulting in a slow application.
Try defining a set of styles that you are gonna reuse all through the application.
The best way to avoid the inline CSS and remember what exactly the style looks like is to have a design page. A design page can look something like this
The idea behind the design page is to have a look at the styles altogether and to make sure that the application follows a consistent style.
You are getting closer to getting an optimized bubble app.
Try to use as few plugins as you can. If you have to use, the one which has minimum lines of code for instance ionic elements plugin is way bigger than iconify or material icons.
Do not go around and keep making changes to the database for things that can be achieved by simply using state(s). States are a lot faster than database searches and on top of that database updates.
“Make changes to a list of X things,” think again.
This action works great when making a quick change to a small list of things, but as the items in the list grow, it raises the chance of the workflow timing out. If you’re experiencing timeouts with such actions, try using “Schedule API Workflow on a list”, which is much better because it takes the list and schedules an API Workflow to run on each item of the list in parallel with some defined delay (i.e. lowering the risk of a timeout).
For massive lists consider using schedule API workflow recursively. It is more scalable, though a bit slower, than running the API workflow on the entire list at once. If you are persistent on running it on a list then you need to increase your server capacity.
You might be having some extremely long workflows, with a lot of actions like this one:
This will take a while.
This workflow will take a while, especially if it involves things like external API calls, making changes to/copying a list of things, etc.
What we can do to avoid the delay here is to move to the server side, the API workflow. This way all you need to do is execute the part that has to happen right on the page (charging the user in this case) and then pass whatever parameters are needed to the API workflow, on the server side.
This would be much quicker
There might be some tasks that are optimized but still a bit slow for you (needs a long time to execute). What you can do to overcome it is to have a good sense of user experience.
Try making it more pleasant to the users by letting them know what’s going on or keeping them entertained with some animations while they wait. Some amazing animations can be found over Lottiefiles.
We all know how important privacy rules are in any application. Of course, they are fundamentally used to keep the data of the application secure. Then why are we discussing them in application optimization?
Good question, If you have really strict privacy rules, the amount of data that is ever gonna sent to the browser will be limited to those privacy policies. Lesser data means lesser page load time.
This is something like a safety net. Say you have messed up with your search expression somewhere, the privacy rules are there to save you from leaking the sensitive information of the application to unwanted users
Fonts, images, and plugins always add to the total download size and some of the server requests to your application page, ultimately slowing it down. You might be unconsciously using them on the page, or they might be downloaded as an asset. You can use the Chrome network tab to identify such files that are weighing your page down and what kind of font files and JS libraries are being loaded.
This also helps you to identify which library/asset is taking the most time.
When you are done with the above-mentioned tweaks but still the voice inside you says, I might have missed something. No worries at all, bubble.io has got your back. Bubble.io can effectively and efficiently find out the “unused” things (styles, datatypes, plugins, etc) in your application and remove them for you in one click.
All you need to do is go to Settings→ General, scroll down to the bottom there you see the “Optimize Application” button.
Click on it and you see the following screen.
Here you can select what you want to keep and what to remove.
Remember, you cannot see inline CSS properties here.