การสร้างคอมโพเนนต์รูปภาพที่มีประสิทธิภาพ

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

Leena Sohoni
Leena Sohoni
Kara Erickson
Kara Erickson
Alex Castle
Alex Castle

รูปภาพเป็นแหล่งที่มาที่พบบ่อยของจุดคอขวดด้านประสิทธิภาพสําหรับเว็บแอปพลิเคชัน และเป็นจุดที่ควรมุ่งเน้นสําหรับการเพิ่มประสิทธิภาพ รูปภาพที่ไม่ได้เพิ่มประสิทธิภาพทำให้หน้าเว็บมีขนาดใหญ่ขึ้นและคิดเป็นสัดส่วนมากกว่า 70% ของน้ำหนักหน้าเว็บทั้งหมดในไบต์ที่เปอร์เซ็นต์ไทล์ 90th การเพิ่มประสิทธิภาพรูปภาพมีหลายวิธี ซึ่งต้องใช้ "คอมโพเนนต์รูปภาพ" อัจฉริยะที่มีโซลูชันด้านประสิทธิภาพในตัวโดยค่าเริ่มต้น

ทีม Aurora ทำงานร่วมกับ Next.js เพื่อสร้างคอมโพเนนต์ดังกล่าวเพียงอันเดียว เป้าหมายคือการสร้างเทมเพลตรูปภาพที่เพิ่มประสิทธิภาพซึ่งนักพัฒนาเว็บจะปรับแต่งเพิ่มเติมได้ คอมโพเนนต์นี้ใช้เป็นโมเดลที่ดีและกำหนดมาตรฐานในการสร้างคอมโพเนนต์รูปภาพในเฟรมเวิร์ก ระบบจัดการเนื้อหา (CMS) และแพ็กเกจเทคโนโลยีอื่นๆ เราได้ทำงานร่วมกันเกี่ยวกับคอมโพเนนต์ที่คล้ายกันสำหรับ Nuxt.js และกำลังทำงานร่วมกับ Angular ในการเพิ่มประสิทธิภาพรูปภาพในเวอร์ชันในอนาคต โพสต์นี้กล่าวถึงวิธีที่เราออกแบบคอมโพเนนต์รูปภาพ Next.js และบทเรียนที่เราได้เรียนรู้ไปตลอด

คอมโพเนนต์รูปภาพที่เป็นส่วนขยายของรูปภาพ

ปัญหาและโอกาสในการเพิ่มประสิทธิภาพรูปภาพ

รูปภาพไม่เพียงส่งผลต่อประสิทธิภาพ แต่ยังส่งผลต่อธุรกิจด้วย จํานวนรูปภาพในหน้าเว็บเป็นตัวคาดการณ์ Conversion ที่ใหญ่ที่สุดอันดับ 2 ของผู้ใช้ที่เข้าชมเว็บไซต์ เซสชันที่ผู้ใช้ทํา Conversion มีรูปภาพน้อยกว่าเซสชันที่ไม่ได้ทํา Conversion 38% Lighthouse แสดงโอกาสมากมายในการเพิ่มประสิทธิภาพรูปภาพและปรับปรุง Web Vitals ซึ่งเป็นส่วนหนึ่งของการตรวจสอบแนวทางปฏิบัติแนะนำ ตัวอย่างบางส่วนของพื้นที่ทั่วไปที่รูปภาพอาจส่งผลต่อ Core Web Vitals และประสบการณ์ของผู้ใช้มีดังนี้

รูปภาพที่ไม่ได้ปรับขนาดส่งผลเสียต่อ CLS

รูปภาพที่แสดงโดยไม่ได้ระบุขนาดอาจทําให้เลย์เอาต์ไม่เสถียรและทําให้ Cumulative Layout Shift (CLS) สูง การตั้งค่าแอตทริบิวต์ width และ height ในองค์ประกอบ img จะช่วยป้องกันการเปลี่ยนเลย์เอาต์ได้ เช่น

<img src="flower.jpg" width="360" height="240">

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

รูปภาพขนาดใหญ่อาจส่งผลเสียต่อ LCP

