Performance Guide
This guide covers performance optimization strategies for FastHTML apps built with Faststrap.
Static Assets
CDN Mode (Default)
from faststrap import add_bootstrap
add_bootstrap(app)
# Uses jsDelivr CDN for Bootstrap, Bootstrap Icons, and HTMX
CDN mode benefits: - No build step required - Assets cached across sites - Smaller app bundle
Local Mode
Local mode benefits: - Works offline - No external dependencies - Full control over asset versions
Hybrid Mode
from faststrap import add_bootstrap
add_bootstrap(
app,
mode="cdn",
include_js=True, # Include HTMX locally
)
Component Rendering
Use include_js Wisely
from faststrap import add_bootstrap
# Only include JS when needed
add_bootstrap(app, include_js=False) # No JS
add_bootstrap(app, include_js=True) # Full JS bundle
Lazy Load Components
from faststrap import LazyLoad
LazyLoad(
"/api/heavy-component",
target="#heavy-area",
placeholder=Spinner(size="sm"),
)
Caching
Static File Caching
from faststrap import get_assets
assets = get_assets(app)
# Assets are cached with cache-control headers
Response Caching
from fasthtml.common import CacheControl
@app.get("/api/data")
def get_data():
return JsonResponse(data, headers={"Cache-Control": "max-age=300"})
Database Queries
N+1 Prevention
# Bad: N+1 queries
items = db.query(Item).all()
for item in items:
print(item.user.name) # Extra query per item
# Good: Eager loading
items = db.query(Item).options(selectinload(Item.user)).all()
Service Worker (PWA)
from faststrap import PwaMeta
PwaMeta(
name="My App",
short_name="App",
theme_color="#5B6CFF",
background_color="#FFFFFF",
start_url="/",
display="standalone",
)
Service workers cache static assets for offline use and faster loads.
Monitoring
Response Times
import time
@app.before
def log_request_time(req, resp):
start = time.time()
yield
elapsed = time.time() - start
if elapsed > 0.5:
print(f"Slow request: {req.url.path} took {elapsed:.2f}s")
Memory Usage
import tracemalloc
tracemalloc.start()
# ... app code ...
snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics("lineno")
for stat in top_stats[:10]:
print(stat)