มีอะไรใหม่ในคำสั่ง NgOptimizeImage ของ Angular

อเล็กซ์ คาสเซิล
อเล็กซ์ คาสเซิล

เมื่อกว่า 1 ปีที่ผ่านมา ทีม Chrome Aurora ได้เปิดตัวคำสั่ง Angular NgOptimizeImage แล้ว คำสั่งนี้มุ่งเน้นที่การปรับปรุงประสิทธิภาพเป็นหลักซึ่งวัดโดยเมตริก Core Web Vitals โดยจะรวมการเพิ่มประสิทธิภาพรูปภาพทั่วไปและแนวทางปฏิบัติแนะนำไว้ใน API ที่แสดงต่อผู้ใช้ ซึ่งไม่ได้ซับซ้อนกว่าองค์ประกอบ <img> มาตรฐานมากนัก

ในปี 2023 เราได้ปรับปรุงคำสั่งดังกล่าวด้วยฟีเจอร์ใหม่ๆ โพสต์นี้อธิบายถึงฟีเจอร์ใหม่ที่สำคัญที่สุด โดยเน้นย้ำถึงเหตุผลที่เราเลือกให้ความสำคัญกับแต่ละฟีเจอร์ และวิธีที่ฟีเจอร์ดังกล่าวช่วยปรับปรุงประสิทธิภาพของแอปพลิเคชัน Angular ได้

ฟีเจอร์ใหม่

NgOptimizeImage ได้รับการปรับปรุงอย่างมากเมื่อเวลาผ่านไป ซึ่งรวมถึงฟีเจอร์ใหม่ต่อไปนี้

โหมดเติมสี

การปรับขนาดรูปภาพโดยระบุแอตทริบิวต์ width และ height เป็นการเพิ่มประสิทธิภาพที่สำคัญอย่างยิ่งในการลดการเปลี่ยนเลย์เอาต์ เนื่องจากเบราว์เซอร์จำเป็นต้องทราบสัดส่วนภาพของรูปภาพเพื่อให้มีพื้นที่ว่าง อย่างไรก็ตาม การปรับขนาดรูปภาพเป็นงานเพิ่มเติมสำหรับนักพัฒนาแอปพลิเคชัน และไม่เหมาะกับกรณีการใช้งานรูปภาพบางกรณี

ซึ่งเป็นฟีเจอร์หลักอย่างแรกที่เพิ่มลงในโหมดการเติมข้อมูลในตัวอย่างคอมโพเนนต์รูปภาพหลังนักพัฒนาแอปเพื่อช่วยแก้ไขความเครียดนี้ วิธีนี้จะช่วยให้นักพัฒนาแอปใส่รูปภาพได้โดยไม่ต้องปรับขนาดอย่างชัดเจน และไม่ทำให้เลย์เอาต์เปลี่ยนแปลง

เมื่อใช้โหมดเติมสี ระบบจะปิดใช้ข้อกำหนดการปรับขนาดรูปภาพและจะมีการจัดรูปแบบรูปภาพโดยอัตโนมัติเพื่อใส่ในองค์ประกอบที่มีอยู่ ซึ่งจะแยกสัดส่วนภาพของรูปภาพออกจากพื้นที่ที่ใช้ในหน้าเว็บ และทำให้คุณสามารถควบคุมการจัดรูปภาพให้พอดีกับเลย์เอาต์หน้าเว็บได้มากขึ้น

โหมดเติมจะใช้ NgOptimizeImage เป็นทางเลือกที่มีประสิทธิภาพมากกว่าสำหรับพร็อพเพอร์ตี้ CSS ของ background-image วางรูปภาพลงใน <div> หรือองค์ประกอบอื่นๆ ที่อาจมีการจัดรูปแบบ background-image จากนั้นเปิดใช้โหมดเติมตามที่แสดงในตัวอย่างโค้ดก่อนหน้า ใช้คุณสมบัติ CSS object-fit และ object-position ใน <div> เพื่อควบคุมวิธีจัดตำแหน่งรูปภาพในเบื้องหลัง

// Height and width are required
<img ngSrc="example.com" height="300" width="400">

// Unless you use fill mode!
<div style="width: 100vw; height: 50em; position: relative">
  <img ngSrc="example.com" fill>
</div>

การสร้าง Srcset

หนึ่งในเทคนิคการเพิ่มประสิทธิภาพรูปภาพที่มีประสิทธิภาพมากที่สุดคือการใช้แอตทริบิวต์ srcset เพื่อให้แน่ใจว่าระบบจะดาวน์โหลดรูปภาพที่มีขนาดเหมาะสมสำหรับอุปกรณ์ใดก็ตามที่เข้าถึงแอปพลิเคชันของคุณ การใช้ srcset ทั่วทั้งแอปจะช่วยลดการสูญเสียแบนด์วิดท์และปรับปรุง LCP Core Web Vitals ได้อย่างมาก

