Hey everyone,
I’m seeing something odd in my Bubble page load metrics and would love your input
I have a single page app which runs from my index page. Bubble metrics shows both P50 and P99 page load duration (render complete) are ~5.8 seconds. From what I understand, this suggests a consistent bottleneck affecting all users and Im looking for ways to improve it
A few important notes about my setup:
-
Frontend is Bubble, backend is Xano (all data via API)
-
I’ve already heavily optimized the UI:
-
Minimal conditions
-
Only one font across the app
-
Only one set of icons across the app
-
Lightweight structure
-
No heavy repeating groups
-
Minimal images (non on page load)
-
Still, the load time is consistently high across the board
What do you think could cause this?
I just seen that my bubble version is 22 (from 2023) - could this have such a big impact?
Ive been optimizing this for some time now and just cant seem to improve it..
Thanks a lot!
Omer
Have you looked at the network graph in the devtools? Anything stand out?
1 Like
Hey, thanks for the reply
Yeah i was investigating it but Im not too familiar with it. this is how it looks like on page load:
Anything interesting here?
My guess is you might be running all API calls on page load. You mentioned minimal conditions and an SPA.
Usually an SPA tries to mimick a native app quick view change by loading all data on first page load instead of only when needed
Are your repeating groups and other data sources loaded in main data source section of element, or conditionally with a condition like only when this element is visible, which usually references a reusable element the data source container is in.
Even when something is not visible its data could still be fetched. Those first 2-3 seconds from graph look like element loading, then 3-5 seconds looks like data loading
4 Likes
@boston85719 is probably onto something here.
If this is truly an SPA on the index page, I’d strongly suspect hidden/reusable sections are still evaluating their data sources on initial load. In Bubble, “not visible” does not always mean “not doing work,” especially if the element already has a api call in data source for example.
The P50/P99 being almost identical also makes this feel like a fixed initialization pattern, not intermittent slowness.
A few things I’d check:
- repeating groups with a data source defined from the start
- reusable elements that load searches even before the user navigates to that section
- workflows/API calls triggered on page load
Another good clue would be comparing data loaded vs render complete. If both are high, that points more toward page-wide data hydration than just asset weight.
2 Likes
Thanks for the reply!
I actually dont run all apis at once. My flow is:
- Auth request
- Main essential api (which is requierd to show page and is fast)
- All other data apis are requested when needed
As of repeating groups and data fetches blocked by conditions or hidden elements - I actually tightly control when i trigger my Xano data apis so they are not affected by their visibitly or other conditions. But - that makes me think of another thing - each of my reusables have paramaters which recieve dynamic data from these APIs. Could that be an issue when the expected data wasnt fetched yet?
Any other ideas? Im losing my mind here 
OK this is super interesting
I do have all sorts of reusables functioning as pages which are hidden on page load. Some hidden pages have repeating groups with a data source and some of them recieve data from the first moment as the initial API request feed these hidden pages as well
What would you do with such a case? I can for example add a condition which empty all of the reusables’ (which functions as inner pages) parameters that rely on dynamic api data, so untill the page is viewed it wont try to to do anything with this data
Just to be clear - all of my apis are controlled from the index page and the data is being fed into the reusables as dynamic parameters
As of data loaded- this is the metric:
And for this is for render complete
Any other idea?
Thanks for the help!!!
1 Like
Another thing that comes to mind, Im mangaging my languages dynamically from my backend. I pull all app texts using a key-value json via the api connector and connect each value to a specific text using a specific value
The api is pretty fast but I wonder how to treat hidden reusables so they dont need to process these texts (and other dynamic data arriving from the reusable paramters). Maybe its better to have the reusable parameters empty as default and only set the data using a condition which is only active when the reusable is shown?
1 Like
I’m converting my app to a SPA and have been chipping away on the build. 3 pages (each reusable elements) to go! Definitely interested in seeing how I can improve page load speed.
The repeating groups is interesting since most of my pages (reusable elements) have some RG being loaded when the reusable element is visible.
Based on that, what are some best practices (conditions, workflow, etc.) to make sure the RG doesn’t load data when not visible?
1 Like
Yes, any data source not needed until reusable is visible should be set conditionally, even parameters.
1 Like
I think @boston85719 is correct here, but thought I’d add some tips on how to use the network tab to help in these situations.
I think you opened the network tab after everything was done (it’s only showing the css files etc), so always make sure to hit cmd/cntrl + r to refresh the page with the network tab open.
When you do this, you should see all the requests the browser makes. If you press filter for fetch/xhr at the top, you can see when the browser makes a data request to the backend (i.e. to Xano data api in your case).
Here’s a screenshot of what this all looks like on the bubble forum home page for instance. When we click one of them, we can see more details about the request, like the query parameters that were used, etc.
The network tab is really useful when trying to optimize performance and confirm that requests are happening when they should.
1 Like
I want to know more about this if anyone can help, I am low version too, does upgrading help on performance?
Ok this is introducing something new to my app - excited to see if this improves the metric!
And a quick followup if I may, how “deep down” would you implement this strategy? like, for elements inside the reusable would you also set empty datasource as default or is it sufficient to just do it on the parent reusable level?
Thanks again!
I do, but not many. Only the ones I really need. Any thoughts about plugins I should think about?
You are right!
I acciedntly had the screenshot while the filter was activated for css stuff.
Here are the non filtered ones:
Anything that looks like worth investigating here?
Thanks again!!
I would filter on just xhr/fetch to see just the data requests. Bubble handles optimizing things like scripts and fonts and css files, so you’d rarely need to jump into that yourself (or would be able to change those).
From the waterfall chart, it does look like there’s stuff happening at the 1-2 second mark, and looks like the page loads after one or two things (around the red line), but that largely lines up with what yall had assessed re: reusables making data requests.
Hope this helps!
1 Like
I will try filtering that way. Thanks!
Whatever is the datasource pulling from either bubble db or 3rd party via api. If parent data is empty it doesn’t matter, if it is the parent it matters
1 Like
Be careful don’t use Bubble made front end plugins and don’t ever use bubble native map element, the bubble made plugins causes DOM to load even if everything is invisible, and removing map element on that page will save you 0,1-0,2 secs on fcp