From a09aef0889341673c242a6e886a9750a9c8ddae4 Mon Sep 17 00:00:00 2001 From: Uri Tauber Date: Thu, 25 Jun 2026 16:20:24 +0300 Subject: [PATCH] fix: Optimize Bookmark Rendering by Removing XPath Lookup (#2417) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary fix #2414 ### Root Cause `updateBookmarkFlag()` was introduced in commit 1db1442 and is executed on every render (every page turn). The function calls: `ProgressMapper::toSavedProgress()` → `ChapterXPathResolver::findXPathForProgress()` This path decompresses the current EPUB section content twice: 1. To count visible characters. 2. To resolve the corresponding XPath. For larger sections (e.g. ~133 KB decompressed content), this adds approximately **1 second of I/O overhead per page turn**, with the cost increasing as chapter size grows. ### Fix `updateBookmarkFlag()` only needs to determine whether a bookmark falls within the currently displayed page range. The required information is already available during rendering: * `currentPage` * `section->pageCount` * `currentSpineIndex` Instead of converting the current location to a saved progress object (and resolving an XPath), the implementation now computes the current page's progress range directly and compares bookmark percentages against that range. This is effectively the same percentage-based matching logic already used as a fallback in `bookmarkMatchesProgress()` when XPath matching is unavailable. --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**< PARTIALLY >**_ --- src/activities/reader/EpubReaderActivity.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/activities/reader/EpubReaderActivity.cpp b/src/activities/reader/EpubReaderActivity.cpp index 3d2df14e..6e1a1978 100644 --- a/src/activities/reader/EpubReaderActivity.cpp +++ b/src/activities/reader/EpubReaderActivity.cpp @@ -1350,11 +1350,15 @@ void EpubReaderActivity::updateBookmarkFlag() { currentPageBookmarked = false; return; } - SavedProgressPosition progress = ProgressMapper::toSavedProgress(epub, getCurrentPosition()); const ProgressRange pageRange = getPageProgressRange(epub, currentSpineIndex, section->currentPage, section->pageCount); currentPageBookmarked = std::any_of(cachedBookmarks.begin(), cachedBookmarks.end(), [&](const BookmarkEntry& b) { - return bookmarkMatchesProgress(b, progress, pageRange); + if (b.computedSpineIndex == currentSpineIndex && b.computedChapterPageCount == section->pageCount && + b.computedChapterProgress == section->currentPage) { + return true; + } + const float bp = std::clamp(b.percentage, 0.0f, 1.0f); + return bp + bookmarkProgressEpsilon >= pageRange.start && bp - bookmarkProgressEpsilon <= pageRange.end; }); }