Using cache with dataframes and "static st commands"

Summary

I’m following up on an announcement from release v1.12, which states… functions cached with st.experimental_memo or st.experimental_singleton can now contain static st commands. This allows caching text, charts, dataframes, and more!

Prior to v1.12, I used @st.experimental_memo to cache dataframes results. And I believe it worked as expected. However, I would like to understand how v1.12 improves performance and/or more specifically how I can cache charts to improve performance. Here’s an example to use for discussion:

Steps to reproduce

Code snippet:

import pandas as pd
import streamlit as st

df = pd.DataFrame({'a':[2,2], 'b': [3,4]})

@st.experimental_memo()
def cfunc(df):
    print('not cached')

st.button('Run function', on_click=cfunc, args=(df,))

Clicking the button only prints “not cached” to the console once–which is the actual / expected behavior pre-v1.12.

If I modify the code with an st.write command as follows:

import pandas as pd
import streamlit as st

df = pd.DataFrame({'a':[2,2], 'b': [3,4]})

st.header('Page Title')

@st.experimental_memo()
def cfunc(df):
    st.write('not cached')
    print('not cached')

st.button('Run function', on_click=cfunc, args=(df,))

st.write('not cached') writes to the page every time I click the button, but print('not cached') still only prints to the console once.

So I’m wondering

Is this what was meant by “cached functions can now contain static st commands”? Are there other applications of this upgraded version that I’m missing? Elaboration here would help me maximize the UX of my data app. Thanks.

Using a static st command within a cached function previously meant that the st command would only execute on a cache miss. As you noticed, in version 1.12.0, the static st command executes on every run rather than only on a cache miss.