ข้อเสียของแอตทริบิวต์ srcset คือการใช้งานอาจยุ่งยาก การเขียนค่า srcset ด้วยตนเองหมายถึงการเพิ่มมาร์กอัปหลายบรรทัดลงในองค์ประกอบรูปภาพแต่ละรายการในแอป พร้อมด้วย URL ที่กำหนดเองหลายรายการสำหรับ srcset แต่ละรายการ คุณต้องตัดสินใจเกี่ยวกับชุดเบรกพอยท์ซึ่งมีความซับซ้อน เนื่องจากเบรกพอยท์สามารถแสดงทั้งความหนาแน่นของหน้าจอและขนาดวิวพอร์ตของอุปกรณ์ทั่วไป

ดังนั้นการเพิ่มการสร้าง srcset อัตโนมัติลงในคำสั่ง NgOptimizeImage จึงเป็นเป้าหมายสำคัญหลังเปิดตัว ทำให้แอปพลิเคชันใดก็ตามที่ใช้ CDN ที่รองรับการปรับขนาดรูปภาพจะได้รับการเพิ่ม srcsets ทั้งหมดที่ปรับแต่งได้ลงในทุกรูปภาพที่สร้างขึ้นด้วยคำสั่ง NgOptimizeImage โดยอัตโนมัติ

เราได้รวม API แบบง่ายสําหรับการตั้งค่าพร็อพเพอร์ตี้ sizes เข้าไปด้วย เพื่อให้แน่ใจว่ารูปภาพแต่ละรูปจะมีประเภท srcset ที่ถูกต้อง หากไม่ได้ระบุแอตทริบิวต์ sizes เราทราบดีว่ารูปภาพควรมีขนาดคงที่และควรได้รับ srcset ที่ขึ้นอยู่กับความหนาแน่น ดังตัวอย่างต่อไปนี้

<img src="www.example.com/image.png" srcset="www.example.com/image.png?w=400 1x, www.example.com/image.png?w=800 2x" >

srcset ประเภทนี้ช่วยให้มั่นใจได้ว่ารูปภาพจะแสดงผลในขนาดที่คำนึงถึงความหนาแน่นพิกเซลอุปกรณ์ของผู้ใช้ด้วย

ในทางกลับกัน ถ้าคุณรวมพร็อพเพอร์ตี้ sizes ไว้ด้วย NgOptimizedImage จะสร้าง srcset ที่ปรับเปลี่ยนตามอุปกรณ์ซึ่งมีเบรกพอยท์สำหรับอุปกรณ์และขนาดรูปภาพทั่วไปจำนวนมาก โดยใช้รายการเบรกพอยท์เริ่มต้นต่อไปนี้

[16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840]

การสร้างการเชื่อมต่อล่วงหน้า

ในการปรับปรุง LCP คุณจะต้องลดเวลาที่ใช้ดาวน์โหลดรูปภาพ LCP ในส่วนก่อนหน้านี้ คุณได้ทราบวิธีที่ srcset จะช่วยในการโอนไฟล์ภาพขนาดเล็กลงแล้ว แต่การเพิ่มประสิทธิภาพที่สำคัญไม่แพ้กันคือ เริ่มการโอนโดยเร็วที่สุด วิธีหนึ่งที่สามารถทำได้คือการใช้แท็ก link rel="preconnect" เพื่อเริ่มการเชื่อมต่อกับโดเมนรูปภาพของคุณ

ตั้งแต่เริ่มต้น NgOptimizeImage จะแจ้งเตือนหากคุณเชื่อมต่อกับโดเมนของรูปภาพ LCP ล่วงหน้าไม่สำเร็จ แต่คำเตือนยังไม่ใช่วิธีแก้ปัญหาที่ดีที่สุด เราเพียงต้องการแก้ไขปัญหานี้ให้คุณ และนั่นคือสิ่งที่ NgOptimizeImage ทำได้ทันทีด้วยการสร้างการเชื่อมต่อล่วงหน้าอัตโนมัติ

เพื่อรองรับฟีเจอร์นี้ เราใช้การวิเคราะห์โค้ดแบบคงที่เพื่อพยายามตรวจหาโดเมนรูปภาพในตัวโหลด NgOptimizeImage และสร้างแท็กลิงก์ที่เชื่อมต่อล่วงหน้าสำหรับโดเมนเหล่านั้นโดยอัตโนมัติ อาจมีบางกรณีที่ต้องใช้ลิงก์เชื่อมต่อล่วงหน้าด้วยตนเอง แต่สำหรับผู้ใช้ส่วนใหญ่ การเชื่อมต่อล่วงหน้าอัตโนมัติหมายความว่ามีขั้นตอนน้อยลง 1 ขั้นตอนเพื่อให้รูปภาพมีประสิทธิภาพที่ดี

การสนับสนุนระดับสูงสำหรับตัวโหลดที่กำหนดเอง

