Recently Written · git

scan-subread

PDF reader that follows an audiobook with the SubRead suite

git clone https://github.com/equwal/scan-subread

Log | Files | Refs


commit 7ec5673d88e35ca8843dd15010e8595f722558f7
truex <truex@equwal.com>
2026-09-26 14:54:40 -0700

Load pdf.js and tesseract.js when the app needs them

The new UI modules made the main chunk 503 kB, and the build warned
about a chunk over 500 kB. pdf.js now loads with the first PDF, and
tesseract.js with the first page that needs OCR. The main chunk is now
53 kB and the pdf.js chunk 432 kB, so the build gives no warning, and
the start card shows before the browser parses pdf.js.

 src/main.ts | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/src/main.ts b/src/main.ts
index 48e750e..e77eb1a 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -23,9 +23,9 @@ import {
   readingText,
 } from './messages';
 import { setupNav } from './nav';
-import { createOcr, type Ocr } from './ocr';
+import type { Ocr } from './ocr';
 import { defaultRtl } from './paging';
-import { loadPdf, type PdfDoc } from './pdf';
+import type { PdfDoc } from './pdf';
 import { nextPage } from './read-order';
 import { scrollTarget } from './scroll';
 import { say, showPlayer, showReading } from './status';
@@ -219,6 +219,8 @@ ui.pdfFile.addEventListener('change', async () => {
   try {
     state.readSeq++;
     await state.pdf?.destroy();
+    // pdf.js loads with the first PDF, so the start card shows sooner.
+    const { loadPdf } = await import('./pdf');
     state.pdf = await loadPdf(await file.arrayBuffer());
     state.file = file;
     state.pages = [];
@@ -293,14 +295,16 @@ async function readBook(): Promise<void> {
   const read = (): number => counts.text + counts.ocr;
   /** The page that is read now. */
   let page = -1;
-  // The OCR worker starts on the first page that needs it.
+  const onOcrProgress = (p: number): void => {
+    if (seq === state.readSeq) {
+      showReading(readingText(read(), total, `page ${page + 1}: OCR ${Math.round(p * 100)}%`));
+    }
+  };
+  // The OCR worker, and tesseract.js itself, load on the first page that needs them.
   const ocr: { started?: Promise<Ocr> } = {};
   const getOcr = (): Promise<Ocr> => {
-    ocr.started ??= createOcr(ui.lang.value, (p) => {
-      if (seq === state.readSeq) {
-        showReading(readingText(read(), total, `page ${page + 1}: OCR ${Math.round(p * 100)}%`));
-      }
-    });
+    const lang = ui.lang.value;
+    ocr.started ??= import('./ocr').then(({ createOcr }) => createOcr(lang, onOcrProgress));
     return ocr.started;
   };
   try {