Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/common/reader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2167,6 +2167,14 @@ class Reader {
this._updateState({ freeze: false });
}

// Release rendered pages and pause rendering while the reader is in a
// hidden (background) tab, and restore them when the tab is shown again.
// Currently only has an effect for the PDF view
setSuspended(suspended) {
this._primaryView?.setSuspended?.(suspended);
this._secondaryView?.setSuspended?.(suspended);
}

print() {
if (this._type === 'pdf') {
if (this._state.annotations.length) {
Expand Down
15 changes: 15 additions & 0 deletions src/pdf/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ export default class Page {
this._pageRenderer.render();
}

destroy() {
this._pageRenderer.destroy();
this._detailRenderer.destroy();
}

renderAnnotationOnCanvas(annotation, canvas) {
return this._pageRenderer.renderAnnotationOnCanvas(annotation, canvas);
}
Expand Down Expand Up @@ -95,6 +100,16 @@ class Renderer {
: this._originalPage.canvas;
}

// Zero the snapshot canvas to release its backing store immediately,
// rather than waiting for GC
destroy() {
this._snapshotCanvas.width = 0;
this._snapshotCanvas.height = 0;
this._lastSourceCanvas = null;
this._lastSourceSize = { w: 0, h: 0 };
this._context = null;
}

_initContext() {
let baseCanvas = this._getSourceCanvas();
this._context = baseCanvas ? baseCanvas.getContext('2d') : null;
Expand Down
35 changes: 35 additions & 0 deletions src/pdf/pdf-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,11 @@ class PDFView {

_handlePageDestroy(originalPage) {
let pageIndex = originalPage.id - 1;
for (let page of this._pages) {
if (page.originalPage === originalPage) {
page.destroy();
}
}
this._pages = this._pages.filter(x => x.originalPage !== originalPage);
delete this._pdfPages[pageIndex];
}
Expand Down Expand Up @@ -841,6 +846,36 @@ class PDFView {
this._overlayPopupDelayer.destroy();
}

// Discard rendered pages while the view is hidden (i.e. in a background tab)
// to release page canvases, page snapshot canvases and worker-side page
// resources, which otherwise are retained for up to 10 pages per view.
// Page views stay in place and visible pages re-render on resume
setSuspended(suspended) {
suspended = !!suspended;
if (this._suspended === suspended) {
return;
}
this._suspended = suspended;
let app = this._iframeWindow?.PDFViewerApplication;
if (!app?.pdfViewer) {
return;
}
if (suspended) {
// Prevent new rendering from starting while hidden, otherwise a resize
// or scale change would immediately re-render the discarded pages
app.pdfRenderingQueue.paused = true;
for (let pageView of app.pdfViewer._pages) {
pageView.destroy();
}
// Release worker-side resources (fonts, images) until re-rendering
app.pdfDocument?.cleanup().catch(() => {});
}
else {
app.pdfRenderingQueue.paused = false;
app.pdfViewer.update();
}
}

focus() {
this._iframe.focus();
// this._iframeWindow.focus();
Expand Down