# Island Directive **Isolated Component Rendering** - Render heavy components separately for better performance. ## Overview The `#[Island]` directive enables isolated rendering of LiveComponents, allowing them to be rendered separately from the main template flow. This is particularly useful for resource-intensive components that can slow down page rendering. ## Features - **Isolated Rendering**: Components are rendered separately without template wrapper - **Lazy Loading**: Optional lazy loading when component enters viewport - **Independent Caching**: Islands can have their own caching strategies - **Isolated Events**: Islands don't receive parent component events ## Basic Usage ### Simple Island Component ```php use App\Framework\LiveComponents\Attributes\LiveComponent; use App\Framework\LiveComponents\Attributes\Island; #[LiveComponent('heavy-widget')] #[Island] final readonly class HeavyWidgetComponent implements LiveComponentContract { // Component implementation } ``` ### Lazy Island Component ```php #[LiveComponent('metrics-dashboard')] #[Island(isolated: true, lazy: true, placeholder: 'Loading dashboard...')] final readonly class MetricsDashboardComponent implements LiveComponentContract { // Component implementation } ``` ## Configuration Options ### `isolated` (bool, default: `true`) Whether the component should be rendered in isolation. When `true`, the component is rendered via the `/island` endpoint without template wrapper. ```php #[Island(isolated: true)] // Isolated rendering (default) #[Island(isolated: false)] // Normal rendering (not recommended) ``` ### `lazy` (bool, default: `false`) Whether the component should be lazy-loaded when entering the viewport. When `true`, a placeholder is generated and the component is loaded via IntersectionObserver. ```php #[Island(lazy: true)] // Lazy load on viewport entry #[Island(lazy: false)] // Load immediately (default) ``` ### `placeholder` (string|null, default: `null`) Custom placeholder text shown while the component is loading (only used when `lazy: true`). ```php #[Island(lazy: true, placeholder: 'Loading widget...')] ``` ## Template Usage ### In Templates Island components are used the same way as regular LiveComponents: ```html ``` When processed, lazy Islands generate a placeholder: ```html
Loading widget...
``` ## Island vs. Lazy Component ### Lazy Component (`data-live-component-lazy`) - Loaded when entering viewport - Part of normal template flow - Shares state/events with parent components - Uses `/lazy-load` endpoint ### Island Component (`data-island-component`) - Rendered in isolation (separate request) - No template wrapper (no layout/meta) - Isolated event context (no parent events) - Optional lazy loading on viewport entry - Uses `/island` endpoint ## Performance Benefits ### Isolation Islands reduce template processing overhead for heavy components by rendering them separately. This means: - Heavy components don't block main page rendering - Independent error handling (one island failure doesn't affect others) - Separate caching strategies per island ### Lazy Loading When combined with lazy loading, Islands provide: - Reduced initial page load time - Faster Time to Interactive (TTI) - Better Core Web Vitals scores ### Example Performance Impact ```php // Without Island: 500ms page load (heavy component blocks rendering) // With Island: 200ms page load + 300ms island load (non-blocking) ``` ## Use Cases ### Heavy Widgets ```php #[LiveComponent('analytics-dashboard')] #[Island(isolated: true, lazy: true, placeholder: 'Loading analytics...')] final readonly class AnalyticsDashboardComponent implements LiveComponentContract { // Heavy component with complex data processing } ``` ### Third-Party Integrations ```php #[LiveComponent('external-map')] #[Island(isolated: true, lazy: true)] final readonly class ExternalMapComponent implements LiveComponentContract { // Component that loads external resources } ``` ### Conditional Components ```php #[LiveComponent('admin-panel')] #[Island(isolated: true)] final readonly class AdminPanelComponent implements LiveComponentContract { // Component only visible to admins // Isolated to prevent template processing for non-admin users } ``` ## Technical Details ### Endpoint Islands are rendered via: ``` GET /live-component/{id}/island ``` This endpoint: - Renders component HTML without template wrapper - Returns JSON with `html`, `state`, `csrf_token` - Uses `ComponentRegistry.render()` directly (no wrapper) ### Frontend Integration Islands are automatically detected and handled by `LazyComponentLoader`: - Lazy islands: Loaded when entering viewport - Non-lazy islands: Loaded immediately - Isolated initialization: Islands don't receive parent events ### Event Isolation Islands have isolated event contexts: - No parent component events - No shared state with parent components - Independent SSE channels (if configured) ## Best Practices 1. **Use Islands for Heavy Components**: Only use `#[Island]` for components that significantly impact page load time 2. **Combine with Lazy Loading**: Use `lazy: true` for below-the-fold content 3. **Provide Placeholders**: Always provide meaningful placeholder text for better UX 4. **Test Isolation**: Verify that islands work correctly in isolation 5. **Monitor Performance**: Track island load times and optimize as needed ## Examples ### Complete Example ```php $this->id->toString(), 'metrics' => $this->loadMetrics(), ] ); } private function loadMetrics(): array { // Heavy operation - isolated rendering prevents blocking return [ 'users' => 12345, 'orders' => 6789, 'revenue' => 123456.78, ]; } } ``` ## Migration Guide ### Converting Regular Component to Island 1. Add `#[Island]` attribute to component class 2. Test component rendering (should work identically) 3. Optionally enable lazy loading with `lazy: true` 4. Monitor performance improvements ### Backward Compatibility - Components without `#[Island]` work exactly as before - `#[Island]` is opt-in (no breaking changes) - Existing lazy components continue to work ## Troubleshooting ### Island Not Loading - Check browser console for errors - Verify component is registered in ComponentRegistry - Ensure `/island` endpoint is accessible ### Placeholder Not Showing - Verify `lazy: true` is set - Check `placeholder` parameter is provided - Inspect generated HTML for `data-island-component` attribute ### Events Not Working - Islands have isolated event contexts - Use component-specific events, not parent events - Check SSE channel configuration if using real-time updates ## See Also - [Lazy Loading Guide](livecomponents-lazy-loading.md) - [Component Caching](livecomponents-caching.md) - [Performance Optimization](livecomponents-performance.md)