ReadViewSDK/.planning/phases/08-pagination-quality-cache-performance/08-03-PLAN.md
shen 86e6922f7b docs(08): create phase plan — image display fix, cache stub, perf sampling
Three plans for Phase 8 (分页质量、缓存与性能采样):
- 08-01: Pagination cache key struct and manager stub (QUAL-01)
- 08-02: Unified 1080x1920 max-size constraint for all images, footnote width-only sizing (QUAL-02, QUAL-03, QUAL-04)
- 08-03: Pagination timing instrumentation with [EPUB][Perf] diagnostic output (QUAL-04)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-23 18:30:56 +08:00

122 lines
5.2 KiB
Markdown

---
phase: 08-pagination-quality-cache-performance
plan: 03
type: execute
wave: 1
depends_on: []
files_modified:
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift
autonomous: true
requirements:
- QUAL-04
must_haves:
truths:
- "Pagination timing is logged with chapter ID, page count, and elapsed milliseconds"
- "Diagnostic summary includes per-chapter pagination stats"
artifacts:
- path: "Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift"
provides: "Pagination timing instrumentation in existing rendering path"
contains: "[EPUB][Perf]"
key_links:
- from: "RDEPUBTextRendererSupport"
to: "os.signpost / print"
via: "timing instrumentation"
pattern: "\\[EPUB\\]\\[Perf\\]"
---
<objective>
Add performance sampling and diagnostic output to the pagination pipeline: log chapter ID, page count, and elapsed time for each pagination pass. This provides the baseline data needed to detect regressions and validate that quality improvements don't degrade performance.
Purpose: QUAL-04 requires that pagination improvements don't significantly degrade first-screen time, re-pagination time, or interaction smoothness. Without measurement, this can't be verified.
Output: Timing instrumentation in the existing rendering path with `[EPUB][Perf]` log prefix.
</objective>
<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>
<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/08-pagination-quality-cache-performance/08-CONTEXT.md
@.planning/phases/08-pagination-quality-cache-performance/08-RESEARCH.md
<interfaces>
<!-- Key types the executor needs -->
From RDEPUBTextRendererSupport.swift:
- The main pagination entry point processes a chapter HTML string and produces an array of pages
- Existing logging pattern: `print("[EPUB][Attachment] footnote classes=...")`
- Use the same `print("[EPUB]...")` convention for consistency
From RDEPUBDTCoreTextRenderer.swift:
- `RDEPUBTextChapterRenderRequest` contains chapter identification
- Rendering produces `NSAttributedString` per page
</interfaces>
</context>
<tasks>
<task type="auto">
<name>Task 1: Add pagination timing instrumentation</name>
<files>Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift</files>
<read_first>
- Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift (full file — find the main pagination entry point)
- Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift (understand render request flow and chapter identification)
</read_first>
<action>
Add timing instrumentation to the pagination pipeline in `RDEPUBTextRendererSupport.swift`.
**What to instrument:** The function that takes chapter HTML and produces paginated output (the main entry point called by the renderer). Wrap the core pagination logic with `CFAbsoluteTimeGetCurrent()` before and after.
**What to log:** After pagination completes, print a single diagnostic line:
```
[EPUB][Perf] chapter={chapterIdentifier} pages={pageCount} elapsed={milliseconds}ms
```
Where:
- `chapterIdentifier` = the chapter href or file name passed into the rendering request
- `pageCount` = number of pages produced
- `milliseconds` = elapsed time as a rounded integer
**Implementation approach:**
1. At the top of the pagination function, capture `let startTime = CFAbsoluteTimeGetCurrent()`
2. At the end (after pages are produced), compute `let elapsed = Int(round((CFAbsoluteTimeGetCurrent() - startTime) * 1000))`
3. Print: `print("[EPUB][Perf] chapter=\(chapterID) pages=\(pages.count) elapsed=\(elapsed)ms")`
Use the same logging convention as the existing `[EPUB][Attachment]` logs. If the function already has a chapter identifier parameter, use it directly. If not, extract it from the request context.
Do NOT add `os.signpost` or `OSLog` — keep it simple with `print` to match existing project conventions. A more sophisticated logging system can be added in Phase 9.
</action>
<verify>
<automated>xcodebuild build -project ReadViewDemo/ReadViewDemo.xcodeproj -scheme ReadViewDemo -destination 'platform=iOS Simulator,name=iPhone 16' 2>&1 | tail -5</automated>
</verify>
<acceptance_criteria>
- RDEPUBTextRendererSupport.swift contains `CFAbsoluteTimeGetCurrent()` for timing capture
- RDEPUBTextRendererSupport.swift contains `print("[EPUB][Perf]` diagnostic output
- Diagnostic line includes chapter identifier, page count, and elapsed milliseconds
- xcodebuild build exits 0
</acceptance_criteria>
<done>Pagination timing instrumentation is in place, build compiles, diagnostic log line fires after each chapter pagination</done>
</task>
</tasks>
<verification>
- Build succeeds
- Running the demo app produces `[EPUB][Perf]` log lines in the console after navigating between chapters
</verification>
<success_criteria>
- Each pagination pass logs chapter ID, page count, and elapsed time
- Log format is consistent with existing `[EPUB]` convention
- No performance overhead beyond a single `CFAbsoluteTimeGetCurrent()` call (negligible)
</success_criteria>
<output>
Create `.planning/phases/08-pagination-quality-cache-performance/08-03-SUMMARY.md` when done
</output>