forked from mengyxu/noob-components
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
3.0 KiB
84 lines
3.0 KiB
|
3 months ago
|
# Pretext.js Integration for list-table-v2
|
||
|
|
|
||
|
|
## Goal
|
||
|
|
|
||
|
|
Replace the mini-table DOM measurement approach with Pretext.js for calculating text heights in list-table-v2, eliminating forced synchronous reflow and improving performance.
|
||
|
|
|
||
|
|
## Context
|
||
|
|
|
||
|
|
### Current State
|
||
|
|
- list-table-v2 uses a hidden mini-table to measure row heights via `getBoundingClientRect()`
|
||
|
|
- This triggers forced synchronous reflow (~94ms for 1000 items)
|
||
|
|
- The mini-table approach works but has performance cost
|
||
|
|
|
||
|
|
### Target State
|
||
|
|
- Use Pretext.js to calculate text heights mathematically (no DOM access)
|
||
|
|
- Keep mini-table for custom renderer columns (or use running max heuristic)
|
||
|
|
- Reduce/eliminate reflow during height calculation
|
||
|
|
|
||
|
|
## Requirements
|
||
|
|
|
||
|
|
### Must Have
|
||
|
|
1. [ ] Install `@chenglou/pretext` dependency
|
||
|
|
2. [ ] Calculate column widths mathematically (flexbox replication)
|
||
|
|
3. [ ] Integrate Pretext into `renderCellContent` for text-only columns
|
||
|
|
4. [ ] Fallback for custom renderer columns (keep mini-table or use heuristic)
|
||
|
|
5. [ ] Support horizontal resize (recalculate widths when container width changes)
|
||
|
|
|
||
|
|
### Should Have
|
||
|
|
6. [ ] Verify width calculation matches el-table-v2 actual rendering
|
||
|
|
7. [ ] Performance benchmark comparing old vs new approach
|
||
|
|
|
||
|
|
## Technical Approach
|
||
|
|
|
||
|
|
### 1. Width Calculation
|
||
|
|
- Use `useColumnWidthCalculator` (already created)
|
||
|
|
- Formula: `width = flexBasis + (freeSpace * flexGrow / totalFlexGrow)`
|
||
|
|
- Handle shrinking case: `width = flexBasis + (freeSpace * flexShrink / totalFlexShrink)`
|
||
|
|
- Clamp to [minWidth, maxWidth]
|
||
|
|
|
||
|
|
### 2. Pretext Integration
|
||
|
|
```ts
|
||
|
|
// In renderCellContent
|
||
|
|
import { prepare, layout } from '@chenglou/pretext'
|
||
|
|
|
||
|
|
// Prepare once per text/font pair
|
||
|
|
const prepared = prepare(cellData, '14px Inter')
|
||
|
|
|
||
|
|
// Layout at runtime with calculated width
|
||
|
|
const { height } = layout(prepared, textMaxWidth, lineHeight)
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Hybrid Approach for Custom Renderers
|
||
|
|
- Text-only columns: Use Pretext directly
|
||
|
|
- Custom renderer columns: Use running maximum heuristic
|
||
|
|
- Initial estimate based on worst-case content
|
||
|
|
- Update `estimatedRowHeight` with actual observed maximum on scroll
|
||
|
|
|
||
|
|
## Files to Modify
|
||
|
|
|
||
|
|
1. `packages/base/data/list-table-v2.vue`
|
||
|
|
- Add Pretext import
|
||
|
|
- Modify `renderCellContent` to use Pretext for text columns
|
||
|
|
- Handle custom renderer fallback
|
||
|
|
|
||
|
|
2. `packages/base/data/useColumnWidthCalculator.ts`
|
||
|
|
- May need refactoring to work with Vue's script setup order
|
||
|
|
|
||
|
|
## Risks & Mitigation
|
||
|
|
|
||
|
|
| Risk | Mitigation |
|
||
|
|
|------|------------|
|
||
|
|
| Initialization order issue | Integrate Pretext directly, not via separate composable |
|
||
|
|
| Width calculation mismatch | Benchmark against actual el-table-v2 widths |
|
||
|
|
| Custom renderer fallback | Keep mini-table as fallback for non-text columns |
|
||
|
|
|
||
|
|
## Acceptance Criteria
|
||
|
|
|
||
|
|
1. [ ] Table renders without errors at http://localhost:5173/#/table-v2
|
||
|
|
2. [ ] Horizontal scroll works in Combined Test (section 13)
|
||
|
|
3. [ ] Fixed columns display correctly
|
||
|
|
4. [ ] No "Cannot access 'tableColumns' before initialization" error
|
||
|
|
5. [ ] Performance: Height calculation completes without triggering reflow
|
||
|
|
6. [ ] Basic Usage (section 1) still works correctly
|