There are more or less shown 600+ couples of rows that are similar. For a certain condition (depending on the values of the rows) Iām creating a radio button for some couples. Iām ending up with more or less 400 radio buttons. Apart of the fact that the loading of the page is very slow, but every time I click the radio button of a certain couple streamlit reloads the entire page (note that the radio button doesnāt influence the page, so itās reloading exactly the same page) and it takes ~1 minutes for every radio button and this makes this page unuasble for a userā¦
Any suggest on how to avoid this? Code snippet here:
The following may or may not be applicable to your case:
In most cases users do not need to have 600 tables and 400 radio buttons in the same page. Usually they are more confortable dealing with smaller chunks.
~1 min is way too much. The picture of your code suggests that you are repeating a lot of calculations and logic in each rerun. You can store the result and use it in succesive reruns instead.
Widgets inside a form do not trigger a rerun when the user interacts with them.
Yes I know that from an UX point of view itās quite a tragedy. In this page Iām showing, with some criteria before it, all the possible duplicates within a dataset. Usually Iād not expect this amount (400) but in this case theyāre a lot.
I know itās something the user probably wonāt do but Iād like to give him the possibility to choose to keep one row or the other.
The answer is without any doubt yes, but the problem is that I canāt avoid this⦠imagine that Iām in the same state of the page, Iāve to do these computations somewhere and I know the parameters only when the page is shown the first time. How can I prevent a rerun to execute again all the computations if they are coded in the same page that is being rerun?
This could be interesting, but can I store 400 variables in 400 different widgets in 400 different forms? And moreover, how could I encapsulate only the radio button in a form? I wouldnāt like to add also the submit button⦠is this doable?
I already told you. The first time you compute and store the results, next time you use the stored results, no need to compute the same thing again.
I am not aware of any limits in the number of widgets in a form or the number of forms. You can also put the 600 tables and 400 radio buttons inside just one form.
No. But then, what is an user supposed to do? Because, according to your description, just clicking the radio buttons isnāt going to take them anywhere. So they should do something else after that, shouldnāt they?
I already told you. The first time you compute and store the results, next time you use the stored results, no need to compute the same thing again.
Yes, I know that I can do it somewhere else, but the problem is that the expensive computation is for the 99% due to the printing of the rows, that is something I canāt do in advance. So the point is yes, to compute the numbers outside the for and not every time the page reloads would acutally help, but will speed up the time only of 1%
No. But then, what is an user supposed to do? Because, according to your description, just clicking the radio buttons isnāt going to take them anywhere. So they should do something else after that, shouldnāt they?
The idea is to store every radio result in a session_state array and when the page is refreshed I still have all the results and I can apply the transformation I want
I donāt see why you couldnāt also cache the numbers computed inside the for. That might require some refactoring. Unfortunately I canāt provide more specific advice without actual code that I can run.
But does the transformation depend on the radio button? Because if it does, that doesnāt match what you wrote before: āthe radio button doesnāt influence the page, so itās reloading exactly the same pageā.
If the transformation depends on the radio button you only have to apply it when the radio button changes, not on every reload. Again, I canāt be more specific without code that I can run.
I donāt see why you couldnāt also cache the numbers computed inside the for . That might require some refactoring. Unfortunately I canāt provide more specific advice without actual code that I can run.
Maybe the point Iāve missed to tell you is that when I say the āprinting of the rowsā , Iām not meaning the rows āSimilarity of couple ā¦ā but the real records taken from the dataset.Is there a way to cache these writes? Hereās the code:
The writes are done at lines 203 and 215. Without these 2 lines Iād not have any problem in reloading the page but I mandatorily have to print these rows. item[1] and item[0] are rowās indexes.
But does the transformation depend on the radio button? Because if it does, that doesnāt match what you wrote before: āthe radio button doesnāt influence the page, so itās reloading exactly the same pageā.
If the transformation depends on the radio button you only have to apply it when the radio button changes, not on every reload. Again, I canāt be more specific without code that I can run.
Imagine this use case: 600 couples of rows, 600 radio buttons and a session_state array of 600 elements.
Ideally what I want to do is: the user with the radio button choose to drop row1 or row2 or to do not drop anything. (Imagine the radio possibilities are Row1, Row2, None). The user performs this selection for every couple as every case of possible duplicate should be singularly handled.
Now the point is: I donāt want that the row is dropped as soon as the page is refreshed for the pressed radio button, I want all the rows to be dropped later. In order to this I store all the 600 results of the radio buttons in 600 elements of the session state array. So Iāll have this information always avaialable also in the future.
Imagine now the user has finished all the 600 choices and clicks save ā itās here that i can exploit the array and apply the transformation (dropping of the rows).
Thatās pixels, not code. And even if I translated it to code it wouldnāt run.
I wrote code that fits your description the best I could. Using a form avoids the need for caching because clicking the radio buttons does not trigger a rerun.
There is still a noticeable lag when interacting with the radio buttons, which I think is unavoidable with so much stuff to render, but it is only a few seconds, not even close to one minute.
import uuid
def default_selection(couple):
# do something smarter here
return "None"
n_couples = 600
if st.button("Generate couples"):
st.session_state.couples = [
{"code": [uuid.uuid4(), uuid.uuid4()]}
for _ in range(n_couples)
]
if "couples" not in st.session_state:
st.stop()
with st.form(key="form"):
for i, couple in enumerate(st.session_state.couples):
st.dataframe(couple)
key=f"selection_{i}"
st.session_state[key] = default_selection(couple)
st.radio(label="Select", options=["None", "First", "Second"], horizontal=True, key=key)
save_button = st.form_submit_button(label="Save")
I still think this makes a terrible UX and that your efforts would be better spent in improving that.