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:
- Team member search logic
- Avatar rendering
- Permission checking
- Socket connections
- Optimistic updates
)
}), 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:
- Calendar rendering logic
- Date validation
- Timezone handling
- Locale support
- Accessibility features
)
}), 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:
- Priority level logic
- Color calculations
- Business rules
- Validation
- State management
)
}), 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:
- Label management
- Color picker
- Search functionality
- CRUD operations
- Drag & drop
)
}), 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 }) => (
: icon}
onClick={onClick}
className={`${loaded ? 'border-blue-500 bg-blue-50' : ''}`}
>
{loaded ? 'Loading...' : label}
);
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:
- ✅ Faster Initial Load: Only lightweight placeholders load initially
- ✅ Reduced Bundle Size: Heavy components split into separate chunks
- ✅ Better UX: Instant visual feedback, components load on demand
- ✅ Memory Efficient: Components only consume memory when needed
- ✅ Network Optimized: Parallel loading of components as user interacts
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. Page loads instantly with lightweight placeholder buttons
- 2. User clicks a button to interact with a feature
- 3. Heavy component starts loading in the background
- 4. Loading state shows immediate feedback
- 5. Full component renders when ready
- 6. Subsequent interactions are instant (component cached)
);
};
export default AsanaStyleLazyDemo;