Skip to content

Heavily degrading performance when running PDFKit in a web worker #855

@unpollito

Description

@unpollito

TL:DR: to generate a single PDF file, web workers seem to be much slower than executing PDFKit in the browser's main thread. On top of that, execution times seem to grow much more quickly in web workers than the main thread as the content grows.

Hello,

I'm trying to generate large PDF files from a browser, and these consist mainly of tables. In order not to cause the main thread to do too much work, which would cause the application to stutter, I moved all the PDF generation logic (including PDFKit) into a web worker. However, I noticed a very sharp decrease in performance as generation times grew greatly.

To compare the performance of PDFKit in the main thread or a web worker, I created a simple script. It essentially creates a set number of pages and writes a table in each:

function generatePdf() {
    var doc = new PDFDocument({autoFirstPage: false});
    stream = doc.pipe(blobStream());
    stream.on("finish", function() {
        callback(stream.toBlob("application/pdf"));
    });

    var startTime = Date.now();
    var counter = 0;
    for (var page = 0; page < NUM_PAGES; page++) {
        doc.addPage({margin: 0, size: "A4"});
        var nextLineAt = TOP_MARGIN;
        while (nextLineAt < PAGE_HEIGHT - HORIZONTAL_MARGIN - 25) {
            var nextColumnAt = HORIZONTAL_MARGIN;
            while (nextColumnAt < PAGE_WIDTH - HORIZONTAL_MARGIN - 100) {
                counter++;
                doc.text("Cell number " + counter, nextColumnAt, nextLineAt);
                nextColumnAt += 100;
            }
            nextLineAt += 25;
        }
    }
    console.log(Date.now() - startTime);
    doc.end();
}

When running it with 100 pages on Chrome 68.0.3440.84, there was a noticeable difference between executing the task in the main or a worker thread, but as I kept on adding more pages, that difference skyrocketed:

Pages Thread Execution 1 (ms) Execution 2 (ms) Relative slowdown
100 Main 7429 7509 -
100 Worker 10125 10462 38%
250 Main 19028 19513 -
250 Worker 34485 35975 83%
500 Main 39963 38836 -
500 Worker 120310 120703 206%
1000 Main 78780 82270 -
1000 Worker 503469 gave up here 525%

I'm uploading the scripts I used for the benchmarks, as I couldn't find a CDN link to PDFKit which I could use in a JSFiddle. There are two main files in there, main-thread.html and worker-thread.html. The main function (and the parameter governing the number of pages) can be found on generate-pdf.js.

Is there something I'm doing wrong? Can web workers' performance be reasonably expected to degrade over time, or is there something in the library itself which can be causing this slowdown?

demo.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions