4.4 KiB
4.4 KiB
Yew WASM Website Architecture
Overview
This example demonstrates a minimal Yew WASM application optimized for small binary size and fast loading through lazy loading strategies. The architecture prioritizes performance and modularity.
System Architecture
graph TD
A[Browser] --> B[Main App Component]
B --> C[Router]
C --> D[Route Matcher]
D --> E[Lazy Loader]
E --> F[Home Component]
E --> G[About Component]
E --> H[Contact Component]
I[Trunk Build] --> J[WASM Bundle]
I --> K[Static Assets]
J --> L[Optimized Binary]
M[Code Splitting] --> N[Route Chunks]
N --> O[Dynamic Imports]
Core Components
1. App Component (src/app.rs
)
- Root component managing application state
- Handles routing initialization
- Minimal initial bundle size
2. Router (src/router.rs
)
- Route definitions using
yew-router
- Lazy loading configuration
- Dynamic component imports
3. Page Components (src/pages/
)
- Home - Landing page (eagerly loaded)
- About - Information page (lazy loaded)
- Contact - Contact form (lazy loaded)
Lazy Loading Strategy
Route-Based Code Splitting
// Only load components when routes are accessed
match route {
AppRoute::Home => html! { <Home /> },
AppRoute::About => {
// Lazy load About component
spawn_local(async {
let component = import_about_component().await;
// Render when loaded
});
}
}
Benefits
- Reduced initial bundle size
- Faster first paint
- Progressive loading based on user navigation
File Structure
examples/website/
├── Cargo.toml # Dependencies and build config
├── Trunk.toml # Trunk build configuration
├── index.html # HTML template
├── src/
│ ├── main.rs # Application entry point
│ ├── app.rs # Root App component
│ ├── router.rs # Route definitions
│ └── pages/
│ ├── mod.rs # Page module exports
│ ├── home.rs # Home page component
│ ├── about.rs # About page component
│ └── contact.rs # Contact page component
└── static/ # Static assets (CSS, images)
Binary Size Optimizations
Cargo.toml Configuration
[profile.release]
opt-level = "s" # Optimize for size
lto = true # Link-time optimization
codegen-units = 1 # Single codegen unit
panic = "abort" # Smaller panic handling
[dependencies]
yew = { version = "0.21", features = ["csr"] }
yew-router = "0.18"
wasm-bindgen = "0.2"
Trunk.toml Configuration
[build]
target = "index.html"
[serve]
address = "127.0.0.1"
port = 8080
[tools]
wasm-opt = ["-Os"] # Optimize WASM for size
Additional Optimizations
- Use
web-sys
selectively (only needed APIs) - Minimize external dependencies
- Tree-shaking through proper imports
- Compress static assets
Build Process
-
Development:
trunk serve
- Hot reload enabled
- Debug symbols included
- Fast compilation
-
Production:
trunk build --release
- Size optimizations applied
- WASM-opt processing
- Asset compression
Performance Targets
- Initial Bundle: < 100KB (gzipped)
- First Paint: < 1s on 3G
- Route Transition: < 200ms
- Total App Size: < 500KB (all routes loaded)
Implementation Notes
Lazy Loading Pattern
use yew::prelude::*;
use yew_router::prelude::*;
#[function_component(App)]
pub fn app() -> Html {
html! {
<BrowserRouter>
<Switch<Route> render={switch} />
</BrowserRouter>
}
}
fn switch(routes: Route) -> Html {
match routes {
Route::Home => html! { <Home /> },
Route::About => html! { <Suspense fallback={loading()}><About /></Suspense> },
}
}
Component Splitting
- Each page component in separate file
- Use
#[function_component]
for minimal overhead - Avoid heavy dependencies in lazy-loaded components
Next Steps
- Implement basic routing structure
- Add lazy loading for non-critical routes
- Configure build optimizations
- Measure and optimize bundle sizes
- Add performance monitoring
This architecture provides a solid foundation for a fast, efficient Yew WASM application with room for growth while maintaining optimal performance characteristics.