I am using react-pdf
to render a pdf in a react application which is then rendered via WebView
in ios
and android
.
The pdf render works in android
.
In ios
, I am getting this error Total canvas memory use exceeds the maximum limit (224 MB).
<Document
file={pdfBlob}
onLoadSuccess={onDocumentLoadSuccess}
renderMode="canvas"
loading={<AppLoader />}
>
<Page
object-fit="fill"
pageNumber={currentPage}
width={isMobile && 350}
loading={<AppLoader />}
onRenderSuccess={() => {
setPdfRenderLoading(false);
}}
renderTextLayer={false}
/>
<IconWrapper isMobile={isMobile}>
<IconButton
disabled={!canGoToPrev()}
colorScheme="blue"
aria-label="go-previous"
icon={<ChevronLeftIcon fontSize={fontSizes.md} />}
backgroundColor={appColors.brandGrey['50']}
color={appColors.brandGrey['900']}
mr={2}
onClick={handlePrevPage}
/>
<AppText title={`${currentPage} of ${totalPages}`} />
<IconButton
disabled={!canGoToNext()}
colorScheme="blue"
aria-label="go-next"
icon={<ChevronRightIcon fontSize={fontSizes.md} />}
backgroundColor={appColors.brandGrey['50']}
color={appColors.brandGrey['900']}
ml={2}
onClick={handleNextPage}
/>
</IconWrapper>
</Document>
I am fetching the pdf from s3
and storing it as a blob
to prevent fetching everytime the page rerenders
My dependencies
"dependencies": {
"@chakra-ui/icons": "^1.1.7",
"@chakra-ui/react": "^1.8.8",
"@emotion/react": "^11",
"@emotion/styled": "^11",
"@fontsource/nunito": "^4.5.8",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.1.1",
"@testing-library/user-event": "^13.5.0",
"axios": "^0.27.2",
"chakra-react-select": "^3.3.1",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-unused-imports": "^2.0.0",
"framer-motion": "^6",
"prettier": "^2.6.2",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-pdf": "^5.7.2",
"react-query": "^3.38.1",
"react-router-dom": "^6.3.0",
"react-scripts": "5.0.1",
"use-debounce": "^8.0.1",
"web-vitals": "^2.1.4",
"zustand": "^4.0.0-rc.1"
}
The entire block is displayed inside a webview using react-native-webview
The pdf starts to render, but get stucks and then the canvas error pops up, is there a fix for this in react-pdf
IOS prevents painting the canvas for such memory."Total canvas memory use exceeds the maximum limit (384 MB)."
Hence React PDF is unable to paint the image.
A quick fix would be to change renderMode
to svg
which just renders the SVG.
SVG takes a bit more time to load than the Canvas. As the Canvas can be viewed to the user and then be painted / rendered, Whereas the SVG is completely rendered before the user can view.
This can be a deal breaker for large PDFs or PDFs with image rich content as rendering SVGs will take a longer time to render
<Document
file={pdfBlob}
onLoadSuccess={onDocumentLoadSuccess}
renderMode="svg" // Changed
loading={<AppLoader />}
>
<Page
object-fit="fill"
pageNumber={currentPage}
width={isMobile && 350}
loading={<AppLoader />}
onRenderSuccess={() => {
setPdfRenderLoading(false);
}}
renderTextLayer={false}
/>
<IconWrapper isMobile={isMobile}>
<IconButton
disabled={!canGoToPrev()}
colorScheme="blue"
aria-label="go-previous"
icon={<ChevronLeftIcon fontSize={fontSizes.md} />}
backgroundColor={appColors.brandGrey['50']}
color={appColors.brandGrey['900']}
mr={2}
onClick={handlePrevPage}
/>
<AppText title={`${currentPage} of ${totalPages}`} />
<IconButton
disabled={!canGoToNext()}
colorScheme="blue"
aria-label="go-next"
icon={<ChevronRightIcon fontSize={fontSizes.md} />}
backgroundColor={appColors.brandGrey['50']}
color={appColors.brandGrey['900']}
ml={2}
onClick={handleNextPage}
/>
</IconWrapper>
</Document>