Podczas tworzenia nowoczesnych aplikacji webowych, takich jak Look Scanned, optymalizacja wydajności stanowi kluczowy priorytet. Jest to szczególnie istotne w kontekście przetwarzania obrazów. Interfejs ImageBitmap, choć nie jest jeszcze powszechnie stosowany, stanowi potężne narzędzie umożliwiające znaczącą poprawę wydajności. W tym artykule omawiamy główne funkcje ImageBitmap, jego zalety oraz nasze doświadczenia z wdrożenia w Look Scanned.
Czym jest ImageBitmap?
ImageBitmap to interfejs HTML5 stworzony z myślą o wydajnym przetwarzaniu obrazów. Jego kluczową zaletą jest możliwość wykonywania dekodowania i przetwarzania obrazów poza głównym wątkiem, co znacząco redukuje obciążenie podczas renderowania i poprawia ogólną responsywność aplikacji. Utworzony obiekt ImageBitmap może być bezpośrednio wykorzystywany w kontekstach renderowania, takich jak Canvas 2D czy WebGL, co sprawia, że jest idealnym rozwiązaniem dla aplikacji operujących na dużej liczbie obrazów.
Dlaczego zdecydowaliśmy się na ImageBitmap?
Początkowo w Look Scanned wykorzystywaliśmy Blob do przekazywania danych obrazów między funkcjami przetwarzającymi. Niestety, Blob wymaga kodowania i dekodowania przy każdym użyciu, co negatywnie wpływa na wydajność. Z kolei ImageBitmap zapewnia bezpośredni dostęp do danych obrazu, eliminując te dodatkowe operacje i znacząco poprawiając wydajność renderowania.
Szczegóły wdrożenia
Ze względu na konieczność zachowania kompatybilności ze starszymi przeglądarkami, całkowite przejście na ImageBitmap nie wchodziło w grę. Dlatego opracowaliśmy hybrydowe podejście zapewniające szeroką kompatybilność. Szczegółowe informacje o wsparciu można znaleźć na caniuse.com. Dodatkowo, z powodu ograniczeń Safari w obsłudze Canvas, wykorzystujemy WebAssembly (WASM) do przetwarzania obrazów, co wymaga użycia Blob jako formatu wejściowego.
Uwzględniając te uwarunkowania, stworzyliśmy stopniowe rozwiązanie hybrydowe obsługujące zarówno Blob, jak i ImageBitmap. Oto kluczowe elementy implementacji:
Ładowanie i dekodowanie obrazów
async function loadImage(url): Promise<ImageBitmap | Blob> {
const response = await fetch(url);
const blob = await response.blob();
if (window.createImageBitmap) {
return createImageBitmap(blob);
}
// Fallback do Blob
return blob;
}
Integracja z WebAssembly
W przypadku zaawansowanego przetwarzania, przekazujemy Blob do modułu WASM, co zapewnia funkcjonalność w przeglądarkach bez obsługi ImageBitmap. W tym procesie najpierw renderujemy obraz na Canvas, a następnie wykorzystujemy canvas.toBlob do utworzenia wymaganego obiektu Blob.
Alternatywny system renderowania
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);
}
}
Uzyskane rezultaty
Wdrożenie ImageBitmap pozwoliło skrócić czas przetwarzania obrazów w Look Scanned z 50 ms do 20 ms na obraz. Poprawa jest szczególnie widoczna przy przetwarzaniu skanowanych dokumentów, zapewniając znacznie płynniejsze i szybsze działanie aplikacji.
Ciekawe spostrzeżenia
Podczas wdrożenia dokonaliśmy interesującego odkrycia: utworzenie nowej kopii ImageBitmap przed przekazaniem jej do Web Workera zapewnia lepszą wydajność niż bezpośrednie przekazanie oryginalnego obiektu. Najprawdopodobniej wynika to z wewnętrznych optymalizacji przeglądarki dla obiektów przenośnych.
Wsparcie w przeglądarkach
Obecnie ImageBitmap jest szeroko wspierany we wszystkich głównych nowoczesnych przeglądarkach, włączając najnowsze wersje Chrome, Firefox, Edge i Safari. Szczegółowe informacje o kompatybilności znajdują się w dokumentacji createImageBitmap na caniuse.com.
Podsumowanie i perspektywy
Wdrożenie ImageBitmap w Look Scanned nie tylko przyniosło znaczącą poprawę wydajności, ale również umożliwiło asynchroniczne dekodowanie, efektywne renderowanie i lepszą integrację z Web Workers. Choć wsparcie dla Blob pozostaje niezbędne dla starszych przeglądarek, stopniowe przechodzenie na ImageBitmap będzie przynosić coraz większe korzyści w dłuższej perspektywie.
Wypróbuj ulepszenia wydajności na własną rękę na Look Scanned!