219 lines
5.7 KiB
Markdown
219 lines
5.7 KiB
Markdown
# Yew Suspense-Based Lazy Loading Implementation
|
|
|
|
## Overview
|
|
|
|
This implementation demonstrates **proper Yew lazy loading** using the `Suspense` component and feature flags, following the official Yew patterns for deferred component loading.
|
|
|
|
## How It Works
|
|
|
|
### 1. Feature Flags for Conditional Compilation
|
|
|
|
```toml
|
|
# Cargo.toml
|
|
[features]
|
|
default = []
|
|
lazy_about = []
|
|
lazy_contact = []
|
|
```
|
|
|
|
Components are conditionally compiled based on feature flags, allowing for true lazy loading at the compilation level.
|
|
|
|
### 2. Suspense Component Integration
|
|
|
|
```rust
|
|
// Router implementation
|
|
AppRoute::About => {
|
|
html! {
|
|
<Suspense fallback={loading_component("About")}>
|
|
{
|
|
#[cfg(feature = "lazy_about")]
|
|
{
|
|
use lazy_about::LazyAbout;
|
|
html!{<LazyAbout/>}
|
|
}
|
|
#[cfg(not(feature = "lazy_about"))]
|
|
{
|
|
html! { <crate::pages::About /> }
|
|
}
|
|
}
|
|
</Suspense>
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Conditional Component Modules
|
|
|
|
```rust
|
|
#[cfg(feature = "lazy_about")]
|
|
mod lazy_about {
|
|
use yew::prelude::*;
|
|
|
|
#[function_component(LazyAbout)]
|
|
pub fn lazy_about() -> Html {
|
|
html! {
|
|
<div>{"I am a lazy loaded component!"}</div>
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Build Commands
|
|
|
|
### Development (All Features Enabled)
|
|
```bash
|
|
# Build with all lazy loading features
|
|
cargo build --features "lazy_about,lazy_contact"
|
|
trunk serve --features "lazy_about,lazy_contact"
|
|
```
|
|
|
|
### Production Builds
|
|
|
|
**Minimal Build (No Lazy Loading)**:
|
|
```bash
|
|
trunk build --release
|
|
# Only home page and fallback components included
|
|
```
|
|
|
|
**Selective Lazy Loading**:
|
|
```bash
|
|
# Include only About page lazy loading
|
|
trunk build --release --features "lazy_about"
|
|
|
|
# Include only Contact page lazy loading
|
|
trunk build --release --features "lazy_contact"
|
|
|
|
# Include both lazy components
|
|
trunk build --release --features "lazy_about,lazy_contact"
|
|
```
|
|
|
|
## Benefits of This Approach
|
|
|
|
### 1. **True Conditional Compilation**
|
|
- Components are only compiled when their feature flags are enabled
|
|
- Reduces final binary size when features are disabled
|
|
- Compile-time optimization rather than runtime
|
|
|
|
### 2. **Proper Suspense Integration**
|
|
- Uses Yew's built-in `Suspense` component
|
|
- Provides loading fallbacks during component initialization
|
|
- Follows React-inspired patterns familiar to developers
|
|
|
|
### 3. **Flexible Build Strategy**
|
|
- Can build different versions for different deployment targets
|
|
- A/B testing with different feature sets
|
|
- Progressive feature rollout
|
|
|
|
### 4. **Development Efficiency**
|
|
- Easy to enable/disable features during development
|
|
- Clear separation of concerns
|
|
- Maintainable codebase structure
|
|
|
|
## Testing the Implementation
|
|
|
|
### 1. **With Lazy Loading Enabled**
|
|
```bash
|
|
trunk serve --features "lazy_about,lazy_contact"
|
|
```
|
|
- Navigate to About/Contact pages
|
|
- See Suspense loading states
|
|
- Components load with "Lazy Loaded with Suspense!" alerts
|
|
|
|
### 2. **Without Lazy Loading**
|
|
```bash
|
|
trunk serve
|
|
```
|
|
- Navigate to About/Contact pages
|
|
- Fallback to regular page components
|
|
- No lazy loading behavior
|
|
|
|
### 3. **Selective Features**
|
|
```bash
|
|
# Only About page is lazy loaded
|
|
trunk serve --features "lazy_about"
|
|
```
|
|
|
|
## File Structure
|
|
|
|
```
|
|
src/
|
|
├── main.rs # Main app with Suspense routing
|
|
├── pages/
|
|
│ ├── home.rs # Always loaded (eager)
|
|
│ ├── about.rs # Fallback component
|
|
│ ├── contact.rs # Fallback component
|
|
│ └── not_found.rs # Always loaded
|
|
└── lazy components defined inline in main.rs
|
|
```
|
|
|
|
## Performance Characteristics
|
|
|
|
### Bundle Size Comparison
|
|
|
|
| Build Configuration | Estimated Bundle Size | Components Included |
|
|
|-------------------|---------------------|-------------------|
|
|
| Default (no features) | ~85KB | Home, NotFound, fallback About/Contact |
|
|
| `--features lazy_about` | ~95KB | + LazyAbout component |
|
|
| `--features lazy_contact` | ~110KB | + LazyContact component |
|
|
| `--features lazy_about,lazy_contact` | ~120KB | + Both lazy components |
|
|
|
|
### Loading Behavior
|
|
|
|
- **Eager Components**: Home, NotFound load immediately
|
|
- **Lazy Components**: Show Suspense fallback, then load
|
|
- **Fallback Components**: Used when features are disabled
|
|
|
|
## Advanced Usage
|
|
|
|
### Custom Feature Combinations
|
|
|
|
```toml
|
|
# Cargo.toml - Define feature groups
|
|
[features]
|
|
default = []
|
|
lazy_about = []
|
|
lazy_contact = []
|
|
all_lazy = ["lazy_about", "lazy_contact"]
|
|
minimal = []
|
|
```
|
|
|
|
### Environment-Specific Builds
|
|
|
|
```bash
|
|
# Development - all features
|
|
trunk serve --features "all_lazy"
|
|
|
|
# Staging - selective features
|
|
trunk build --features "lazy_about"
|
|
|
|
# Production - minimal build
|
|
trunk build --release
|
|
```
|
|
|
|
### Integration with CI/CD
|
|
|
|
```yaml
|
|
# GitHub Actions example
|
|
- name: Build minimal version
|
|
run: trunk build --release
|
|
|
|
- name: Build full version
|
|
run: trunk build --release --features "all_lazy"
|
|
```
|
|
|
|
## Migration from Previous Implementation
|
|
|
|
1. **Remove simulation code**: No more `gloo::timers` delays
|
|
2. **Add feature flags**: Define in Cargo.toml
|
|
3. **Wrap in Suspense**: Use proper Yew Suspense components
|
|
4. **Conditional compilation**: Use `#[cfg(feature = "...")]`
|
|
5. **Update build commands**: Include feature flags
|
|
|
|
## Best Practices
|
|
|
|
1. **Feature Naming**: Use descriptive feature names (`lazy_about` vs `about`)
|
|
2. **Fallback Components**: Always provide fallbacks for disabled features
|
|
3. **Loading States**: Design meaningful loading components
|
|
4. **Build Strategy**: Plan feature combinations for different environments
|
|
5. **Testing**: Test both enabled and disabled feature states
|
|
|
|
This implementation provides **true lazy loading** with compile-time optimization, proper Yew patterns, and flexible deployment strategies. |