Hi everyone,
As some of you may know, I’ve been developing my first dash application [https://www.buscafes.com.ar]. It consists on an interactive map of coffee places from my city (Buenos Aires) with the possibility to filter the map by certain features obtained by google places API.
The app is almost finished, there are some ux/ui things I need to improve, but the core of the app is finished. I’m currently deploying it with Azure using the first paid plan, the basic one.
The thing is, I’ve been analyzing the performance of my app with devtools like lighthouse, webpagetest and gtmetrix but there are some stuff I don’t know/understand how to solve. Let me show you some of the information provided by webpagetest on mobile performance:
As you can see, the part that takes most of the time te finish is the layout, which makes sense because I have to render many points of the map, but there are other steps like the bWLwgP.css located on my github assets foulder and the montserrat font (step 16) that delays a little bit the app.
Some other relevant information about app performance:
And let me print some part of my code:
import dash
from dash import dcc, html
from dash.dependencies import Input, Output, State
import dash_leaflet as dl
import pandas as pd
from dash_extensions.javascript import assign
#import dash_bootstrap_components as dbc
import numpy as np
from flask_compress import Compress
import json
import requests
# Crear la aplicación Dash
external_stylesheets = [
#dbc.themes.BOOTSTRAP,
'https://fonts.googleapis.com/css2?family=Montserrat:wght@400;700&display=swap'
]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets,title="Buscafes")
...
# URL of the JSON file
url = url
# Fetch the content from the URL
response = requests.get(url)
# Load the content into a Python dictionary
geojson_data = response.json()
...
#Then, the part of app.layout that render everything
dl.Map(
id='map',
style={'width': '100%', 'height': '100vh', 'max-height': '100vh'},
center=[-34.598, -58.436],
zoomControl=False,
bounds=[[lat_min, lon_min], [lat_max, lon_max]],
zoom=12,
children=[
dl.TileLayer(id="base-layer", url="https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png"),
dl.LocateControl(locateOptions={'enableHighAccuracy': True,'setView': False}, position='topright', showPopup=False),
dl.ZoomControl(position='topright'),
dl.GeoJSON(
id="geojson-layer",
options=dict(
pointToLayer=assign("""
function(feature, latlng){
let iconUrl = feature.properties.iconUrl; // Usa el URL del ícono definido en Python
return L.marker(latlng, {
icon: L.icon({
iconUrl: iconUrl,
iconSize: [18, 27],
iconAnchor: [12, 23],
popupAnchor: [1, -34],
shadowSize: [0, 0]
})
}).bindPopup(feature.properties.popupContent)
.bindTooltip(feature.properties.tooltipContent, {
className: 'marker-tooltip'
});
}
""")
),
zoomToBoundsOnClick=True,
)
...
#then it comes the callbacks, in which the most relevant one (the one that applies the filters is a clientside one)
I’m having a hard time trying to solve those issues. Is there any part of my code that can be improved in order to reduce the time of the app execution? Maybe even paying a better server, idk, or doing some changes in the libraries that I’m importing, or trying to place the .css and google fonts in another place, or changes on the app.layout code or on the external codes, .etc.
I’d really appreciate your help.