ยิ่งไฟล์รูปภาพมีขนาดใหญ่เท่าใด ก็ยิ่งใช้เวลาดาวน์โหลดนานขึ้นเท่านั้น รูปภาพขนาดใหญ่อาจเป็นรูปภาพ "ภาพหลัก" ของหน้าเว็บหรือองค์ประกอบที่สําคัญที่สุดในวิวพอร์ตซึ่งทริกเกอร์ Largest Contentful Paint (LCP) รูปภาพที่เป็นส่วนหนึ่งของเนื้อหาสำคัญและใช้เวลาดาวน์โหลดนานจะทำให้ LCP ทำงานล่าช้า

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

การบีบอัดรูปภาพไม่ดีอาจส่งผลเสียต่อ LCP

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

การโหลดรูปภาพที่ไม่จําเป็นส่งผลเสียต่อ LCP

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

ปัญหาการเพิ่มประสิทธิภาพ

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

  • ลำดับความสำคัญ: นักพัฒนาเว็บมักจะมุ่งเน้นที่โค้ด, JavaScript และการเพิ่มประสิทธิภาพข้อมูล ด้วยเหตุนี้ ผู้ขายจึงอาจไม่ทราบว่ารูปภาพมีปัญหาหรือวิธีเพิ่มประสิทธิภาพรูปภาพ รูปภาพที่สร้างโดยนักออกแบบหรือที่ผู้ใช้อัปโหลดอาจไม่มีอยู่ในรายการลำดับความสำคัญสูง
  • โซลูชันที่พร้อมใช้งานทันที: แม้ว่านักพัฒนาซอฟต์แวร์จะทราบถึงความแตกต่างของการเพิ่มประสิทธิภาพรูปภาพ แต่การไม่มีโซลูชันแบบครบวงจรที่พร้อมใช้งานทันทีสำหรับเฟรมเวิร์กหรือสแต็กเทคโนโลยีอาจทำให้นักพัฒนาซอฟต์แวร์ลังเล
  • รูปภาพแบบไดนามิก: นอกเหนือจากรูปภาพนิ่งที่เป็นส่วนหนึ่งของแอปพลิเคชันแล้ว ผู้ใช้ยังอัปโหลดรูปภาพแบบไดนามิกหรือดึงมาจากฐานข้อมูลภายนอกหรือ CMS ได้ การกําหนดขนาดของรูปภาพดังกล่าวซึ่งแหล่งที่มาของรูปภาพเป็นแบบไดนามิกอาจเป็นเรื่องยาก
  • มาร์กอัปมากเกินไป: โซลูชันสำหรับการใส่ขนาดรูปภาพหรือ srcset สำหรับรูปภาพขนาดต่างๆ ต้องใช้มาร์กอัปเพิ่มเติมสำหรับรูปภาพทุกรูป ซึ่งอาจทำให้ยุ่งยาก แอตทริบิวต์ srcset เปิดตัวเมื่อปี 2014 แต่มีเว็บไซต์เพียง 26.5% ที่ใช้ในปัจจุบัน เมื่อใช้ srcset นักพัฒนาแอปจะต้องสร้างรูปภาพเป็นขนาดต่างๆ เครื่องมืออย่าง just-gimme-an-img จะช่วยได้ แต่ต้องดำเนินการด้วยตนเองสำหรับรูปภาพแต่ละรูป
  • การรองรับเบราว์เซอร์: รูปแบบรูปภาพสมัยใหม่ เช่น AVIF และ WebP จะสร้างไฟล์รูปภาพที่มีขนาดเล็กลง แต่ต้องได้รับการจัดการพิเศษในเบราว์เซอร์ที่ไม่รองรับ นักพัฒนาซอฟต์แวร์ต้องใช้กลยุทธ์ต่างๆ เช่น การเจรจาต่อรองเนื้อหาหรือเอลิเมนต์ <picture> เพื่อให้รูปภาพแสดงในเบราว์เซอร์ทั้งหมด
  • ความซับซ้อนของการโหลดแบบ Lazy Loading: มีเทคนิคและไลบรารีหลายรายการที่พร้อมใช้งานเพื่อใช้การโหลดแบบ Lazy Loading สำหรับรูปภาพที่อยู่ด้านล่าง การเลือกรูปแบบที่ดีที่สุดอาจเป็นเรื่องยาก นอกจากนี้ นักพัฒนาแอปอาจไม่ทราบระยะที่ดีที่สุดจาก "แนวพับ" เพื่อโหลดรูปภาพที่เลื่อนเวลา วิวพอร์ตขนาดต่างๆ ในอุปกรณ์อาจทําให้ปัญหานี้ซับซ้อนยิ่งขึ้น
  • การเปลี่ยนแปลงภูมิทัศน์: เมื่อเบราว์เซอร์เริ่มรองรับฟีเจอร์ HTML หรือ CSS ใหม่ๆ เพื่อเพิ่มประสิทธิภาพ อาจทำให้นักพัฒนาซอฟต์แวร์ประเมินแต่ละฟีเจอร์ได้ยาก ตัวอย่างเช่น Chrome กำลังเปิดตัวฟีเจอร์ลําดับความสําคัญในการดึงข้อมูลเป็นช่วงทดลองใช้จากต้นทาง ซึ่งสามารถใช้เพื่อเพิ่มลำดับความสำคัญของรูปภาพบางรูปในหน้าเว็บ โดยรวมแล้ว นักพัฒนาแอปจะใช้งานง่ายขึ้นหากมีการประเมินการเพิ่มประสิทธิภาพดังกล่าวและนำไปใช้ในระดับคอมโพเนนต์

