React-pdf: With worker: Site unresponsive while PDF is rendered

Created on 14 May 2018  Â·  11Comments  Â·  Source: wojtekmaj/react-pdf

Before you start - checklist

  • [✓] I have read documentation in README
  • [✓ I have checked sample and test suites to see real life basic implementation
  • [✓] I have checked if this question is not already asked

What are you trying to achieve? Please describe.
I want to render a pdf using the worker. I do import { Document, Page as PDFPage } from 'react-pdf/dist/entry.webpack' and there is no warning. However, the page is super slow and not responsive at all while loading.

It feels like this is not running in a separate worker and I wonder if I have to do other things besides this import.

Environment

bug

Most helpful comment

I've confirmed that a single render of a pdf page causes the overlapping text to be rendered 3 times. If you turn off the text layer render time drops massively.

<Page
  pageNumber={this.props.page}
  renderTextLayer={false}
/>

All 11 comments

I'm experiencing a similar issue, but it appears that it's caused when rendering the custom HTML text layer that sits on top of a PDF. I'm using the customTextRenderer with a trivial element for testing, and it takes a considerable amount of time to render & locks up the UI while doing so.

Also - I'm not experiencing the same issue in an earlier version of react-pdf (2.4.2). Render times are faster by an order of magnitude. Our temporary solution has been to downgrade to the earlier version.

I solved it with batch loading ...

<Document (some props here)>
    {
      Array.from(
        new Array(props.numPages),
        (el, index) => (
          <PDFPage
            key={`page_${index + 1}`}
            pageNumber={index + 1}
            renderInteractiveForms={false}
            onRenderSuccess={props.renderNext}
          />
        ),
      )
    }
  </Document>

Note that I'm giving numPages from an outside component:

<PDFRenderer (some other props)
    numPages={this.state.loadedPageIndex}              
    renderNext={this.incrementPageLoad}
/>
incrementPageLoad() {
    if (this.state.loadedPageIndex < this.props.numPages) {
      this.setState({ loadedPageIndex: this.state.loadedPageIndex + 1 })
    }
  }

This loads one page after another, resulting in a very smooth experience. It works very well for me as i have a scrollable component anyway (you might need to set the height prior if you mind the scrollbar changing).

Very nice. We're actually only rendering one page at a time, so I imagine your render time was really bad.

I've confirmed that only versions >3.x have this issue, and earlier versions (2.x) render significantly faster. I think the problem you pointed out is still a very real one.

I've confirmed that a single render of a pdf page causes the overlapping text to be rendered 3 times. If you turn off the text layer render time drops massively.

<Page
  pageNumber={this.props.page}
  renderTextLayer={false}
/>

It does indeed render faster. So in combination with my approach it is now SUPER fast. What does renderTextLayer do?

I renders layouts embedded in the pdf file as html on top of the pdf, allowing you to have things like selection behavior on top of the pdf.

We need it because our pdfs are OCR'd, and we need to allow selections on the embedded layout. Unfortunately, drop in rendering speed in the 3.x versions kill usability. We're planning to fork this library and fix the issue to move forward, and submit a PR with what we find (unless the creator knows exactly what the cause is and does it first).

Thx. I'll close it for now. My solution combined with yours (injust need to embed Terms ans conditions) is fast enough.

Thx. I'll close it for now. My solution combined with yours (injust need to embed Terms ans conditions) is fast enough.

@shredding Hey, have you got a working example of your implementation to share ? Thanks

What's in your 'props.renderNext'?
I guess the examples one, is it ?

Was this page helpful?
0 / 5 - 0 ratings