first commit
This commit is contained in:
137
examples/website/LAZY_LOADING.md
Normal file
137
examples/website/LAZY_LOADING.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# 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
|
||||
|
||||
1. **Loading States**: Proper loading spinners and suspense components
|
||||
2. **Async Component Loading**: Components load asynchronously with realistic delays
|
||||
3. **Route-Based Splitting**: Different routes trigger different loading behaviors
|
||||
4. **Console Logging**: Shows when "chunks" are being loaded
|
||||
5. **Visual Feedback**: Users see loading states and success indicators
|
||||
|
||||
### Code Structure
|
||||
|
||||
```rust
|
||||
#[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
|
||||
|
||||
1. Open browser dev tools (Console tab)
|
||||
2. Navigate to About or Contact pages
|
||||
3. 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
|
||||
|
||||
1. **Custom Webpack/Vite Configuration**: To split WASM modules
|
||||
2. **Dynamic Import Support**: Browser support for WASM dynamic imports
|
||||
3. **Module Federation**: For micro-frontend architectures
|
||||
4. **Advanced Bundlers**: Tools like `wasm-pack` with splitting support
|
||||
|
||||
### Implementation Pattern
|
||||
|
||||
```rust
|
||||
// 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
|
||||
|
||||
1. **Learning**: Understand lazy loading patterns without build complexity
|
||||
2. **UX Development**: Perfect loading states and user experience
|
||||
3. **Architecture**: Proper component structure for future upgrades
|
||||
4. **Testing**: Validate user flows and loading behaviors
|
||||
5. **Foundation**: Ready for true chunk splitting when tooling improves
|
||||
|
||||
## Migration Path
|
||||
|
||||
When WASM chunk splitting tooling becomes more mature:
|
||||
|
||||
1. Replace simulated delays with real dynamic imports
|
||||
2. Configure build tools for chunk splitting
|
||||
3. Update import paths to actual chunk files
|
||||
4. Test network behavior and performance
|
||||
5. Optimize chunk sizes and loading strategies
|
||||
|
||||
This implementation provides the complete foundation for lazy loading while remaining practical for current Yew development workflows.
|
Reference in New Issue
Block a user