stephanrauh / ngx-extended-pdf-viewer

A full-blown PDF viewer for Angular 16, 17, and beyond
https://pdfviewer.net
Apache License 2.0
473 stars 181 forks source link

slow performance with pdf having 13234 pages #995

Closed subhasispanda98 closed 2 years ago

subhasispanda98 commented 2 years ago

I tried to open a pdf having 13234 pages and its size is 30MB. When I tried to open with ng2-extended-pdf-viewer issue is It performed slow when I tried to scroll down its lagging and not smooth. Link for pdf file to download is

https://1drv.ms/b/s!AnQBGhZ6jZZmgY9WwSoErTmxU7SeVQ?e=jIMAG2

on one drive working like a charm.

https://user-images.githubusercontent.com/82865585/138648642-d3fd723a-4016-4783-85c0-46ef1b8067b6.mp4

stephanrauh commented 2 years ago

Actually, I'm surprised ngx-extended-pdf-viewer manages to open the file at all!

You'll want to activate range requests for such a huge document. Did you already do that? If range requests are activated, you see many small requests in the network tab, each of them requesting a couple of pages of the PDF file. Plus, rendering starts much earlier because the PDF viewer doesn't have to wait until the entire file has been loaded.

stephanrauh commented 2 years ago

I've compared the performance of https://pdfviewer.net to https://mozilla.github.io/pdf.js/web/viewer.html. The latter has a hard time rendering the file, too, at least on my six-year old laptop running on battery. But ngx-extended-pdf-viewer is a lot slower. It seems even the much-faster version 10.5.0 doesn't run on full speed yet. I'll have a look.

stephanrauh commented 2 years ago

BTW, can you send me a file half the size? It's hard to hunt down a performance bug if the developer tools are affected by the performance leak, too. :)

Oh, and what about copyright? I believe your file has been published under a Create Commons 2.5 license, but I need to know for sure to use it as an official demo. Would you mind to research the copyright?

stephanrauh commented 2 years ago

BTW, the file size doesn't seem to be the problem. This 25 MB file renders smoothly: https://research.nhm.org/publications/pdfpick.html?id=10840&pdfroot=http://research.nhm.org/pdfs

subhasispanda98 commented 2 years ago

https://1drv.ms/b/s!AnQBGhZ6jZZmgY9WwSoErTmxU7SeVQ?e=jIMAG2, here is the file . Also you can go to pdftron website to download this files https://www.pdftron.com/webviewer/demo/large-files. Also https://www.pdftron.com/webviewer/demo/gallery/us-public-health-and-welfare-code.pdf. I tried to open the file locally but its lagging. Is there any way to show this pdf in paginated view (we are document processing company so we have requirement for this). Or Any other suggestion how to handle this. Thank you.

stephanrauh commented 2 years ago

Thank you very much!

subhasispanda98 commented 2 years ago

Welcome, can you please solve this issue if not can you suggest me an alternative solution? or can you implement pagination for this.

stephanrauh commented 2 years ago

I can't promise anything. I'll have a look at the performance problem, but this kind of performance problems is always hard to hunt down. Plus, the performance of the base library, pdf.js, isn't overwhelming, either. By the look of it, I've implemented a brake, but there's no way my library can be faster than Mozilla's PDF viewer.

subhasispanda98 commented 2 years ago

then please add pagination like pdftron.com did https://www.pdftron.com/webviewer/demo/large-files there is no other way because canvas consumes huge memory for large pdfs or only render canvas when it is visible to user like one drive did https://1drv.ms/b/s!AnQBGhZ6jZZmgY9WwSoErTmxU7SeVQ?e=jIMAG2

elvisgraho commented 2 years ago

I also experience bad performance on iOS touchscreen (Ionic+Capacitor Application)

I used https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf

Changing enablePinchOnMobile or pdfDefaultOptions.assetsFolder = 'bleeding-edge'; didnt get rid of the performance issue

Edit - I include the dependencies package.json

