Things I've learned while building complex apps

I get the feeling that the “spacer” or “object to squeeze” technique might have pre-dated some of the responsive options we have today. (Not sure as I’ve not been using Bubble for particularly long, so I don’t know the history of them. When I first ran across that in the footer I was like, “WHY???” :crazy_face:)

Anyway, glad that the suggestion helped!

This is very helpful. Thank you, Petter.

To clarify, does this apply at the page level or across the whole app? In other words, is there a cost to every page load for every element in the app, even if most are on pages that are rarely used?

(It feels like a dumb question, but I just don’t know if there are performance costs for having lots of pages, adding up to lots of elements, even if no one page is large or complex.

This is at a page level. Bubble only loads the elements needed for the page currently being accessed.

1 Like

Great stuff @petter!

Here are a few thoughts on what causes slow apps. Didn’t quite fit into the DO/DON’Ts. In my view (and feel free to comment), there are three things that cause slow apps, and knowing them may help to plan how your app is built:

DATABASE
The amount of, and complexity of database operations. The logic is straightforward: the more amount and complexity of work you give your database, the less efficient your app will be. It’s my impression (having a little knowledge about databases before Bubble), that a lot of Bubble users are not realizing how much work they’re truly putting their server through. For example, placing a Do a Search For on a page load with a thousand users per day means you’re forcing the database to perform the search a thousand times, maybe even more if the user’s reload the site too. By creating a list of the search, or hiding the content until the user asks for it, etc. you can drastically reduce the server workload. I actually find it easier to think of the database as an Excel sheet. Imagine you have a hundred lines. No problem. A thousand. No problem. But then you have an Excel document with millions of rows with hundreds of columns, and you have one thousand people working remotely on your computer at the same time, searching for stuff in the document. Obviously, your computer would become ridiculously sluggish. A server is a beefed up desktop computer in an entirely literal sense. It has a lot of computing power, but far from limitless.
DEPENDS ON,HARDWARE: Bubble’s servers
DEPENDS ON, SOFTWARE: the workflows and repeating groups on your page
HOW DOES IT AFFECT THE APP: whenever you perform an operation, such as a search, or create a thing, the app will slow down while the operation finishes. Usually it’s not noticeable, but with lots of operations and/or users, you’ll start to feel it. If creating one thing takes 0,2 seconds, creating ten things will take 2 seconds (probably not 100% accurate, but just to illustrate). By finding ways around it or moving it into API workflows, you can make the user experience a lot better.
EDIT: other excellent threads have gone into a lot of detail describing database performance. I recommoned this one in particular.

AMOUNT OF DATA TO DOWNLOAD
This is the actual size, in kb’s of your page. Let’s say a blank Bubble page is a 400 kb download. You write some text, that adds a few bytes. But then you want a nice custom font. That means the font needs to be downloaded, and the file is 100 kb. You just made your page 25% bigger. The page looks better with a nice, fullscreen background image. You compress it from 2,2MB down to 450 kb (nice!), and add it to the page. Compressed or not, the image added just increased download time by 90%. If you have a repeating group of users showing a 100 users, each with a 25kb profile pic, that means 2500 kb extra, increasing the download size another 263%. Big things and small things both matter.
DEPENDS ON,HARDWARE: User’s internet connection speed and RAM
DEPENDS ON, SOFTWARE: the files and scripts that you load into the app (images, fonts, custom scripts, etc)
HOW DOES IT AFFECT THE APP: first time loading, as all the files and data has to be downloaded. Also, a lot of heavy elements can make the user’s browser slow and choppy and eat up lots of RAM, completely unrelated to Bubble’s performance.
Bonus tip: use this site on all your images. It can drastically reduce their size with minimal loss: https://tinypng.com/

RENDERING
The rendering is the actual process that the browser performs, of transforming code into the visual experience that your user sees. The more complex your page (number of elements, number of effects like shadows, animations, amount of data displayed (long lists, etc), the more it demands from the user’s computer in terms of processing and RAM. Once the page has loaded (except for database operations), Bubble’s job is done, and if the app feels slow to browse, the fault is with the design, not Bubble. Keep it simple. When you think about it, most popular tech products really don’t look that fancy. They just work. There’s a reason Google’s homepage is nothing but a small logo, a search box and little text, even if they have access to the best designers in the world. I come from a marketing and design background, and I find it hopelessly tempting to throw myself into a creative bonanza of design. I’ve spent countless hours correcting that mistake by ending up with sites that are heavy to load, sluggish to scroll, not mobile friendly and where design trumps UX.
DEPENDS ON,HARDWARE: The user’s browser, RAM and processor
DEPENDS ON, SOFTWARE: how you design your page in terms of number of elements, effects, amount of data displayed (very long lists for example), size and number of images, icons and fonts
HOW DOES IT AFFECT THE APP: first time loading and continued use such as scrolling, hovering, etc. depending on how your app is built.

30 Likes

Excellent post! Thanks for sharing. How do you go about planning your app design? What tools do you use?

I’ve tested a bunch of tools, and find myself landing on the same one every time: pen and paper :slight_smile:

6 Likes

Ha, love it. :grinning: Thanks

I couldn’t find much explanation in the manual on the setting’s languages tab. I get what it does, but not how to use it for every text element. ANy good links for how you got really acquainted with it? Or was it just trial and error?

Also THANK YOU about the hovering not working in mobile. I had no idea and you just saved me from not having some main parts function!

Hi @alijones

I can’t remember exactly where I picked it up actually, but might have been just trial and error. To use texts saved in the Language tab in a text element (or any other element), you use the App Text. By default, this will show the English (en_us) text.

image

To determine which language the the current user should see, you set up a field of type Text, which includes the abbreviations for the different languages used in the language dropdown. So, if you want the user to see english, you set the field to en_us.

Note: be careful not to allow the user to choose languages that aren’t fully translated. I’ve found that when a string is not translated, even though it displays it in english in the Language tab, it will simply show up as blank in the app. Not sure if this is intended or a bug actually.

7 Likes

Ok I’m still brand new, so bare with me here:

So is it supposed to look like this? Or do I need to take out all the font settings and what not?

So I don’t get to see the text anymore unless Im in my settings, right? I feel like this is wrong though and that I completely misunderstood. Total noob here.

You don’t need to include the font settings in the translation text, as this is instead done by using Styles or directly in the element settings. The purpose of the App Text feature is to save “raw” text with no formatting, so that it can be used in any element.

I didn’t quite get your last question. If it wasn’t answered above, could you elaborate?

ahh ok. So you’re trying to save space by reusing text into multiple elements and having it set up to be interchangeable with other languages, right?

What I was asking was that I dont get to see the text itself anymore once I do that. For example, before App Text:
26%20PM

And after App Text:
09%20PM

That’s how it’s supposed to look right? Or is this not an appropriate place to implement this option? It seems like you’d want to do use it anywhere that there is text, so that it all translates… am I just misunderstanding the functionality?

Yes, it saves a bit of space by re-using repeated text strings, and if you change the Current User’s specified language field, he’ll see the text in his own language instead of default English (provided a translation is saved of course).

The bottom image I’m assuming is from your editor? Does the text show up correctly in the app preview?

It does, yes! Ill just do that. Thank you so much for all your help!

1 Like

This is very helpful! I’m a new user who has done the tutorials and read most of the manual, but still has a lot of questions about best practices. Thanks!

I’ve been trying to figure out a way to do subfields, so disappointing Bubble doesn’t support it, but good to know to stop looking.

Do you have any other recommendations on how to set privacy as more of a matrix? We have technician users that will support multiple companies. I want the company to only see their data (including what was created by the technicians supporting their company) and the technicians to only see the data for the companies they support (not all companies) including data created by company or other technicians.

Thanks!

Hi @2morses,

Thanks for the kind words.

Yeah, the option to use sub-fields in privacy rules would make things a lot easier, I agree. I don’t know Bubble’s specific plans on this, but my guess is that there are two explanations: 1) It’s more complex than we think, because of some way Bubble is structured, and may need a lot of work to amend. or 2) It’s simply a matter of priorities and they haven’t found the time yet: it will be there somewhere down the road. I don’t know which is true, but at the moment, what you see is what you get. Also, some of the restrictions make very good sense from a security perspective. For example, basing a security policy on a Do a Search for:First item opens up to severe and probably frequent security violations. So some of these restrictions, while frustrating, are obviously in place to force (admittedly often inexperienced) developers to set up rules that are absolute, and will not fail because of slight errors in a search or changes in database structure.