องค์ประกอบหลักของ NgOptimizeImage คือสถาปัตยกรรมตัวโหลด ซึ่งช่วยให้คำสั่งสามารถสร้าง URL ที่ปรับให้เหมาะกับ CDN รูปภาพของแอปพลิเคชันโดยอัตโนมัติ ชุดตัวโหลดในตัวจะรวมอยู่ใน CDN ที่ใช้กันอย่างแพร่หลาย นอกจากนี้ เรายังมีฟังก์ชันตัวโหลดแบบกำหนดเองที่ให้คุณผสานรวม NgOptimizeImage กับโซลูชันการโฮสต์รูปภาพได้เกือบทุกโซลูชัน

ตอนเปิดตัว โปรแกรมโหลดที่กำหนดเองเหล่านี้มีขอบเขตจำกัด และจะอ่านแอตทริบิวต์ width จากองค์ประกอบรูปภาพได้เท่านั้น เราได้เพิ่มการรองรับโครงสร้างข้อมูล loaderParams ที่ปรับแต่งได้เพื่อตอบสนองความคิดเห็นของผู้ใช้ ซึ่งช่วยให้ส่งข้อมูลที่กำหนดเองจากองค์ประกอบรูปภาพไปยังตัวโหลดที่กำหนดเองได้ ด้วยการขยายนี้ ตัวโหลดที่กำหนดเองอาจเรียบง่ายหรือซับซ้อนตามที่โครงสร้างพื้นฐานอิมเมจของแอปพลิเคชันกำหนด

ตัวอย่างต่อไปนี้แสดงวิธีที่ตัวโหลดที่กำหนดเองแบบง่ายสามารถใช้ API ของ loaderParams เพื่อเลือกระหว่างโดเมนรูปภาพสำรอง 2 โดเมน

const myCustomLoader = (config: ImageLoaderConfig) => {
  if (config.loaderParams?.alternateDomain) {
    return `https://alternate.domain.com/images/${config.src}`
  }
  return `https://primary.domain.com/images/${config.src}`;
};

ตัวอย่างตัวโหลดแบบกำหนดเองที่ซับซ้อนมากขึ้นมีอยู่ในเอกสารประกอบของ Angular

คำแนะนำเพิ่มเติมสำหรับประสิทธิภาพของรูปภาพ

ที่ผ่านมา การแจ้งเตือนประสิทธิภาพของรูปภาพทุกรายการที่เราเพิ่มลงใน Angular ล้วนเป็นส่วนหนึ่งของคำสั่ง NgOptimizeImage แล้ว หากไม่ได้ใช้คำสั่งในแอป คุณจะไม่ได้รับคำแนะนำเกี่ยวกับปัญหาด้านประสิทธิภาพของรูปภาพ

ใน Angular 17 เราจะขยายขอบเขตของคําแนะนําด้านประสิทธิภาพรูปภาพให้ครอบคลุมแอป Angular ทั้งหมด ในตอนนี้ หากเราตรวจพบรูปแบบรูปภาพที่เราทราบว่าเป็นข้อผิดพลาดที่เป็นอันตรายต่อประสิทธิภาพ เช่น การโหลดรูปภาพ LCP แบบ Lazy Loading หรือการดาวน์โหลดไฟล์ที่มีขนาดใหญ่เกินไปสําหรับหน้าเว็บ เราจะแจ้งให้คุณทราบ แม้ว่าคุณจะไม่ได้ใช้ NgOptimizeImage ก็ตาม

ประสิทธิภาพของรูปภาพเป็นสิ่งสำคัญสำหรับทุกแอป และเรายินดีที่จะสร้างแนวป้องกันเพื่อช่วยป้องกันข้อผิดพลาดที่พบบ่อยในแอป Angular ด้วย

เส้นทางต่อจากนี้

เรากำลังทำงานกันอย่างหนักในการพัฒนาฟีเจอร์ชุดถัดไปสำหรับ NgOptimizeImage แม้ว่าประสิทธิภาพของรูปภาพจะยังคงเป็นสิ่งที่เราให้ความสำคัญ แต่เราก็ต้องการเพิ่มฟีเจอร์ที่ช่วยปรับปรุงประสบการณ์การใช้งานของนักพัฒนาซอฟต์แวร์ด้วย เพื่อให้แน่ใจว่า NgOptimizeImage ยังคงเป็นตัวเลือกที่น่าสนใจสำหรับการรวมรูปภาพในแอปพลิเคชัน Angular

ฟีเจอร์หนึ่งที่เราให้ความสำคัญสูงสุดคือตัวยึดตำแหน่งรูปภาพ โดยทั่วไปแล้วจะใช้เพื่อทำให้การโหลดรูปภาพดูดีขึ้นในเว็บแอปพลิเคชัน แต่ก็อาจส่งผลเสียต่อประสิทธิภาพได้หากใช้ไม่ถูกต้อง เราหวังว่าจะสร้างระบบตัวยึดตำแหน่งรูปภาพที่เน้นประสิทธิภาพเป็นหลักใน NgOptimizeImage ได้ ติดตามบล็อกของเราเพื่อให้ทราบประกาศเพิ่มเติม