ReadViewSDK/.planning/phases/08-pagination-quality-cache-performance/08-01-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

5.6 KiB

phase plan type wave depends_on files_modified autonomous requirements must_haves
08-pagination-quality-cache-performance 01 execute 1
Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift
true
QUAL-01
truths artifacts key_links
Cache key struct exists that captures viewport + typography configuration
Cache lookup and store methods exist on the cache type
Build succeeds with new cache file in project
path provides exports
Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift Cache key struct and cache manager stub
RDEPUBTextRendererCache
RDEPUBPaginationCacheKey
from to via pattern
Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift RDEPUBDTCoreTextRenderer import (future wiring) RDEPUBTextRendererCache
Create the pagination cache infrastructure: a cache key struct that captures viewport dimensions and typography configuration, plus a cache manager stub with lookup/store/invalidate methods. This is the structural foundation that plan 08-02 and future work will wire into the actual rendering pipeline.

Purpose: Prevents the same chapter from being fully re-typeset when viewport and typography config haven't changed (QUAL-01).

Output: RDEPUBTextRendererCache.swift with cache key struct and manager stub.

<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_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

From Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift:

  • RDEPUBTextChapterRenderRequest — contains style: RDEPUBTextRenderStyle, context with baseURL
  • RDEPUBTextRenderStyle — has font: UIFont, lineSpacing: CGFloat, textColor: UIColor?, backgroundColor: UIColor?

From Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift:

  • RDEPUBTextRenderStyle properties used in rendering: font.pointSize, font.familyName, font.fontName, lineSpacing
Task 1: Create cache key struct and cache manager stub Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift - Sources/RDReaderView/EPUBTextRendering/RDEPUBDTCoreTextRenderer.swift (understand render request and style types) - Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererSupport.swift (understand what configuration affects pagination output) Create `Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift` with:
  1. RDEPUBPaginationCacheKey struct — captures the inputs that determine pagination output:

    • chapterID: String (unique chapter identifier, e.g. href or file path)
    • viewportSize: CGSize (the available page dimensions)
    • fontDescriptor: String (font family + name + pointSize, concatenated)
    • lineSpacing: CGFloat
    • textColorHash: Int? (hash of textColor, if present)
    • Implement Equatable conformance (auto-synthesize is fine)
  2. RDEPUBTextRendererCache class:

    • static let shared = RDEPUBTextRendererCache()
    • private var cache: [RDEPUBPaginationCacheKey: [NSAttributedString]] — maps key to array of page attributed strings
    • func cachedPages(for key: RDEPUBPaginationCacheKey) -> [NSAttributedString]? — returns cached pages or nil
    • func store(pages: [NSAttributedString], for key: RDEPUBPaginationCacheKey) — stores pages
    • func invalidate(for key: RDEPUBPaginationCacheKey) — removes a specific entry
    • func invalidateAll() — clears entire cache
    • var entryCount: Int — read-only count of cached entries (for diagnostics)

Make the class final and Sendable-safe (use a lock or @MainActor annotation since rendering is main-thread). Use NSLock for thread safety.

Do NOT wire this cache into the rendering pipeline yet — that is future work. This plan only creates the infrastructure. xcodebuild build -project ReadViewDemo/ReadViewDemo.xcodeproj -scheme ReadViewDemo -destination 'platform=iOS Simulator,name=iPhone 16' 2>&1 | tail -5 <acceptance_criteria> - Sources/RDReaderView/EPUBTextRendering/RDEPUBTextRendererCache.swift exists - File contains struct RDEPUBPaginationCacheKey: Equatable with properties: chapterID, viewportSize, fontDescriptor, lineSpacing, textColorHash - File contains final class RDEPUBTextRendererCache with static shared instance - Class has methods: cachedPages(for:), store(pages:for:), invalidate(for:), invalidateAll() - Class has computed property entryCount: Int - Build succeeds (xcodebuild exits 0) </acceptance_criteria> Cache key struct and cache manager stub exist, build compiles successfully

- Build succeeds with new file - Cache types are properly defined and accessible from other modules in the same target

<success_criteria>

  • RDEPUBPaginationCacheKey captures all inputs that affect pagination output
  • RDEPUBTextRendererCache provides a thread-safe, singleton cache surface ready for wiring
  • No existing code is modified — this is purely additive </success_criteria>
Create `.planning/phases/08-pagination-quality-cache-performance/08-01-SUMMARY.md` when done