При разработке современных веб-приложений, таких как Look Scanned, оптимизация производительности является одной из приоритетных задач. Особенно актуально это для обработки изображений. Интерфейс ImageBitmap, хотя пока и не получил широкого распространения, представляет собой мощный инструмент, способный обеспечить существенный прирост производительности. В этой статье мы рассмотрим ключевые возможности ImageBitmap, его преимущества и наш опыт внедрения в Look Scanned.

Что представляет собой ImageBitmap?

ImageBitmap — это интерфейс HTML5, специально разработанный для эффективной обработки изображений. Его ключевое преимущество заключается в возможности выполнять декодирование и обработку изображений вне основного потока, что существенно снижает нагрузку на рендеринг и повышает общую отзывчивость приложения. Созданный объект ImageBitmap можно напрямую использовать в контекстах рендеринга, таких как Canvas 2D или WebGL, что делает его оптимальным выбором для приложений с интенсивной обработкой изображений.

Причины выбора ImageBitmap

Изначально в Look Scanned для передачи данных изображений между функциями обработки использовался Blob. Однако Blob требует выполнения операций кодирования и декодирования при каждом использовании, что создаёт существенные ограничения производительности. В свою очередь, ImageBitmap предоставляет прямой доступ к данным изображения, исключая эти избыточные операции и значительно повышая производительность рендеринга.

Особенности реализации

Учитывая необходимость поддержки устаревших браузеров, полный переход на ImageBitmap оказался нецелесообразным. Поэтому мы реализовали гибридный подход, обеспечивающий широкую совместимость. Подробную информацию о поддержке можно найти на caniuse.com. Кроме того, из-за ограничений Safari в работе с Canvas мы используем WebAssembly (WASM) для обработки изображений, который требует Blob в качестве входного формата.

Учитывая эти факторы, мы разработали поэтапное гибридное решение с поддержкой как Blob, так и ImageBitmap. Рассмотрим основные детали реализации:

Загрузка и декодирование изображений

async function loadImage(url): Promise<ImageBitmap | Blob> {
  const response = await fetch(url);
  const blob = await response.blob();
  if (window.createImageBitmap) {
    return createImageBitmap(blob);
  }
  // Fallback на Blob при отсутствии поддержки
  return blob;
}

Интеграция с WebAssembly

Для расширенной обработки мы передаём Blob в модуль WASM, обеспечивая работоспособность в браузерах без поддержки ImageBitmap. При этом изображение сначала отрисовывается на Canvas, после чего с помощью canvas.toBlob формируется необходимый объект Blob.

Механизм альтернативного рендеринга

async function renderImage(canvas, imageUrl) {
  const ctx = canvas.getContext("2d");
  const image = await loadImage(imageUrl);
  if (image instanceof ImageBitmap) {
    ctx.drawImage(image, 0, 0);
  } else {
    const img = new Image();
    img.src = URL.createObjectURL(image);
    img.onload = () => ctx.drawImage(img, 0, 0);
  }
}

Достигнутые результаты

Внедрение ImageBitmap позволило сократить время обработки изображений в Look Scanned с 50 до 20 миллисекунд на изображение. Это улучшение особенно заметно при работе с отсканированными документами, обеспечивая существенно более плавный и быстрый пользовательский опыт.

Интересные находки

В процессе реализации мы обнаружили интересную особенность: создание новой копии ImageBitmap перед передачей в Web Worker обеспечивает более высокую производительность по сравнению с прямой передачей исходного объекта. Предположительно, это связано с внутренними оптимизациями браузера для передаваемых объектов.

Поддержка в браузерах

На текущий момент ImageBitmap имеет широкую поддержку в основных современных браузерах, включая последние версии Chrome, Firefox, Edge и Safari. Детальную информацию о совместимости можно найти в документации createImageBitmap на caniuse.com.

Заключение и перспективы

Внедрение ImageBitmap в Look Scanned не только существенно повысило производительность, но и позволило реализовать асинхронное декодирование, эффективный рендеринг и улучшенную интеграцию с Web Workers. Хотя поддержка Blob для устаревших браузеров пока остаётся необходимой, постепенный переход на ImageBitmap продолжит приносить значительные преимущества в долгосрочной перспективе.

Оцените улучшения производительности на практике — попробуйте Look Scanned!