package.json ```json "dependencies": { "@angular/common": "~12.0.1", "@angular/core": "~12.0.1", "@angular/forms": "~12.0.1", "@angular/platform-browser": "~12.0.1", "@angular/platform-browser-dynamic": "~12.0.1", "@angular/router": "~12.0.1", "@capacitor-community/http": "^1.3.0", "@capacitor/android": "^3.2.5", "@capacitor/app": "^1.0.4", "@capacitor/app-launcher": "^1.0.5", "@capacitor/browser": "^1.0.5", "@capacitor/camera": "^1.0.2", "@capacitor/cli": "^3.2.5", "@capacitor/core": "^3.2.5", "@capacitor/device": "^1.0.4", "@capacitor/filesystem": "^1.0.4", "@capacitor/haptics": "^1.1.0", "@capacitor/ios": "^3.2.5", "@capacitor/keyboard": "^1.1.0", "@capacitor/status-bar": "^1.0.3", "@capacitor/storage": "^1.2.0", "@ionic-native/android-permissions": "^5.32.1", "@ionic-native/barcode-scanner": "^5.33.1", "@ionic-native/contacts": "^5.33.1", "@ionic-native/core": "^5.36.0", "@ionic-native/document-viewer": "^5.36.0", "@ionic-native/file": "^5.32.1", "@ionic-native/file-opener": "^5.36.0", "@ionic-native/http": "^5.32.1", "@ionic-native/launch-navigator": "^5.32.1", "@ionic-native/network": "^5.32.1", "@ionic-native/photo-viewer": "^5.32.1", "@ionic-native/screen-orientation": "^5.32.1", "@ionic-native/zip": "^5.32.1", "@ionic/angular": "^5.8.5", "@ionic/angular-toolkit": "^5.0.0", "@sentry/angular": "^6.2.5", "@sentry/tracing": "^6.2.5", "@tinymce/tinymce-angular": "^4.2.0", "add": "^2.0.6", "angular-svg-round-progressbar": "^7.0.0", "com-sarriaroman-photoviewer": "^1.2.5", "compare-func": "^2.0.0", "cordova": "^10.0.0", "cordova-android": "^10.1.1", "cordova-plugin-actionsheet": "^2.3.3", "cordova-plugin-advanced-http": "^3.1.0", "cordova-plugin-android-permissions": "^1.1.2", "cordova-plugin-contacts": "^3.0.1", "cordova-plugin-dialogs": "^2.0.2", "cordova-plugin-document-viewer": "^1.0.0", "cordova-plugin-file": "^6.0.2", "cordova-plugin-file-opener2": "^3.0.5", "cordova-plugin-network-information": "^2.0.2", "cordova-plugin-screen-orientation": "^3.0.2", "cordova-plugin-zip": "^3.1.0", "cordova-res": "^0.15.3", "core-js": "^3.12.1", "es6-promise-plugin": "^4.2.2", "jetifier": "^1.6.6", "lodash-es": "^4.17.15", "lodash.merge": "^4.6.2", "ngx-extended-pdf-viewer": "^10.5.0", "ngx-logger": "^4.2.1", "ngx-quill": "^13.2.0", "ngx-virtual-scroller": "^4.0.3", "phonegap-plugin-barcodescanner": "git+https://github.com/elvisgraho/phonegap-plugin-barcodescanner.git", "plugin": "^0.3.3", "proj4": "^2.7.2", "quill": "^1.3.7", "rxjs": "~6.6.0", "swiper": "^6.8.4", "tslib": "^2.0.0", "tui-image-editor": "^3.14.3", "uk.co.workingedge.phonegap.plugin.launchnavigator": "^5.0.5", "uuid4": "^1.1.4", "zone.js": "~0.11.4" }, "devDependencies": { "@angular-devkit/build-angular": "~12.0.1", "@angular-eslint/builder": "~12.0.0", "@angular-eslint/eslint-plugin": "~12.0.0", "@angular-eslint/eslint-plugin-template": "~12.0.0", "@angular-eslint/template-parser": "~12.0.0", "@angular/cli": "~12.0.1", "@angular/compiler": "~12.0.1", "@angular/compiler-cli": "~12.0.1", "@angular/language-service": "~12.0.1", "@types/jasmine": "~3.6.0", "@types/jasminewd2": "~2.0.3", "@types/node": "^12.11.1", "@typescript-eslint/eslint-plugin": "4.16.1", "@typescript-eslint/parser": "4.16.1", "eslint": "^7.6.0", "eslint-plugin-import": "2.22.1", "eslint-plugin-jsdoc": "30.7.6", "eslint-plugin-prefer-arrow": "1.2.2", "jasmine-core": "~3.7.1", "jasmine-spec-reporter": "~5.0.0", "karma": "~6.3.2", "karma-chrome-launcher": "~3.1.0", "karma-coverage": "~2.0.3", "karma-coverage-istanbul-reporter": "~3.0.2", "karma-jasmine": "~4.0.0", "karma-jasmine-html-reporter": "^1.5.0", "protractor": "~7.0.0", "ts-node": "~8.3.0", "typescript": "~4.2.4" }, ```
subhasispanda98 commented 2 years ago