คอมโพเนนต์รูปภาพเป็นโซลูชัน

โอกาสในการเพิ่มประสิทธิภาพรูปภาพและความท้าทายในการใช้งานรูปภาพแต่ละรายการสำหรับแอปพลิเคชันแต่ละรายการทำให้เราเกิดแนวคิดเกี่ยวกับคอมโพเนนต์รูปภาพ คอมโพเนนต์รูปภาพสามารถสรุปและบังคับใช้แนวทางปฏิบัติแนะนำได้ การเปลี่ยนองค์ประกอบ <img> ไปใช้คอมโพเนนต์รูปภาพจะช่วยให้นักพัฒนาแอปแก้ปัญหาเกี่ยวกับประสิทธิภาพรูปภาพได้ดียิ่งขึ้น

ในช่วงปีที่ผ่านมา เราได้ทํางานร่วมกับเฟรมเวิร์ก Next.js เพื่อออกแบบและติดตั้งใช้งานคอมโพเนนต์รูปภาพ โดยสามารถใช้แทนค่าเดิมในการแทนที่องค์ประกอบ <img> ที่มีอยู่ในแอป Next.js ได้ดังนี้

// Before with <img> element:
function Logo() {
  return <img src="/logo.jpg" alt="logo" height="200" width="100" />
}

// After with image component:
import Image from 'next/image'

function Logo() {
  return <Image src="/logo.jpg" alt="logo" height="200" width="100" />
}

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

การป้องกันการเปลี่ยนแปลงเลย์เอาต์

ดังที่ได้กล่าวไปก่อนหน้านี้ รูปภาพที่ไม่ได้ปรับขนาดจะทําให้เลย์เอาต์เปลี่ยนและส่งผลต่อ CLS เมื่อใช้คอมโพเนนต์รูปภาพ Next.js นักพัฒนาซอฟต์แวร์ต้องระบุขนาดรูปภาพโดยใช้แอตทริบิวต์ width และ height เพื่อป้องกันไม่ให้เลย์เอาต์เปลี่ยนแปลง หากไม่ทราบขนาด นักพัฒนาแอปต้องระบุ layout=fill เพื่อแสดงรูปภาพที่ไม่มีขนาดซึ่งอยู่ภายในคอนเทนเนอร์ที่มีขนาด หรือจะใช้การนําเข้ารูปภาพนิ่งเพื่อดึงข้อมูลขนาดของรูปภาพจริงในฮาร์ดไดรฟ์ ณ เวลาที่สร้าง และรวมไว้ในรูปภาพก็ได้

// Image component with width and height specified
<Image src="/logo.jpg" alt="logo" height="200" width="100" />

// Image component with layout specified
<Image src="/hero.jpg" layout="fill" objectFit="cover" alt="hero" />

// Image component with image import
import Image from 'next/image'
import logo from './logo.png'

function Logo() {
  return <Image src={logo} alt="logo" />
}

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

