Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
232 changes: 232 additions & 0 deletions PLUGIN_EXTRACTION_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
# Plugin Extraction Summary

## Overview

This document summarizes the work done to extract heavy components from `@object-ui/components` into separate lazy-loaded plugin packages, following the principle of "基于插件体系重新思考哪些控件应该放在插件中" (Rethink which components should be placed in plugins based on the plugin system).

## Changes Made

### 1. Created `@object-ui/plugin-markdown` Package

**Purpose:** Extract markdown rendering functionality to reduce bundle size

**Features:**
- Lazy-loaded markdown renderer using React.lazy() and Suspense
- GitHub Flavored Markdown support (tables, task lists, strikethrough)
- XSS protection via rehype-sanitize
- Full Tailwind prose styling

**Dependencies Moved:**
- `react-markdown@^10.1.0`
- `remark-gfm@^4.0.1`
- `rehype-sanitize@^6.0.0`

**Bundle Impact:**
- Initial load: +0.19 KB
- Lazy chunk: ~262 KB (66 KB gzipped)
- Only loads when markdown component is rendered

**Files:**
- `packages/plugin-markdown/src/index.tsx` - Main entry with lazy loading
- `packages/plugin-markdown/src/MarkdownImpl.tsx` - Heavy implementation
- `packages/plugin-markdown/src/types.ts` - TypeScript definitions
- `packages/plugin-markdown/README.md` - Documentation

### 2. Created `@object-ui/plugin-kanban` Package

**Purpose:** Extract kanban board functionality to reduce bundle size

**Features:**
- Lazy-loaded kanban board using React.lazy() and Suspense
- Drag-and-drop powered by @dnd-kit
- Column limits and card badges
- Full keyboard navigation support

**Dependencies Moved:**
- `@dnd-kit/core@^6.3.1`
- `@dnd-kit/sortable@^8.0.0`
- `@dnd-kit/utilities@^3.2.2`

**Bundle Impact:**
- Initial load: +0.19 KB
- Lazy chunk: ~79 KB (21 KB gzipped)
- Only loads when kanban component is rendered

**Files:**
- `packages/plugin-kanban/src/index.tsx` - Main entry with lazy loading
- `packages/plugin-kanban/src/KanbanImpl.tsx` - Heavy implementation
- `packages/plugin-kanban/src/types.ts` - TypeScript definitions
- `packages/plugin-kanban/README.md` - Documentation

### 3. Enhanced `@object-ui/plugin-charts` Package

**Purpose:** Consolidate all chart functionality in one plugin

**New Features:**
- Added advanced chart renderer with multiple types (bar, line, area)
- Support for complex configurations with ChartContainer
- Series-based data rendering
- Merged chart.tsx from components package

**Bundle Impact:**
- Initial load: +0.22 KB
- Simple bar chart chunk: ~5 KB (2 KB gzipped)
- Advanced chart chunk: ~49 KB (11 KB gzipped)
- Recharts library chunk: ~538 KB (135 KB gzipped)

**Files Added:**
- `packages/plugin-charts/src/AdvancedChartImpl.tsx` - Advanced chart types
- `packages/plugin-charts/src/ChartContainerImpl.tsx` - Chart container utilities

### 4. Cleaned Up `@object-ui/components` Package

**Removed Files:**
- `src/renderers/data-display/chart.tsx`
- `src/renderers/data-display/markdown.tsx`
- `src/renderers/complex/kanban.tsx`
- `src/ui/chart.tsx`
- `src/ui/markdown.tsx`
- `src/ui/kanban.tsx`

**Dependencies Removed:**
- `react-markdown@^10.1.0` (~100-200 KB)
- `remark-gfm@^4.0.1`
- `rehype-sanitize@^6.0.0`
- `recharts@^3.6.0` (~541 KB minified)
- `@dnd-kit/core@^6.3.1` (~100-150 KB)
- `@dnd-kit/sortable@^8.0.0`
- `@dnd-kit/utilities@^3.2.2`

**Total Size Reduction:** ~900 KB - 1 MB from the main components bundle

### 5. Updated Playground Application

**Changes:**
- Added plugin imports in `App.tsx`
- Updated `package.json` with new plugin dependencies
- Created demo examples:
- `markdown-demo.json` - Comprehensive markdown showcase
- `kanban-demo.json` - Full-featured kanban board
- Updated `plugins-showcase.json` to include all plugins

## Benefits

### 1. Reduced Initial Bundle Size
The main `@object-ui/components` package is now ~900 KB - 1 MB lighter, resulting in faster initial page loads.

### 2. Better Code Splitting
Each plugin is loaded on-demand, only when its components are actually rendered in the UI.

