5.7 KiB
5.7 KiB
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
# 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
// 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
#[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)
# 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):
trunk build --release
# Only home page and fallback components included
Selective Lazy Loading:
# 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
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
trunk serve
- Navigate to About/Contact pages
- Fallback to regular page components
- No lazy loading behavior
3. Selective Features
# 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
# Cargo.toml - Define feature groups
[features]
default = []
lazy_about = []
lazy_contact = []
all_lazy = ["lazy_about", "lazy_contact"]
minimal = []
Environment-Specific Builds
# 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
# 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
- Remove simulation code: No more
gloo::timers
delays - Add feature flags: Define in Cargo.toml
- Wrap in Suspense: Use proper Yew Suspense components
- Conditional compilation: Use
#[cfg(feature = "...")]
- Update build commands: Include feature flags
Best Practices
- Feature Naming: Use descriptive feature names (
lazy_about
vsabout
) - Fallback Components: Always provide fallbacks for disabled features
- Loading States: Design meaningful loading components
- Build Strategy: Plan feature combinations for different environments
- 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.