อำนวยความสะดวกด้านการตอบสนอง

หากต้องการให้รูปภาพปรับเปลี่ยนตามอุปกรณ์ นักพัฒนาซอฟต์แวร์ต้องตั้งค่าแอตทริบิวต์ srcset และ sizes ในองค์ประกอบ <img> เราจึงต้องการลดความซับซ้อนนี้ด้วยคอมโพเนนต์รูปภาพ เราออกแบบคอมโพเนนต์รูปภาพ Next.js ให้ตั้งค่าแอตทริบิวต์เพียงครั้งเดียวต่อแอปพลิเคชัน โดยเราจะนำพารามิเตอร์เหล่านี้ไปใช้กับอินสแตนซ์ทั้งหมดของคอมโพเนนต์รูปภาพตามโหมดเลย์เอาต์ เราจึงหาวิธีแก้ปัญหา 3 อย่างดังนี้

  1. พร็อพเพอร์ตี้ deviceSizes: พร็อพเพอร์ตี้นี้ใช้เพื่อกําหนดค่าจุดหยุดชั่วคราวแบบครั้งเดียวตามอุปกรณ์ที่พบบ่อยในฐานผู้ใช้แอปพลิเคชันได้ ค่าเริ่มต้นของเบรกพอยท์จะรวมอยู่ในไฟล์การกำหนดค่า
  2. พร็อพเพอร์ตี้ imageSizes: พร็อพเพอร์ตี้นี้ยังกําหนดค่าได้เพื่อใช้รับขนาดรูปภาพที่สอดคล้องกับเบรกพอยต์ขนาดอุปกรณ์
  3. แอตทริบิวต์ layout ในรูปภาพแต่ละรูป: ใช้เพื่อระบุวิธีใช้พร็อพเพอร์ตี้ deviceSizes และ imageSizes สำหรับรูปภาพแต่ละรูป ค่าที่รองรับสำหรับโหมดเลย์เอาต์คือ fixed, fill, intrinsic และ responsive

เมื่อมีการขอรูปภาพด้วยโหมดเลย์เอาต์ responsive หรือ fill Next.js จะระบุรูปภาพที่จะแสดงโดยพิจารณาจากขนาดของอุปกรณ์ที่ขอหน้าเว็บและตั้งค่า srcset และ sizes ในรูปภาพอย่างเหมาะสม

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

หน้าจอแล็ปท็อป หน้าจอโทรศัพท์
เลย์เอาต์ = Intrinsic: ปรับขนาดให้เล็กลงเพื่อให้พอดีกับความกว้างของคอนเทนเนอร์ในวิวพอร์ตขนาดเล็ก ไม่ขยายขนาดเกินขนาดเดิมของรูปภาพในวิวพอร์ตที่ใหญ่ขึ้น ความกว้างของคอนเทนเนอร์อยู่ที่ 100%
รูปภาพภูเขาที่แสดงตามที่เป็นอยู่ รูปภาพภูเขาลดขนาดลงแล้ว
เลย์เอาต์ = คงที่: รูปภาพไม่ปรับเปลี่ยนตามขนาดหน้าจอ ความกว้างและความสูงจะคงที่คล้ายกับองค์ประกอบ `` โดยไม่คำนึงถึงอุปกรณ์ที่แสดงผล
รูปภาพภูเขาที่แสดงตามที่เป็นอยู่ รูปภาพภูเขาที่แสดงอยู่ไม่พอดีกับหน้าจอ
เลย์เอาต์ = ปรับเปลี่ยนตามพื้นที่โฆษณา: ปรับขนาดลงหรือขึ้นตามความกว้างของคอนเทนเนอร์ในวิวพอร์ตต่างๆ โดยคงสัดส่วนภาพไว้
รูปภาพภูเขาที่ปรับขนาดให้พอดีกับหน้าจอ รูปภาพภูเขาลดขนาดลงให้พอดีกับหน้าจอ
เลย์เอาต์ = ขยาย: ยืดความกว้างและความสูงให้เต็มคอนเทนเนอร์หลัก (กำหนดความกว้างของ <div> หลักเป็น 300*500 ในตัวอย่างนี้)
ภาพที่แสดงผลให้พอดีกับขนาด 300*500 ภาพที่แสดงผลให้พอดีกับขนาด 300*500
รูปภาพที่แสดงผลสำหรับเลย์เอาต์ต่างๆ

