성능 튜닝

렌더링 및 메모리 최적화

Doconut의 리소스 프로필은 세 가지 요소에 의해 좌우됩니다: 렌더 DPI, 캐시되는 내용, 그리고 세션 지속 시간. 이 가이드는 영향력 순서대로 레버를 설명합니다.

해상도 — 가장 큰 레버

ImageResolution (25–300 DPI)는 렌더링 시간과 이미지 크기 모두에 영향을 줍니다. 대부분의 포맷은 기본값이 200 DPI이며, 이미지와 PSD는 기본값이 100입니다.

csharp
// 문서 목록 미리보기는 인쇄 품질이 필요하지 않습니다
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { ImageResolution = 100 });

DPI를 절반으로 줄이면 페이지당 픽셀 수가 대략 4분의 1이 되어 렌더링이 빨라지고 전송량이 감소하며 캐시 메모리 사용량도 줄어듭니다. 확대가 많이 필요한 경우(CAD, 엔지니어링 도면)에는 250–300 DPI를 유지하십시오.

이미지가 많이 포함된 PDF의 경우, PdfConfig가 더 세밀한 조정을 추가합니다: CompressImages + CompressQuality, ResizeImages + ResizeResolution, 그리고 CompressFast. 일반 이미지의 경우, ImageConfig.MaxImagePixelSize(기본값 3000px)가 출력 크기를 제한합니다.

페이지 캐싱 — 메모리 vs. 재렌더링

BaseConfig.CachePages (기본값 true)은 세션 기간 동안 모든 렌더된 페이지를 메모리에 유지합니다. 이는 인터랙티브 뷰잉에 적합한 기본값이며, 사용자는 앞뒤로 스크롤합니다. 다음 경우에 비활성화하십시오:

  • 문서가 매우 크고 한 번만 전체를 보는 경우,
  • 다수의 동시 세션이 캐시된 페이지를 곱해서 증가시킬 경우,
  • RAM을 유지하기보다 뷰당 CPU 사용을 선호하는 경우.
csharp
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { CachePages = false });

클라이언트에서는 ViewerConfig.CacheEnabled = true가 브라우저 메모리에 다가오는 페이지 이미지의 작은 이동 윈도우를 미리 로드합니다. 이는 뷰당 프리패치 캐시이며, 지속적인 localStorage가 아닙니다.

세션 — 눈에 보이지 않는 메모리

열린 각 세션은 파싱된 문서 모델과 (CachePages와 함께) 렌더된 페이지를 보관하며, 슬라이딩 TimeOut(기본값 60분)이 마지막 요청 이후 경과할 때까지 유지됩니다. 이 두 가지 습관이 이를 제어합니다:

  • 작업이 끝난 것을 닫으세요. viewer.CloseDocument(token)는 유휴 창을 기다리는 대신 엔진을 즉시 해제합니다.
  • 시간 제한을 적절히 설정하세요. 사용자가 2분 정도 살펴보는 미리보기는 1시간 세션이 필요하지 않습니다:
csharp
var token = await viewer.OpenDocumentAsync(path, new DocOptions { TimeOut = 10 });

트레이드오프를 기억하세요: 만료 후 위젯은 Document session not found. Please re-open document.를 표시합니다 — 실제 읽기 세션에 맞는 시간 제한을 선택하십시오.

포맷별 스위치

  • Excel: MemoryOptimizationPreference은 기본적으로 켜져 있으며 매우 큰 워크북을 렌더링할 때 메모리 사용량을 줄입니다 — 켜둔 상태로 두거나, 메모리를 약간의 속도 향상과 교환하고 싶다면 false로 설정하십시오; SheetNames / PrintArea는 중요한 부분만 렌더링하도록 제한합니다.
  • 리다이렉트 모드는 초기 비용이 있습니다: DefaultRender = false는 열 때 전체 문서를 PDF로 변환합니다. 이는 기본 텍스트 기반 검색을 가능하게 하지만, 500페이지 문서에서는 열기 호출이 변환을 포함하므로 자동으로 활성화하지 마십시오.
  • 문서의 폰트가 없는 서버에서 Word/PowerPoint: Office가 없는 Windows Server는 개발 머신보다 훨씬 적은 폰트를 가지고 있습니다. 누락된 폰트는 느린 폰트 대체 탐색과 잘못된 메트릭을 초래합니다; 폰트를 설치하거나, FontFolders를 폰트가 들어 있는 폴더로 지정하십시오.