For your last question, there are several ways to solve it, but here are my initial thoughts:
In your User entry, you can set up a field called “Technician access”, which is a list of Companies to which the User should have access. As you then set up the privacy rule for the Company, you can set it up as "Current Users’s Technician Access contains this Company, and then give them whichever priviliges they should have.
For the regular users (that only have access to one Company, and maybe not all data that a technician can access), you set up a separate Privacy Rule with its own field (for example a singular Company, assuming each user never has access to more than one).

4 Likes

I came to the forum for a specific question…but got totally caught up in this post! And then, just like that:

DON’T overlap elements
In some cases, you may have to of course. But in general, overlapping elements makes responsiveness and page height confusing…

Haha, can’t make this up, there was the answer to the problem I was looking for! Briljant stuff @petter!

1 Like

Haha, glad I could be of service @SenorPelota, even if by random chance! :cowboy_hat_face:

@petter - That approach makes sense to me! I actually attempted the method you proposed a few days ago and got stuck because I apparently don’t know how to handle lists. I’ve tried looking for tutorials or other info, but I’m only finding how to define a field as a list (with the checkbox). That part is working just fine in the data type. I have a field on the User type for Company name (list of company type). But then, when I try to create an input type to populate that data, it says the fields are invalid. Can you point me in the right direction of how to create a list or give a user the ability to add to a list (company user able to add their company to the technician user)?

Thanks for your help!