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>
122 lines
5.2 KiB
Markdown
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>
|