From a database/ data structure perspective, can someone explain to me why ‘Do a search for’ is so much quicker than referencing a Thing’s list of things?
I would assume the database just needs to refer to the current Thing and retrieve a connected list, where with Search for it searches through everything first.
I built most of my app around the concept of creating one main Thing with al kinds of other Things connected (Users, Invoices etc).
So what I always do in a workflow is add the secondary thing (as a list) to the main Thing. But because retrieving this so slow, I wonder if I should even do this.
The difference is enormous as you can see below.
This search box result retrieves a list of approx 300 items.
Data structure: Job Thing has Inventory Thing which has a List of Inventory Items
Left: Do a search for Inventory items with constraint of 'Inventory is searchbox Job’s Inventory’
Right: Searchbox Job’s Inventory’s Inventory Items
Yeah, it’s part of the core Bubble framework. It’s not going to go to zero any time soon, but it’s definitely shrinkable. We periodically audit the size of the code we’re sending over and cut unnecessary things to keep the size down; we’re probably overdue for another audit (the last one was over a year ago I think!), so I’ve added that to our project list, though no promises on the timing.
I’m talking off the top of my head, so no promises that this is correct, but what I think is going on is that right now to display the list of inventory things, we have to load all 300 items, whereas to do the search, we just need to load enough items to fill the repeating groups cells that are currently visible. We’re working on a project to optimize this (as part of an overhaul of our database query planning engine). Another factor is that we have to load each of the 300 items one-by-one, whereas the search we do as a single database query: we aren’t working on this right now, but it’s on our backlog of projects.
I have one more question: what happens if two workflows concurrently modify the same field of the same object (for instance to increase a number by 1) ?
Do you run workflows in sequences or is it parallelized (multi-threaded) in some way ?
If it is multi-threaded, do you have kind of “locks” that prevent an action from modifying a field if another user is already modifying it ? If so, does it happen at action or workflow level ? (ie, between two actions of the same worfklow, can we assume that all used objects have not been modified by another user ?)
Workflows run from the same web browser session are run in sequence to avoid two workflows modifying the same field (we run them in parallel if it’s safe to do so). Unfortunately, we don’t have good controls / locks for two workflows run by different users or browsers, so you can get issues if two different users try to add one to the same number at the same time. That’s on our to-do list to build, since it would make life easier to be able to offer strong guarantees about what will happen in those cases.
@josh thanks for all the great info in this thread. It has been really helpful.
Is there a simple way to add the loading icon to the blank white page similar to the bubble work environment in the attached photo? It is so much better than users staring at a blank white page and seems like it should be easy to do.
@josh Am I right to assume that the searches used on the page are being updated as the workflows run, so it’s possible for a reference in a workflow to suddenly shift to a different thing mid-workflow?
Like, if I have ReusableElementA in cell 3 of a Repeating Group. The Repeating Group’s list comes from a search for Thing1 that meet certain criteria. If I use a workflow to start making changes to the Thing1row5 of cell 3, and part-way through those changes Thing1row5 no longer matches the criteria of the Repeating Group’s list, then the list will update and a different Thing1 will move up to cell 3. That would mean that the references to “ReusableElementA’s Thing1” would switch mid-workflow.
No, we try to freeze a “state of the universe” at the beginning of a workflow execution, and only reflect changes when the workflow explicitly modifies something. Things like a cell in a repeating group showing a different thing we don’t count as an explicit change. That said, our rules for how exactly that works aren’t great: they’re pretty complicated (I sometimes have to read the actual Bubble source code to predict how a particular situation will play out), and they don’t handle interactions between workflows well (if two different users modify the same data at the same time, the end result might ignore the changes made by one of the users), so this is fairly high on our todo list to overhaul: I’d like to be in a place where we have a clear, easily understandable set of guarantees we can make about how data will behave.
@josh is Bubble smart enough to grab data delivered for another element rather than run the search again?
Like if I have a Repeating Group that loads a list of thing-A, and each thing-A has a field with thing-B, so each cell needs to go get the right thing-B for each cell. Am I right in thinking that the call for each thing-B happens after the list of thing-As is loaded?
But, what if I’ve already delivered a bunch of thing-Bs to another element on the page? Will Bubble know that it doesn’t have to go all the way back to the server to get the thing-B?
Great thread. Our app pulls several images from multiple cameras, and loading each image is a bit slow (.5~1s) but once the image is loaded the first time, it’s cached and loads much faster on subsequent views. How could we cache all of these images for the user when the page is loaded? Would this be a good idea or might it hurt more than help?
Note: if you click the camera name in the slideshow (CAM1/CAM2 etc), I have a popup of all images belonging to that camera. As you can see, once they all download, the slideshow is extremely fast, but only for that camera’s images.
Any other optimization advice would be hugely appreciated, thanks again!
Next to in-app performance enhancements, I’d like to reboot the server location question again. I know the choice of server location is currently not an option in non-dedicated plans, but I really hope you will consider this in the very near future as I’d rather stay on a non-dedicated plan that keeps more money in Bubble’s pocket than to go dedicated.
I’m curious to learn 2 things:
Do the differences in download speed between the Oregon server and the Frankfurt server justify going dedicated?
What are other users experiencing connecting to these servers (what is normal?)
I have a repeating table where I have date field. It’s seem that it’s causing a lot of slowdown on loading. If I remove them, this go a lot faster. I try to remove all other stuff one by one in the page to see impact on loading time, but only date field make a difference. What can I do to solve this?
I have a large array of searches to run. Basically one for each combination of a day and a data point. They’re in a set of nested repeating groups.
All I need to know is that there’s at least one search result. That way I know the condition is satisfied. I don’t care if there is more than one result that satisfies the same condition.
I’d prefer that the system stop searching after it finds a single result. @josh If I build the expression like this
search:first item:convert to list:count
Then will the search stop after it finds one result?