Hi all,
I have some performance issues with my dashboard, and I am a bit lost with all the options there are to solve this problem. I have read most of the documentation about performance, advanced callbacks etc. But like I said, I am not sure where to start with this. So I would like to ask a couple of questions, without going too much into detail with my code.
When I run the dash app locally -in this process I also load and read the data from Azure!- it is pretty quick and all is fine. However, when running the same app in a Docker container on Azure, the app is really slow. The same callbacks take around 8-10 times longer. I have a P1v2 app service plan.
At the moment I have an Azure storage container with a pickled csv file (I had some issues with reading csv files in general, but this works fine). This file is only around 5-10MB. So my first question is, what is the best way to load this data in?
From what I understand I have to bypass global variables. Also I want to load the data from Azure only once per session, to prevent traffic and costs. So I did the following: I created a hidden Div and the following callback
html.Div([id="load-data")
dcc.Store(id="store-data", storage_type="memory", data=[])
@callback(
Output("store-data", "data"),
Input("load-data", "children"))
def load_data_page_load(data):
df = blob.read_blob_storage("file.pkl")
return df.to_dict(orient="records")
Read blob storage is the following code:
def read_blob_storage(filename):
blob_client = BlobClient.from_connection_string("endpoint string", fileupload', filename)
downloader = blob_client.download_blob()
blob_file = downloader.readall()
blob_file = pickle.loads(blob_file)
return blob_file
This hidden div is a trick I read on this forum and makes sure the callback is only fired once. The file is stored in a Store component. Again, I have no performance issues offline, so this loads quite fast.
Locally this callback takes less than a second. On Azure this callback takes around 8 seconds.
Then, because I have multiple filters and inputs, I have multiple dcc.Store components (3 of them), which all contain a smaller portion of the dataframe. Is this bad practise? I have tried to think of a way to prevent this, but I have to update the Store multiple times, which isn’t allowed. Does this make the app slow maybe?
So this is high over how the app is designed, but maybe someone can point me in the right direction with this information.
I made sure that callbacks only update the dashboard when necessary and also have used prevent_initial_call=True
for multiple callbacks.
Sorry for the long read and thank you for any tips and tricks!