Pages slower than Tabs? Cache whole pages/tabs?

I have some models, vector DBs and other data I store using cache_resource and cache_data in session_states. (Caching across pages in Multipage App - #3 by blackary)
I initially built an app all in tabs where each tab interacts with different aspects of data while leveraging forms and session_states.
I created a first_run session state to auto run through sections in the tabs when the app is first spun up.

In this way I’ve kept the portions of my app that I can from needing to reload.

My app got larger and I have built out a new structure using pages (v1).
My pages leverage a navigation page which builds the sidebar. (New login page navigation example with streamlit 1.31)
I believed pagination would be quicker than tabs as my impression was only the current page would need to reload.
Currently my page is running even slower on a single page than the tab version was for the entire app.
Can I cache the entire page so that it can reload as quickly as possible when a user changes pages and comes back to the same page? (Page contains 3 different forms, a dataframe and a plotly chart.)
alternatively can I cache whole tabs with forms etc. within them?
At this point I am thinking I may just need to swap to flask but sunk cost fallacy.

Changing tabs does not run any of your code so it is faster than changing pages.

You cannot “cache the entire page” but you can cache every object used in your code.

So what I’m gathering is best case is disappointing one way or the other:

Tab advantage is swapping between them = no load.
Tab disadvantage is change 1 thing outside a form = reload everything.
(additionally is tough to indicate to users that other tabs are still loading)

Page advantage is change 1 thing outside a form = reload just the page.
Page disadvantage is swapping between them = always reloads…

As @Goyo said, you should be able to get good performance on a page by caching heavily. There’s not really anything to stop you from wrapping a large part of your app in a function and putting @st.cache_data on it. Alternatively, you can take individual parts of the code and put them in functions with @st.cache_data in them.

You can also put common data into functions in a separate module and cache those, and use those cached functions across different pages if you’re doing some of the same computation across different pages.

There’s no reason that “3 forms, a dataframe, and a plotly chart” must be slow – a lot of it comes down to how much work is actually being done on a given page to generate those. This might be a case where moving some of the work outside of Streamlit could be a big win How to improve Streamlit app loading speed.

Added cache_data to the few charts/processing functions that weren’t already.

And don’t want to cache widget values.
" Using widgets in cached functions is extremely powerful because it lets you cache entire parts of your app. But it can be dangerous! Since Streamlit treats the widget value as an additional input parameter, it can easily lead to excessive memory usage. Imagine your cached function has five sliders and returns a 100 MB DataFrame. Then we’ll add 100 MB to the cache for every permutation of these five slider values – even if the sliders do not influence the returned data! These additions can make your cache explode very quickly. Please be aware of this limitation if you use widgets in cached functions. We recommend using this feature only for isolated parts of your UI where the widgets directly influence the cached return value."

There is no work to move outside of Streamlit, the data is already as prepped as possible. It is a data exploration tool, so it takes a lot of user input/filters etc. from multiple pages and allows users to join them/other python functions in the background for non-python users.

Rather than cache things leveraging widgets, a workaround might be setting a session state and when I return to a page that has already run, skip running those non-cached widget elements. And just use the data already in session state.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.