176 lines
4.4 KiB
Markdown
176 lines
4.4 KiB
Markdown
# 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
|
|
|
|
```mermaid
|
|
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
|
|
```rust
|
|
// 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
|
|
```toml
|
|
[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
|
|
```toml
|
|
[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
|
|
|
|
1. **Development**: `trunk serve`
|
|
- Hot reload enabled
|
|
- Debug symbols included
|
|
- Fast compilation
|
|
|
|
2. **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
|
|
```rust
|
|
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
|
|
|
|
1. Implement basic routing structure
|
|
2. Add lazy loading for non-critical routes
|
|
3. Configure build optimizations
|
|
4. Measure and optimize bundle sizes
|
|
5. 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. |