มีฟีเจอร์การโหลดแบบ Lazy Loading ในตัว

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

  • ระบุแอตทริบิวต์ loading: เบราว์เซอร์สมัยใหม่ทั้งหมดรองรับ
  • ใช้ Intersection Observer API: การสร้างโซลูชันการโหลดแบบเลื่อนเวลาอย่างละเอียดต้องใช้ความพยายาม รวมถึงการออกแบบและการใช้งานที่รอบคอบ นักพัฒนาซอฟต์แวร์อาจไม่มีเวลาดำเนินการดังกล่าวเสมอไป
  • นําเข้าไลบรารีของบุคคลที่สามเพื่อโหลดรูปภาพแบบ Lazy Loading: คุณอาจต้องทํางานเพิ่มเติมเพื่อประเมินและผสานรวมไลบรารีของบุคคลที่สามที่เหมาะสมสําหรับการโหลดแบบ Lazy Loading

ในคอมโพเนนต์รูปภาพของ Next.js ระบบจะตั้งค่าการโหลดเป็น "lazy" โดยค่าเริ่มต้น ระบบจะใช้การโหลดแบบ Lazy Loading โดยใช้ Intersection Observer ซึ่งใช้ได้กับเบราว์เซอร์สมัยใหม่ส่วนใหญ่ นักพัฒนาแอปไม่จําเป็นต้องดําเนินการใดๆ เพิ่มเติมเพื่อเปิดใช้ แต่สามารถปิดใช้ได้หากจําเป็น

โหลดรูปภาพที่สำคัญล่วงหน้า

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

<link rel="preload" as="image" href="important.png">

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

<Image src="/hero.jpg" alt="hero" height="400" width="200" priority />

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

แนะนำให้ใช้โฮสติ้งรูปภาพประสิทธิภาพสูง

เราขอแนะนำให้ใช้ CDN สำหรับรูปภาพเพื่อเพิ่มประสิทธิภาพรูปภาพโดยอัตโนมัติ และ CDN ดังกล่าวยังรองรับรูปแบบรูปภาพที่ทันสมัย เช่น WebP และ AVIF ด้วย คอมโพเนนต์รูปภาพ Next.js ใช้ CDN รูปภาพโดยค่าเริ่มต้นโดยใช้สถาปัตยกรรมโปรแกรมโหลด ตัวอย่างต่อไปนี้แสดงให้เห็นว่าโปรแกรมโหลดอนุญาตให้กําหนดค่า CDN ในไฟล์การกําหนดค่า Next.js

module.exports = {
  images: {
    loader: 'imgix',
    path: 'https://ImgApp/imgix.net',
  },
}

การกำหนดค่านี้จะทำให้นักพัฒนาแอปสามารถใช้ URL สัมพัทธ์ในแหล่งที่มาของรูปภาพ และเฟรมเวิร์กจะเชื่อมโยง URL สัมพัทธ์เข้ากับเส้นทาง CDN เพื่อสร้าง URL ที่สมบูรณ์ ระบบรองรับ CDN รูปภาพยอดนิยม เช่น Imgix, Cloudinary และ Akamai สถาปัตยกรรมรองรับการใช้ผู้ให้บริการระบบคลาวด์ที่กำหนดเองด้วยการใช้ฟังก์ชัน loader ที่กําหนดเองสําหรับแอป

รองรับรูปภาพที่โฮสต์ด้วยตนเอง

อาจมีกรณีที่เว็บไซต์ใช้ CDN รูปภาพไม่ได้ ในกรณีเช่นนี้ คอมโพเนนต์รูปภาพต้องรองรับรูปภาพที่โฮสต์เอง คอมโพเนนต์รูปภาพ Next.js ใช้เครื่องมือเพิ่มประสิทธิภาพรูปภาพเป็นเซิร์ฟเวอร์รูปภาพในตัวที่มี API คล้าย CDN เครื่องมือเพิ่มประสิทธิภาพจะใช้ Sharp สำหรับการเปลี่ยนรูปแบบรูปภาพเวอร์ชันที่ใช้งานจริงหากติดตั้งไว้ในเซิร์ฟเวอร์ ไลบรารีนี้เป็นตัวเลือกที่ดีสำหรับทุกคนที่ต้องการสร้างไปป์ไลน์การเพิ่มประสิทธิภาพรูปภาพของตนเอง

