【问题标题】:react-pdf slow rendering when using scale prop in Page component在页面组件中使用缩放道具时react-pdf缓慢渲染
【发布时间】:2021-03-17 08:46:46
【问题描述】:

我正在使用 react 应用程序制作一个 pdf 查看器。我有一个将近 150 页的 pdf,我正在使用放大和缩小图标,我正在使用 Page 组件中的 scale 道具来实现这一点。但是,每当我放大或缩小时,pdf 文件都会稍微延迟以重新渲染放大的页面。并且这种延迟不会发生在小型 pdf 中。 这是我的代码-

    const [pages, setPages] = React.useState(0);
    const [pagesArr, setPagesArr] = React.useState([]);
    const [scrolledValue, setScrolledValue] = React.useState(0);
    const [pageNumber, setPageNumber] = React.useState(1);
    const [pdfScale, setPdfScale] = React.useState(1.0);

    function onLoadSuccess(param) {
        setPages(param.numPages);
        const numArr = [];
        for (let num = 1; num <= param.numPages; num++) {
            numArr.push(num);
        }
        setPagesArr(numArr);
    }

    function handleZoominIcon() {
        setPdfScale(prev => {
            if (prev > 2.1) {
                return 2.2;
            } else {
                return prev + 0.1;
            }
        });
    }

    function handleZoomoutIcon() {
        setPdfScale(prev => {
            console.log(prev);
            if (prev <= 0.5) {
                return 0.5;
            } else {
                return prev - 0.1;
            }
        });
    }


return (
  <section className = 'ppt-view-pdf' style = {scrolledStyle[1], {zoom: '100%'}} ref = {props.pdfViewRef}>
      <Document  file = {PPT} onLoadSuccess = {onLoadSuccess}>
          {pagesArr.map(element => <Page scale = {pdfScale} key = {element} pageNumber = {element}></Page>)}
       </Document>
  </section>
)

有什么解决办法吗?

【问题讨论】:

    标签: javascript reactjs pdf react-pdf


    【解决方案1】:

    我有同样的问题。性能很差,因为更改比例因子会重新渲染所有页面。我使用 react-window 解决了这个问题,它虚拟化了 dom 中的不可见组件。我使用了VariableSizeList,因为它比FixedSizeList 性能更高。这是一个最小的例子:

    import React, { useEffect, useMemo, useRef, useState } from "react";
    import { Document, Page } from "react-pdf/dist/esm/entry.webpack";
    import { VariableSizeList } from "react-window";
    
    const PDFDoc = () => {
      const [scale, setScale] = useState(1);
      const [numPages, setNumPages] = useState(0);
      const docRef = useRef<HTMLDivElement>(null);
      const [docWidth, setDocWidth] = useState(0);
      const [docHeight, setDocHeight] = useState(0);
    
      const onDocumentLoadSuccess = ({ numPages }: { numPages: number }) => {
        setNumPages(numPages);
        const rect = docRef.current?.getBoundingClientRect();
    
        if (rect) {
          setDocWidth(rect.width);
          setDocHeight(rect.height);
        }
      };
    
      return (
        <div ref={docRef}>
          {/* TODO: add your zoom controls here */}
          <Document file={"sample.pdf"} onLoadSuccess={onDocumentLoadSuccess}>
            <VariableSizeList
              width={docWidth}
              height={docHeight}
              itemCount={numPages}
              estimatedItemSize={numPages}
              itemSize={() => scale * docWidth}
            >
              {({ style, index }) => {
                const currPage = index + 1;
    
                return (
                  <div style={style}>
                    <Page scale={scale} pageNumber={currPage} />
                  </div>
                );
              }}
            </VariableSizeList>
          </Document>
        </div>
      );
    };
    

    你可以安装react-windowhere

    更新

    由于react-window 的一些用户界面问题,我决定最后切换到react-pdf-viewer。到目前为止,它对我来说效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-02
      • 1970-01-01
      • 2019-04-19
      • 2019-04-01
      • 2021-07-13
      • 1970-01-01
      • 1970-01-01
      • 2014-12-15
      相关资源
      最近更新 更多