4.6 KiB
4.6 KiB
Lazy Loading Implementation Guide
Current Implementation: Simulated Lazy Loading
This example demonstrates the architecture and UX patterns for lazy loading in Yew applications. While it doesn't create separate WASM chunks (which requires advanced build tooling), it shows the complete pattern for implementing lazy loading.
What's Implemented
- Loading States: Proper loading spinners and suspense components
- Async Component Loading: Components load asynchronously with realistic delays
- Route-Based Splitting: Different routes trigger different loading behaviors
- Console Logging: Shows when "chunks" are being loaded
- Visual Feedback: Users see loading states and success indicators
Code Structure
#[function_component(LazyAbout)]
fn lazy_about() -> Html {
let content = use_state(|| None);
use_effect_with((), move |_| {
spawn_local(async move {
// Simulate WASM chunk loading
gloo::console::log!("Loading About WASM chunk...");
gloo::timers::future::TimeoutFuture::new(800).await;
gloo::console::log!("About WASM chunk loaded!");
content.set(Some(html! { <About /> }));
});
});
match (*content).as_ref() {
Some(component) => component.clone(),
None => loading_component(),
}
}
Testing the Implementation
- Open browser dev tools (Console tab)
- Navigate to About or Contact pages
- Observe:
- Loading spinner appears
- Console logs show "Loading X WASM chunk..."
- Page loads after delay
- Success alert confirms lazy loading
True WASM Chunk Splitting
For production applications requiring actual WASM chunk splitting, you would need:
Build Tooling Requirements
- Custom Webpack/Vite Configuration: To split WASM modules
- Dynamic Import Support: Browser support for WASM dynamic imports
- Module Federation: For micro-frontend architectures
- Advanced Bundlers: Tools like
wasm-pack
with splitting support
Implementation Pattern
// Future implementation with true chunk splitting
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_name = "import")]
fn dynamic_import(module: &str) -> js_sys::Promise;
}
async fn load_wasm_chunk(chunk_name: &str) -> Result<JsValue, JsValue> {
let import_path = format!("./{}_chunk.wasm", chunk_name);
let promise = dynamic_import(&import_path);
wasm_bindgen_futures::JsFuture::from(promise).await
}
// Usage in components
#[function_component(TrueLazyAbout)]
fn true_lazy_about() -> Html {
let content = use_state(|| None);
use_effect_with((), move |_| {
spawn_local(async move {
match load_wasm_chunk("about").await {
Ok(module) => {
// Initialize the loaded WASM module
// Render the component from the module
content.set(Some(html! { <About /> }));
}
Err(e) => {
gloo::console::error!("Failed to load chunk:", e);
}
}
});
});
// ... rest of component
}
Network Behavior
With true chunk splitting, you would see:
- Initial page load:
main.wasm
(smaller size) - About page navigation:
about_chunk.wasm
request in Network tab - Contact page navigation:
contact_chunk.wasm
request in Network tab
Current vs Future Comparison
Feature | Current Implementation | True Chunk Splitting |
---|---|---|
Loading UX | ✅ Complete | ✅ Complete |
Suspense Components | ✅ Working | ✅ Working |
Console Logging | ✅ Simulated | ✅ Real |
Network Requests | ❌ None | ✅ Separate chunks |
Bundle Size Reduction | ❌ Simulated | ✅ Real |
Build Complexity | ✅ Simple | ❌ Complex |
Benefits of Current Approach
- Learning: Understand lazy loading patterns without build complexity
- UX Development: Perfect loading states and user experience
- Architecture: Proper component structure for future upgrades
- Testing: Validate user flows and loading behaviors
- Foundation: Ready for true chunk splitting when tooling improves
Migration Path
When WASM chunk splitting tooling becomes more mature:
- Replace simulated delays with real dynamic imports
- Configure build tools for chunk splitting
- Update import paths to actual chunk files
- Test network behavior and performance
- Optimize chunk sizes and loading strategies
This implementation provides the complete foundation for lazy loading while remaining practical for current Yew development workflows.