### 3. Improved Performance
Users who don't use markdown, kanban, or charts don't pay the cost of downloading those libraries.

### 4. Better Modularity
Each plugin is self-contained with its own:
- Dependencies
- Type definitions
- Documentation
- Build configuration

### 5. Easier Maintenance
Heavy dependencies are isolated in specific packages, making it easier to:
- Update individual plugins
- Add new plugins
- Remove unused plugins

## Architecture Principles Followed

### 1. Internal Lazy Loading ✅
Each plugin handles lazy loading internally using React.lazy() and Suspense, so users don't need to wrap components in Suspense themselves.

### 2. Automatic Registration ✅
Plugins auto-register with ComponentRegistry on import, making them immediately available for use.

### 3. Type Safety ✅
Each plugin exports its own TypeScript types for schema definitions.

### 4. Zero Configuration ✅
Just import the plugin and start using it in schemas - no additional setup required.

### 5. Tailwind Native ✅
All plugins follow the Tailwind-first approach with className support.

## Usage Examples

### Import Plugins
```typescript
// In your app entry point
import '@object-ui/plugin-markdown';
import '@object-ui/plugin-kanban';
import '@object-ui/plugin-charts';
```

### Use in Schemas
```typescript
// Markdown
const markdownSchema = {
type: 'markdown',
content: '# Hello World\n\nThis is **markdown**!'
};

// Kanban
const kanbanSchema = {
type: 'kanban',
columns: [
{ id: 'todo', title: 'To Do', cards: [...] }
]
};

// Chart
const chartSchema = {
type: 'chart',
chartType: 'bar',
data: [...],
series: [...]
};
```

## Bundle Size Comparison

### Before (All in @object-ui/components)
- Main bundle: ~1,343 KB (308 KB gzipped)
- Everything loaded on initial page load

### After (Plugins Extracted)
- Main bundle: ~450 KB estimated (estimated 150 KB gzipped)
- Markdown plugin: Lazy loaded (~66 KB gzipped when used)
- Kanban plugin: Lazy loaded (~21 KB gzipped when used)
- Charts plugin: Lazy loaded (~135 KB gzipped when used)

**Result:** ~50% reduction in initial bundle size for applications that don't use all features on every page.

## Testing

### Build Status
All packages build successfully:
- ✅ @object-ui/plugin-markdown
- ✅ @object-ui/plugin-kanban
- ✅ @object-ui/plugin-charts
- ✅ @object-ui/components (with reduced size)
- ✅ Playground application

### Demo Examples Created
- ✅ markdown-demo.json - Comprehensive markdown showcase
- ✅ kanban-demo.json - Full project management board
- ✅ plugins-showcase.json - All plugins in one demo

## Future Improvements

1. **Add More Plugins:** Consider extracting other heavy components like:
- Rich text editor components
- Advanced data tables with virtualization
- Complex visualization components

2. **Plugin Marketplace:** Create a registry for third-party plugins

3. **Performance Monitoring:** Add bundle size tracking in CI/CD

4. **Plugin Templates:** Create scaffolding tools for new plugins

## Conclusion

This refactoring successfully implements the plugin architecture principle of extracting heavy components into separate, lazy-loaded packages. The result is a lighter core package with better performance characteristics and improved modularity, while maintaining the same developer experience through automatic registration and zero-configuration usage.
4 changes: 3 additions & 1 deletion apps/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
"lucide-react": "^0.469.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-router-dom": "^7.12.0"
"react-router-dom": "^7.12.0",
"@object-ui/plugin-markdown": "workspace:*",
"@object-ui/plugin-kanban": "workspace:*"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
Expand Down
2 changes: 2 additions & 0 deletions apps/playground/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import '@object-ui/components';
// Import lazy-loaded plugins
import '@object-ui/plugin-editor';
import '@object-ui/plugin-charts';
import '@object-ui/plugin-markdown';
import '@object-ui/plugin-kanban';

// Import core styles
import './index.css';
Expand Down
4 changes: 4 additions & 0 deletions apps/playground/src/data/examples/plugins.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import codeEditorDemo from './plugins/code-editor-demo.json';
import chartsDemo from './plugins/charts-demo.json';
import markdownDemo from './plugins/markdown-demo.json';
import kanbanDemo from './plugins/kanban-demo.json';
import pluginsShowcase from './plugins/plugins-showcase.json';

export const plugins = {
'code-editor-demo': JSON.stringify(codeEditorDemo, null, 2),
'charts-demo': JSON.stringify(chartsDemo, null, 2),
'markdown-demo': JSON.stringify(markdownDemo, null, 2),
'kanban-demo': JSON.stringify(kanbanDemo, null, 2),
'plugins-showcase': JSON.stringify(pluginsShowcase, null, 2)
};
Loading