please help how to deal with this issue?

stephanrauh commented 2 years ago

@aysha-statvalu I'm sure you know the golden rule of open source: the best way to speed up things is offering your help.

Here's how you can help me. I'd like to know what makes my PDF viewer slow. Would you mind to help me with the investigation?

Best regards, Stephan

stephanrauh commented 2 years ago

@elvisgraho Can you tell me something about the size of your PDF documents?

I'll try a long shot: a common mistake is disabling the service worker. That's my fault: a long time ago I recommended adding the pdf.worker.js file to the scripts section of the angular.json. Removing this files from the angular.json gives your application a major performance boost.

muuvmuuv commented 2 years ago

Well, just commenting here too because I had a similar issue (described here #965). We wrapped this lib into a component which hasn't set changeDetection: ChangeDetectionStrategy.OnPush, so this was the problem because Angular just ran into an infinite loop of CDR. I suggest you to try the same and look if you have range-requests disabled: https://pdfviewer.net/extended-pdf-viewer/range-requests

subhasispanda98 commented 2 years ago

changeDetection: ChangeDetectionStrategy.OnPush not working please help me one thing if a pdf have more than 5000 pages please show single page at a time not 5000 pages at a time please add this feature please help.

muuvmuuv commented 2 years ago

@aysha-statvalu this feature is already implemented and called "range-requests". Is is also enabled by default. Read my comment again. Do you have disabled it? Check your website's network tab in chrome's dev-tools. If you see just one pdf requested then you have disabled it or an old version of ngx-extended-pdf-viewer.

subhasispanda98 commented 2 years ago

please add input property like [showAll]= false like ng2-pdf-viewer has it will enhance performance. Range request not working at all. Rendering 33000 pages are the issue, it's creating a performance issue. Also, you can implement this virtual scroll technique https://www.npmjs.com/package/ngx-virtual-scroller.

stephanrauh commented 2 years ago

Rendering 33000 pages are the issue,

No, it's not. The PDF viewer renders only a few pages in advance. Unless you implement a custom pre-rendering strategy, that's two pages in advance at most.

stephanrauh commented 2 years ago

Did you already discover the single-page mode? https://pdfviewer.net/extended-pdf-viewer/page-view-mode

That's pretty much the same as [showAll]="false". However, what I will not do is writing a new renderer. ngx-extended-pdf-viewer is the PDF viewer of Firefox, plus a few improvements, re-packaged so it supports Angular. I won't re-implement the Firefox PDF viewer from scratch. I agree it has some limitations, and I'm sure it was never meant to display more than a few thousand pages.

I suggest you double-check if you're using range requests, examine your application for performance leaks, and use the single-page mode.

subhasispanda98 commented 2 years ago

pageViewMode="single", This input property saved my life Thank u from my bottom of my heart. But when i tried to zoom in, out its lagging, somewhat improved next page button everything working fine.

stephanrauh commented 2 years ago

Oh, is it really that simple? You're welcome! BTW, kudos to @muuvmuuv who made me realize you might have missed the single-page mode. Ayesha, if you've got an idea how I can document it better or how to empower developers to find the feature faster, just tell me.

As for the lagging zoom: to be honest, I'm clueless. But I'm ready to investigate the topic. But not now: unless I find a sponsor who pays me for working on ngx-extended-pdf-viewer during business hours, it's a leisure-time project, and every once in a while my family life requires me to be there for them.

elvisgraho commented 2 years ago

@elvisgraho Can you tell me something about the size of your PDF documents?

I'll try a long shot: a common mistake is disabling the service worker. That's my fault: a long time ago I recommended adding the pdf.worker.js file to the scripts section of the angular.json. Removing this files from the angular.json gives your application a major performance boost.

I just used random adobe pdf from the web with 978 pages to test. It is 9 mb https://www.adobe.com/content/dam/acom/en/devnet/pdf/pdfs/pdf_reference_archives/PDFReference.pdf

The WebView of the app would go white after the bad performance (4 frames per minute) and application would restart as if going out of memory.

elvisgraho commented 2 years ago

pageViewMode="single" fixed issue performance issue for me too. Now I have a weird problem where the page sticks to the left side of the screen no matter how I zoom, instead of it beeing in the middle.

elvisgraho commented 2 years ago

viewer

subhasispanda98 commented 2 years ago

pageViewMode="single" fixed issue performance issue for me too. Now I have a weird problem where the page sticks to the left side of the screen no matter how I zoom, instead of it beeing in the middle.

Do one thing paste this code in your global style.css

viewerContainer {

text-align: center;

}

and try to open chrome devtools and pick classes from there and add your own style simple and easy.

subhasispanda98 commented 2 years ago

@elvisgraho there is an another package called https://www.npmjs.com/package/ng2-pdf-viewer it has no performance issue try it.

stephanrauh commented 2 years ago

I've got a couple of ideas how to improve the performance. You can implement one of them already now in your project.

Open the file polyfills.ts and scroll down to import 'zone.js'. Add this line:

(window as any).__Zone_disable_requestAnimationFrame = true; // << NEW NEW NEW :)
 import 'zone.js';  // Included with Angular CLI.

That's only a small performance boost, but I'm positive you'll notice it.

Chances are I'm able to release some more brakes soon. Stay tuned!

subhasispanda98 commented 2 years ago

thank you thank you thank you now scroll bar issue is fixed, now on scroll scrollbar not lagging working fine. But One Issue still remaining while Clicking on zoom in, zoom out button its lagging performing slow.

stephanrauh commented 2 years ago

Interesting. I still see hundreds of useless change detections, so I didn't expect the tiny improvement to have such an impact. I'm glad to able to help!

stephanrauh commented 2 years ago

After analyzing the performance today, I'm developing a different theory what's causing the problem. pdf.js generates an empty <div> for each thumbnail and each page. That's 26468 empty divs, and probably quite a challenge for both the V8 engine and the rendering engine.

I'm not sure I want to fix this, but I've decided to investigate the topic. If there's an easy way without risking to break future compatibility to pdf.js, I'll do it.

BTW, you may be interested in using the new scrollmode of pdf.js. It's pretty much the same as my [pageViewMode]="'single'", but developed independently by the pdf.js team.

subhasispanda98 commented 2 years ago

in single view performance is great for rendering pdfs the only issue is on click zoom in, out button it's lagging that thing should only have to fix. On pdftron website if you see they are also doing the same thing single page mode for large documents and thank god we have that feature.

stephanrauh commented 2 years ago

@aysha-statvalu Did you already try the new [scrollMode]="3"? It's been developed by the pdf.js team, so chance are they deliver superior performance. The new feature is currently only available in the "bleeding edge" branch of the 11.0.0-alpha versions.

muuvmuuv commented 2 years ago

After analyzing the performance today, I'm developing a different theory what's causing the problem. pdf.js generates an empty

for each thumbnail and each page. That's 26468 empty divs, and probably quite a challenge for both the V8 engine and the rendering engine.

Now I know why the change detection strategy "on push" fixed it for me xD this is insane haha

Thanks for the zone trick. We already disabled a few must see if this one breaks any other feature.

subhasispanda98 commented 2 years ago

@aysha-statvalu Did you already try the new [scrollMode]="3"? It's been developed by the pdf.js team, so chance are they deliver superior performance. The new feature is currently only available in the "bleeding edge" branch of the 11.0.0-alpha versions.

i am using angular v12 can i use this "bleeding edge" branch.

stephanrauh commented 2 years ago

Yes, of course. The difference between the "assets" branch (which is the default) and the "bleeding edge" branch is it's using a different version of pdf.js. That's nothing to do with the Angular version.

As you've already reported in another ticket, the current version of ngx-extended-pdf-viewer requires RxJS 7, which isn't the default setting of Angular 12 projects. I believe you can update to RxJS 7. Alternatively, wait until I've published the next alpha version. I intend to lower the requirements to RxJS 6.

stephanrauh commented 2 years ago

Starting with version 11.0.0-alpha.3, my custom single-page-mode has been replaced by [scrollMode]="3", provided you're running pdf.js 2.12 or higher. That should solve the issue.