Тонкая настройка производительности

Оптимизация рендеринга и памяти

Профиль ресурсов Doconut определяется тремя вещами: DPI рендеринга, что кэшируется, и как долго живут сессии. Это руководство проходит по рычагам в порядке их влияния.

Разрешение — самый мощный рычаг

ImageResolution (25–300 DPI) определяет как время рендеринга, так и размер изображения. Большинство форматов по умолчанию используют 200 DPI; изображения и PSD — 100.

csharp
// Для предварительного просмотра списка документов не требуется качество печати
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { ImageResolution = 100 });

Уменьшение DPI вдвое примерно уменьшает количество пикселей на странице вчетверо — более быстрый рендер, меньший объём передачи, меньше памяти кэша. Оставляйте 250–300 DPI для сценариев с интенсивным масштабированием (CAD, инженерные чертежи).

Для PDF с большим количеством встроенных изображений, PdfConfig добавляет более тонкие настройки: CompressImages + CompressQuality, ResizeImages + ResizeResolution и CompressFast. Для обычных изображений, ImageConfig.MaxImagePixelSize (по умолчанию 3000 px) ограничивает размер вывода.

Кеширование страниц — память vs. повторный рендер

BaseConfig.CachePages (по умолчанию true) хранит каждую отрисованную страницу в памяти в течение всей сессии. Это правильный параметр по умолчанию для интерактивного просмотра — пользователи прокручивают вперёд и назад. Отключайте его, когда:

  • документы огромные и просматриваются один раз от начала до конца,
  • много одновременных сессий умножат количество кэшированных страниц,
  • вы предпочитаете тратить процессорное время на каждый просмотр, а не держать RAM.
csharp
var token = await viewer.OpenDocumentAsync(path, new PdfConfig { CachePages = false });

На клиенте, ViewerConfig.CacheEnabled = true предварительно загружает небольшое скользящее окно будущих изображений страниц в память браузера. Это кэш предварительной загрузки для каждого просмотра, а не постоянный localStorage.

Сессии — память, которую вы не видите

Каждая открытая сессия хранит разобранную модель документа плюс (с CachePages) её отрисованные страницы, пока не истечёт скользящее окно TimeOut (по умолчанию 60 минут) с момента последнего запроса. Две привычки помогают держать это под контролем:

  • Закрывайте то, чем закончили. viewer.CloseDocument(token) освобождает движок сразу, вместо ожидания простоя.
  • Подбирайте тайм‑аут. Предпросмотр, который пользователи просматривают две минуты, не требует часовой сессии:
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 на сервере без шрифтов документов: Windows Server без Office имеет гораздо меньше шрифтов, чем рабочая машина. Отсутствующие шрифты вызывают медленное резервное определение и неверные метрики; установите шрифты или укажите 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, чтобы тихая ночь не выгружала движки.
  • Прогрейте его при запуске: включите Application Initialization IIS (preloadEnabled="true" на сайте) и укажите его initializationPage на страницу, открывающую небольшой документ. Первый реальный пользователь тогда получит уже загруженные движки.
  • Дайте первому запросу время: проверка состояния балансировщика нагрузки или верхний прокси с коротким тайм‑аутом могут отказаться от холодного старта, который иначе бы завершился успешно.

Менять настройки антивируса на сервере — решение вашей команды безопасности; вышеописанная прогревка работает без него.

Пул приложений

На одном сервере сессии документов и кэшированные страницы находятся в процессе‑рабочем. Каждый рециклинг пула приложений — запланированный, изменение Web.config или idle time-out пула (по умолчанию 20 минут в IIS) — удаляет их все, и открывающие просмотрщики затем показывают Document session not found. Please re-open document.

  • Согласуйте idle time-out пула и расписание рециклинга с тем, как долго пользователи действительно читают, или будьте готовы повторно открывать документы после рециклинга.
  • Запускайте пул как 64‑битный процесс (отключите Enable 32-Bit Applications). Большим документам нужен адресный пространство, которого нет у 32‑битного процесса.
  • В веб‑ферме сессии хранятся в общем хранилище, поэтому рециклинг на одном узле не приводит к их потере — см. Сессии и безопасность.

Чек‑лист настройки

  1. Установите минимальное значение ImageResolution, приемлемое для вашего UX.
  2. Оставляйте CachePages включённым для интерактивного просмотра; отключайте в однопроходных или сценариях высокой конкуренции.
  3. Явно закрывайте сессии; сократите TimeOut, где использование всплескное.
  4. Используйте LargeDoc + значение по умолчанию AutoLoad = false на клиенте для больших документов.
  5. Применяйте DefaultRender = false только когда нужен PDF с текстом.

Была ли эта страница полезной?