import React, { useState, useCallback, Suspense } from 'react'; import { Card, Typography, Space, Button, Divider } from 'antd'; import { UserAddOutlined, CalendarOutlined, FlagOutlined, TagOutlined, LoadingOutlined } from '@ant-design/icons'; const { Title, Text } = Typography; // Simulate heavy components that would normally load immediately const HeavyAssigneeSelector = React.lazy(() => new Promise<{ default: React.ComponentType }>((resolve) => setTimeout(() => resolve({ default: () => (
🚀 Heavy Assignee Selector Loaded!
This component contains:
) }), 1000) // Simulate 1s load time ) ); const HeavyDatePicker = React.lazy(() => new Promise<{ default: React.ComponentType }>((resolve) => setTimeout(() => resolve({ default: () => (
📅 Heavy Date Picker Loaded!
This component contains:
) }), 800) // Simulate 0.8s load time ) ); const HeavyPrioritySelector = React.lazy(() => new Promise<{ default: React.ComponentType }>((resolve) => setTimeout(() => resolve({ default: () => (
🔥 Heavy Priority Selector Loaded!
This component contains:
) }), 600) // Simulate 0.6s load time ) ); const HeavyLabelsSelector = React.lazy(() => new Promise<{ default: React.ComponentType }>((resolve) => setTimeout(() => resolve({ default: () => (
🏷️ Heavy Labels Selector Loaded!
This component contains:
) }), 700) // Simulate 0.7s load time ) ); // Lightweight placeholder buttons (what loads immediately) const PlaceholderButton: React.FC<{ icon: React.ReactNode; label: string; onClick: () => void; loaded?: boolean; }> = ({ icon, label, onClick, loaded = false }) => ( ); const AsanaStyleLazyDemo: React.FC = () => { const [loadedComponents, setLoadedComponents] = useState<{ assignee: boolean; date: boolean; priority: boolean; labels: boolean; }>({ assignee: false, date: false, priority: false, labels: false, }); const [showComponents, setShowComponents] = useState<{ assignee: boolean; date: boolean; priority: boolean; labels: boolean; }>({ assignee: false, date: false, priority: false, labels: false, }); const handleLoad = useCallback((component: keyof typeof loadedComponents) => { setLoadedComponents(prev => ({ ...prev, [component]: true })); setTimeout(() => { setShowComponents(prev => ({ ...prev, [component]: true })); }, 100); }, []); const resetDemo = useCallback(() => { setLoadedComponents({ assignee: false, date: false, priority: false, labels: false, }); setShowComponents({ assignee: false, date: false, priority: false, labels: false, }); }, []); return ( 🎯 Asana-Style Lazy Loading Demo
Performance Benefits:
Task Management Components (Click to Load):
} label="Add Assignee" onClick={() => handleLoad('assignee')} loaded={loadedComponents.assignee && !showComponents.assignee} /> } label="Set Date" onClick={() => handleLoad('date')} loaded={loadedComponents.date && !showComponents.date} /> } label="Set Priority" onClick={() => handleLoad('priority')} loaded={loadedComponents.priority && !showComponents.priority} /> } label="Add Labels" onClick={() => handleLoad('labels')} loaded={loadedComponents.labels && !showComponents.labels} />
Components loaded: {Object.values(showComponents).filter(Boolean).length}/4
{showComponents.assignee && ( Loading assignee selector...
}> )} {showComponents.date && ( Loading date picker...
}> )} {showComponents.priority && ( Loading priority selector...}> )} {showComponents.labels && ( Loading labels selector...}> )}
How it works:
  1. 1. Page loads instantly with lightweight placeholder buttons
  2. 2. User clicks a button to interact with a feature
  3. 3. Heavy component starts loading in the background
  4. 4. Loading state shows immediate feedback
  5. 5. Full component renders when ready
  6. 6. Subsequent interactions are instant (component cached)
); }; export default AsanaStyleLazyDemo;