fix(pdfviewer): skip page text extraction when enableTextSelection is false - #2560
Open
ali-pouneh wants to merge 1 commit into
Conversation
… false _checkVisiblePages() calls PdfTextExtractor.extractText() unconditionally for every visible page, regardless of the enableTextSelection property. The extraction runs synchronously on the UI isolate and its results are cached in _pageTextExtractor, which is only cleared when the document changes. On large documents this causes an unrecoverable "Out of Memory" in the Dart heap and an Android ANR, because the parse allocates growable byte lists per content stream while the cache keeps every previously visited page alive. Guard the three extractText() call sites with widget.enableTextSelection so applications that disable text selection do not pay for extraction they cannot use. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
SfPdfViewerState._checkVisiblePages()callsPdfTextExtractor.extractText()for every visible page unconditionally — theenableTextSelectionproperty is never consulted. On large documents this produces an unrecoverable DartOut of Memoryand an Android ANR.This PR guards the three
extractText()call sites withwidget.enableTextSelection.The problem
In
lib/src/pdfviewer.dart,enableTextSelectionis referenced in exactly one place (line 3786), where it is forwarded to the page widget for the selection UI. It does not gate extraction. Meanwhile_checkVisiblePages()extracts text at three sites (single-page mode, and the forward/backward visible-page loops), and the results are cached in_pageTextExtractor, which is cleared only when the document changes — so every page visited during a session stays resident.Extraction runs synchronously on the UI isolate. The combination means an application that sets
enableTextSelection: falsestill pays the full parse cost, and on a large document the allocation eventually fails.Reproduction
Android release build, Pixel 9 / Android 17,
syncfusion_flutter_pdfviewer33.2.7, ~50-page PDF,PdfPageLayoutMode.continuous,enableTextSelection: false. Paging through the document withPdfViewerController.nextPage()reliably reproduces it.Followed by:
Note frames #20–#26: the extraction is reached from the UI isolate via a tap handler, which is what turns the memory problem into an ANR.
Measured effect
adb shell dumpsys meminfo, same device, same document, same navigation, release builds:Unknown(Dart/native)Out of MemoryoccurrencesPage rendering is also visibly faster, since the UI isolate no longer parses content streams for every page that scrolls into view.
Scope and compatibility
enableTextSelectiondefaults totrue, so existing behaviour is unchanged for applications that do not opt out. Only applications that explicitly setenableTextSelection: falseare affected, and for those the extracted text was already unusable for selection.One thing worth a maintainer's eye: if
_pageTextExtractoris consumed by any path other than selection when the flag is off, that path would now see an empty cache. I could not find one, but I do not know the codebase as well as you do.Separately, and not addressed here:
_pageTextExtractorhas no eviction policy while a document is open, so even withenableTextSelection: truememory grows with the number of pages visited. A bounded cache would likely help large documents independently of this change.Verification
Verified on a patched local copy of 33.2.7 consumed through a
dependency_overridespath override, in a release build on a physical device. The same three call sites are present and unguarded in 34.1.29 (this branch) and in the published 34.2.8.