Hi everyone,
I tried creating a multi page panel app that is hosted inside a single pn.Column(). The structure is as follows:
app.py:
1 import panel as pn
2
3 from src.presentation.navigation.NavState import nav_state
4 from src.presentation.navigation.Screens import screens
5
6
7
8 def get_screen(page_key):
9 print(f"Show Screen {page_key}")
10
11 return screenspage_key
12
13 content = pn.bind(get_screen, nav_state)
14
15 #pn.Column(content).servable()
16 pn.serve(pn.Column(content))
NavState.py:
1 import param
2
3 nav_state = param.rx(“Home”)
Screens.py:
1 from src.presentation.screen.HomeScreen import HomeScreen
2 from src.presentation.screen.OtherScreen import OtherScreen
3
4 screens = {
5 “Home”: HomeScreen,
6 “Other”: OtherScreen
7 }
HomeScreen.py:
1 from panel.viewable import Viewer, Viewable
2 import panel as pn
3
4 from src.presentation.component.TopBar import TopBar
5 from src.presentation.navigation.NavState import nav_state
6
7
8 class HomeScreen(Viewer):
9
10 def init(self, **params):
11 super().init(**params)
12 def navigate(self, event):
13 nav_state.rx.value = “Other”
14
15 def panel(self) → Viewable:
16 return pn.Column(
17 “# Home Screen”,
18 pn.widgets.Button(
19 name=“Go to other screen”,
20 on_click=self.navigate
21 ),
22 sizing_mode=“stretch_both”
23 )
OtherScreen.py:
Looks the same as HomeScreen.py just with a different class name and it sets nav_state.rx.value = “Home” instead of “Other”.
The Problem
When starting the app by running the app.py file
python app.py
The app starts as expected. I can navigate between the two screens, for every time I navigate the print statement (line 9 in app.py) is fired once.
When I now change the app.py from ending with
pn.serve(pn.Column(content))
to
pn.Column(content).servable()
and start the app using
panel serve app.py
the app still works and navigates correctly. However, now the print statement (line 9 in app.py) is fired one additional time for every time I reload the webpage. I want to prevent this, as re-drawing the screens multiple times will negatively impact user experience when the screens get more complex and drawing them takes more time.
The code provided here is a small excerpt and simplification of a larger app we are working on. In this app we are actually experiencing this problem right from the beginning when starting the app using panel serve instead of pn.serve(). Here the screens are drawn twice when first loading the app and then an additional two times for every time the user reloads the web page.
My specific question: It seems I don’t fully understand how the application is served to the user. Can someone please point me to relevant resources and/or explain, why our app behaves this way? Thanks in advance!