🌀
Streamlitのst.spinnerで長時間の処理を行った際に画面全体がフェードしてしまう現象
はじめに
Streamlitで生成AIアプリを作成した際に、表題の事象に遭遇しました。いまだに完全にはなぜこれが起こるのか理解できていないですが、解決策は見つかったのでメモしておきます。
環境
Windows
Python 3.12.0
streamlit==1.41.0
現象
import time
import streamlit as st
def render_sidebar():
with st.sidebar:
st.text_input("あなたの名前は?", key="name")
def render_main_fade_all():
if st.session_state.name is not None:
st.markdown("# Title")
st.markdown("ここもフェードします。")
def recommend_dinner():
with st.spinner("処理中です。"):
time.sleep(5)
st.write(
f"{st.session_state.name}さんへのおすすめの晩御飯を考えました!"
)
st.markdown("- ココ壱番屋\n - 丸亀うどん\n - オリジン弁当")
st.button("実行", on_click=recommend_dinner)
if __name__ == "__main__":
render_sidebar()
render_main_fade_all()
以下のように、st.spinner内での処理実行中に、コードではst.spinnerの外にある部分の描画も中断され、画面全体が白くフェードしてしまいます。
ユーザ観点からすると、フリーズしてしまったかのような印象を受けるため、UI的にも問題になりえます。
解決方法
import time
import streamlit as st
def render_sidebar():
with st.sidebar:
st.text_input("あなたの名前は?", key="name")
def render_main():
if st.session_state.name is not None:
st.markdown("# Title")
st.markdown("ここはフェードしないです。")
if st.button("実行"):
with st.spinner("処理中です。"):
time.sleep(5)
st.write(
f"{st.session_state.name}さんへのおすすめの晩御飯を考えました!"
)
st.markdown("- ココ壱番屋\n - 丸亀うどん\n - オリジン弁当")
if __name__ == "__main__":
render_sidebar()
render_main()
st.spinnerの処理を、st.buttonのon_clickコールバックに含めないようにすることで、画面の一部のみがフェードする挙動となります。
on_clickが実行される際に、画面全体が再描画されるのですが、その途中にst.spinnerが挟まることで、全体が処理中のようにフェードしてしまうということのようですが、背後の仕組みは完全には理解しきれていません。
Discussion