עיבוד תמונות בצד הלקוח בביצועים גבוהים
עיבוד תמונות בדפדפן הוא כיום דרישה סטנדרטית. ייתכן שתבנו עורכי תמונות, ערכות כלים לנכסים (asset toolkits) או מסנני נגישות. כדי לשמור על ממשק משתמש (UI) מגיב, עליכם להבטיח זמן תגובה (latency) נמוך.
משימה פשוטה היא היפוך צבעים. המשמעות היא הפיכת ערכי RGB לערכים השליליים שלהם. אם תשתמשו בגישה הסטנדרטית על תמונות 4K, תיתקלו בצווארי בקבוק של החומרה.
הבעיה: איטרציה נאיבית
רוב המפתחים משתמשים במתודה getImageData(). היא מחזירה Uint8ClampedArray. מערך זה שומר פיקסלים כערוצי Red, Green, Blue, ו-Alpha (RGBA).
לולאה סטנדרטית נראית כך:
- מעבר בלולאה על כל בייט בודד.
- חיסור כל ערך צבע מ-255.
- דילוג על ערוץ ה-Alpha.
זה עובד עבור תמונות קטנות. זה נכשל עבור נכסי 4K. לתמונה ב-4K יש למעלה מ-8 מיליון פיקסלים. לולאה סטנדרטית מבצעת למעלה מ-33 מיליון כתיבות נפרדות. זה חוסם את ה-main thread, גורם לקפיעות בדפדפן ולדילוג על פריימים (drops frames).
הפתרון: מניפולציה של Buffer ב-32 סיביות
אתם יכולים להפסיק להתייחס לפיקסלים כארבעה ערוצים נפרדים. במקום זאת, הניחו Uint32Array מעל ה-data buffer.
באמצעות שימוש ב-view של 32 סיביות, אתם מקבצים את R, G, B, ו-A למספר שלם אחד. הלולאה שלכם מבצעת כעת רק 8.2 מיליון איטרציות במקום 33 מיליון. אתם מבצעים פעולה אחת לכל פיקסל במקום ארבע.
היפוך צבעים מהיר באמצעות Bitwise XOR
כדי להפוך צבעים מבלי לגעת ב-Alpha, השתמשו באופרטור ה-bitwise XOR (^). השתמשו ב-mask 0x00FFFFFF.
איך זה עובד:
- ה-mask מכוון רק לביטים של הצבע.
- ביטי ה-Alpha נשארים ללא שינוי.
- ה-CPU מעבד זאת במחזור (cycle) אחד.
התוצאות:
- נכסי 1080p: מהירים פי 3.8.
- תבניות 2K: מהירות פי 4.1.
- רקעים ב-4K: מהירים פי 4.4.
טיפ של מקצוענים: השתמשו ב-Web Workers
אם אתם מעבדים קבצים רבים ברזולוציה גבוהה, אפילו פעולות של 32 סיביות עלולות להאט את ה-UI. העבירו את הלוגיקה ל-Web Worker. השתמשו ב-Transferable Objects כדי להעביר את ה-buffer. זה מונע העתקת נתונים ושומר על ה-main thread שלכם פנוי.
הפסיקו להשתמש בלולאות כבדות. השתמשו ב-32-bit words וב-bitwise flags כדי לבנות pipelines של תמונות רזים ומהירים.