How to run faster an Streamlit app

I am running an app with Streamlit and it is relatively slow.
My code is generally as follows. I use a selectbox (or more) then i query my database based on the selectbox input (by users).
I repeat this schema many times in program…

My database is large, and my program is very slow when i change the input of one of my (many) selectbox options. I suppose that is because Streamlit run my entire program each time i change an option.

How can I get something that is faster?
Should I use all the query in a function with @st.cache_data ? (so i need to change a little bit my approach)
Or are there other ways to proceed with Streamlit ?

I hope my question was clear enough to get replies

This is a snapchat of my program:

    cols = st.columns(2)

    # Choix du fonds
    fonds = cols[0].selectbox(
        "Choix du fonds",
        df_fonds
        .query("classif_amf_fonds=='Fonds de fonds' or classif_amf_fonds=='Fonds diversifié'")
        ["nom_fonds"]
        .sort_values()
        .unique()
        )

    # Date du fonds à analyser
    date = cols[1].date_input(
        "Date du fonds",
        value=df_inventaire.query("id_fonds_main==@id")["date_vl"].max(),
        min_value=df_inventaire.query("id_fonds_main==@id")["date_vl"].min(),
        max_value=df_inventaire.query("id_fonds_main==@id")["date_vl"].max(),
        format="DD/MM/YYYY",
        )
  
  df = df.query("date==@date and fonds==@fonds")
etc...

Hey @Jacques2101, yeah I think using @st.cache_data is usually a good approach to avoid executing queries multiple times (note that a Streamlit app always runs top to bottom when interacting with one of the widgets).
Other directives to look into are st.form, which only triggers a re-run for the enclosed widgets when clicking on the submit button or st.fragment, which will lead to only rerun the decorated function when interacting with an enclosed widget. These two commands might require for you to rewrite the app slightly.

A Streamlit-independent (additional) approach would be to create a view on your database with only the relevant data and leverage that in your application; this might be a good idea anyways but of course depends on your overall setup and requirements :slightly_smiling_face:

1 Like