ในการพัฒนาแอปพลิเคชันเว็บสมัยใหม่อย่าง 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);
}
// ใช้ 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!