รองรับการโหลดแบบเป็นขั้นๆ

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

คอมโพเนนต์รูปภาพ Next.js รองรับการโหลดแบบเป็นขั้นๆ สำหรับรูปภาพผ่านพร็อพเพอร์ตี้ placeholder สามารถใช้เป็น LQIP (ตัวยึดตําแหน่งรูปภาพคุณภาพต่ำ) เพื่อแสดงรูปภาพคุณภาพต่ำหรือเบลอขณะที่รูปภาพจริงโหลด

ผลกระทบ

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

เมื่อ Leboncoin ย้ายข้อมูล Frontend JavaScript รุ่นเดิมไปยัง Next.js ทางบริษัทยังได้อัปเกรดไปป์ไลน์รูปภาพเพื่อใช้คอมโพเนนต์รูปภาพ Next.js ด้วย ในหน้าที่ย้ายข้อมูลจาก <img> ไปยัง next/image LCP ลดลงจาก 2.4 วินาทีเป็น 1.7 วินาที จำนวนไบต์ของรูปภาพที่ดาวน์โหลดทั้งหมดสำหรับหน้าเว็บลดลงจาก 663 KB เป็น 326 KB (โดยมีไบต์รูปภาพที่โหลดแบบ Lazy Loading ประมาณ 100 kB)

บทเรียนที่ได้เรียนรู้

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

วาล์วควบคุมแรงดันอาจก่อให้เกิดอันตรายมากกว่าผลดี

ในคอมโพเนนต์รูปภาพ Next.js รุ่นแรกๆ เรามีแอตทริบิวต์ unsized ที่อนุญาตให้นักพัฒนาแอปข้ามข้อกำหนดการปรับขนาดและใช้รูปภาพที่มีขนาดที่ไม่ระบุได้ เราคิดว่าการดำเนินการนี้จำเป็นในกรณีที่ไม่สามารถทราบความสูงหรือความกว้างของรูปภาพล่วงหน้า อย่างไรก็ตาม เราสังเกตเห็นว่าผู้ใช้แนะนำแอตทริบิวต์ unsized ในปัญหา GitHub เป็นวิธีแก้ปัญหาที่ครอบคลุมสำหรับปัญหาเกี่ยวกับข้อกำหนดด้านขนาด แม้ในกรณีที่ผู้ใช้สามารถแก้ปัญหาด้วยวิธีที่จะไม่ทำให้ CLS แย่ลง หลังจากนั้นเราได้เลิกใช้งานและนำแอตทริบิวต์ unsized ออก

แยกความยุ่งยากที่มีประโยชน์ออกจากความรำคาญที่ไร้จุดหมาย

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

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

หาจุดสมดุลระหว่างฟีเจอร์เพื่อความสะดวกและการเพิ่มประสิทธิภาพ

หากคอมโพเนนต์รูปภาพของคุณไม่มีฟังก์ชันการทำงานใดๆ เลย แต่จะสร้าง "การขัดข้องอันเป็นประโยชน์" ให้กับผู้ใช้ นักพัฒนาแอปก็มักจะไม่ต้องการนำมาใช้ เราพบว่าแม้ว่าฟีเจอร์ด้านประสิทธิภาพ เช่น การปรับขนาดรูปภาพและการสร้างค่า srcset โดยอัตโนมัติจะมีความสำคัญมากที่สุด ฟีเจอร์ที่อำนวยความสะดวกสำหรับนักพัฒนาซอฟต์แวร์ เช่น การโหลดแบบ Lazy Loading โดยอัตโนมัติและตัวยึดตำแหน่งแบบเบลอในตัว ยังช่วยกระตุ้นความสนใจในคอมโพเนนต์รูปภาพของ Next.js ด้วย

กำหนดแผนกลยุทธ์สำหรับฟีเจอร์ต่างๆ เพื่อกระตุ้นการนำไปใช้

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

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

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

บทสรุป

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

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

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