클라이언트 측 전략

  • LargeDoc = true — 매우 큰 문서에 대한 레이지 로드 전략; 사용자가 페이지에 가까워질 때 페이지가 로드됩니다.
  • AutoLoad = false (기본값) — 실제로 View(token)를 호출할 때까지 렌더링하지 않습니다.
  • ShowThumbs = false — 단일 페이지 또는 임베디드 미리보기에 대한 썸네일 생성/요청을 건너뜁니다.
  • FixedZoom를 활성화하면 자유형 줌 변경을 방지합니다; C# ViewerConfig를 매핑할 때, 작은 화면에 맞게 FixedZoomPercentMobile(C# 기본값 75)를 조정하십시오.

시작 시 한 번, 요청당이 아니라

Encoding.RegisterProvider(CodePagesEncodingProvider.Instance)은 Application_Start에 위치해야 하며, DoconutHost.Initialize 옆에 두어야 합니다 — 요청당 인코딩을 등록하는 것은 불필요한 작업이며, 이를 완전히 놓치면 레거시 코드 페이지 문서가 깨집니다.

시작 후 첫 번째 문서

Doconut은 애플리케이션에서 문서를 처음 열 때 문서 엔진을 로드합니다 — 풀 시작 후, 각 재활용 후, 그리고 새로운 애플리케이션 도메인마다. 첫 번째 열기는 이후 열기보다 느리며, 실시간 안티바이러스가 훨씬 더 느리게 만들 수 있습니다: 엔진은 메모리에서 로드되고, Microsoft Defender가 로드되는 코드를 스캔합니다. 파일이 관여하지 않기 때문에 폴더 제외는 도움이 되지 않습니다.

4코어 Windows Server 2022 머신에서 두 페이지 Word 문서를 여는 시간을 측정한 결과:

첫 번째 문서그 이후 모든 문서
Defender 실시간 보호 켜짐약 70초0.3–7.5초, 포맷에 따라 다름
Defender 실시간 보호 끔12–15초0.3–7.5초, 포맷에 따라 다름

한 번만 비용을 지불하고, 사용자보다 먼저 수행하십시오:

  • 워커 프로세스를 유지하십시오: 애플리케이션 풀의 Start Mode를 AlwaysRunning로 설정하고, idle time-out을 늘리거나 비활성화하여 조용한 밤에 엔진이 언로드되지 않도록 합니다.
  • 시작 시 워밍업: IIS Application Initialization을 활성화하고(preloadEnabled="true"를 사이트에 적용) 그 initializationPage를 작은 문서를 여는 페이지에 지정하십시오. 첫 실제 사용자는 이미 로드된 엔진을 발견합니다.
  • 첫 요청에 시간을 주세요: 로드 밸런서 헬스 체크나 짧은 타임아웃을 가진 업스트림 프록시가 성공했을 차가운 시작을 포기하도록 할 수 있습니다.

서버에서 안티바이러스 설정을 변경할지는 보안 팀의 결정이며, 위의 워밍업은 안티바이러스 없이도 작동합니다.

애플리케이션 풀

단일 서버에서는 문서 세션과 캐시된 페이지가 워커 프로세스에 존재합니다. 모든 애플리케이션 풀 재활용 — 예약된 재활용, Web.config 편집, 또는 풀의 idle time-out(IIS 기본값 20분) — 은 모두를 삭제하고, 열려 있는 뷰어는 Document session not found. Please re-open document.를 표시합니다.

  • 풀의 idle time-out 및 재활용 일정을 사용자가 실제로 읽는 시간에 맞추거나, 재활용 후 문서를 다시 열 준비를 하십시오.
  • 풀을 64비트 프로세스로 실행하십시오(Enable 32-Bit Applications를 끄세요). 큰 문서는 32비트 워커 프로세스가 제공하지 못하는 주소 공간이 필요합니다.
  • 웹 팜은 세션을 공유 스토어에 보관하므로, 한 노드에서 재활용해도 세션이 손실되지 않습니다 — 참고 세션 및 보안.

튜닝 체크리스트

  1. UX에서 허용하는 가장 낮은 ImageResolution를 설정하십시오.
  2. 인터랙티브 뷰잉을 위해 CachePages를 켜두고, 일회성 또는 고동시성 시나리오에서는 끄십시오.
  3. 세션을 명시적으로 종료하고, 사용이 급증하는 경우 TimeOut를 단축하십시오.
  4. 큰 문서에 대해 클라이언트에서 LargeDoc와 기본 AutoLoad = false를 사용하십시오.
  5. 텍스트가 포함된 PDF 투사가 필요할 때만 DefaultRender = false를 사용하십시오.

이 페이지가 도움이 되었나요?