คอมโพเนนต์รูปภาพสรุปแนวทางปฏิบัติแนะนำด้านประสิทธิภาพและมีโซลูชันที่พร้อมใช้งานทันทีเพื่อเพิ่มประสิทธิภาพรูปภาพ
รูปภาพเป็นสาเหตุที่พบบ่อยของจุดคอขวดด้านประสิทธิภาพสำหรับเว็บแอปพลิเคชัน และสิ่งสำคัญสำหรับการเพิ่มประสิทธิภาพ รูปภาพที่ไม่ได้เพิ่มประสิทธิภาพมีส่วนทำให้เกิดการขยายหน้าเว็บ และปัจจุบันคิดเป็นกว่า 70% ของน้ำหนักหน้าเว็บรวมในหน่วยไบต์ที่เปอร์เซ็นไทล์ที่ 90 การเพิ่มประสิทธิภาพรูปภาพแบบต่างๆ ต้องมี "คอมโพเนนต์รูปภาพ" อัจฉริยะที่มีโซลูชันประสิทธิภาพรวมไว้เป็นค่าเริ่มต้น
ทีม Aurora ทำงานร่วมกับ Next.js เพื่อสร้างคอมโพเนนต์ดังกล่าวขึ้นมา 1 รายการ โดยมีเป้าหมายเพื่อสร้างเทมเพลตรูปภาพที่เพิ่มประสิทธิภาพซึ่งนักพัฒนาเว็บปรับแต่งเพิ่มเติมได้ คอมโพเนนต์นี้ทำหน้าที่เป็นโมเดลที่ดีและกำหนดมาตรฐานในการสร้างคอมโพเนนต์รูปภาพในเฟรมเวิร์ก ระบบจัดการเนื้อหา (CMS) และชุดซอฟต์แวร์อื่นๆ เราใช้คอมโพเนนต์ที่คล้ายกันสำหรับ Nuxt.js แล้วและกำลังทำงานร่วมกับ Angular ในการเพิ่มประสิทธิภาพรูปภาพในเวอร์ชันต่อๆ ไป โพสต์นี้กล่าวถึงวิธีที่เราออกแบบคอมโพเนนต์รูปภาพ Next.js และบทเรียนต่างๆ ที่เราได้เรียนรู้มา
ปัญหาและโอกาสในการเพิ่มประสิทธิภาพรูปภาพ
รูปภาพไม่เพียงแต่ส่งผลต่อประสิทธิภาพเท่านั้น แต่ยังส่งผลต่อธุรกิจอีกด้วย จำนวนรูปภาพในหน้าเว็บเป็นตัวคาดการณ์ Conversion ที่มากที่สุดเป็นอันดับสองของผู้ใช้ที่เข้าชมเว็บไซต์ เซสชันที่ผู้ใช้ทำ 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">
ควรตั้งค่าความกว้างและความสูงเพื่อให้สัดส่วนภาพของรูปภาพที่แสดงผลใกล้เคียงกับสัดส่วนภาพตามธรรมชาติ ความแตกต่างในสัดส่วนภาพที่มีนัยสำคัญอาจส่งผลให้รูปภาพบิดเบี้ยว พร็อพเพอร์ตี้ที่ค่อนข้างใหม่ซึ่งช่วยให้คุณระบุสัดส่วนภาพใน CSS ได้ ซึ่งช่วยปรับขนาดรูปภาพให้ปรับเปลี่ยนตามอุปกรณ์ได้ในขณะที่ป้องกัน CLS
รูปภาพขนาดใหญ่อาจส่งผลเสียต่อ LCP
ยิ่งไฟล์ภาพมีขนาดใหญ่เท่าไร ก็ยิ่งใช้เวลาดาวน์โหลดนานขึ้นเท่านั้น รูปภาพขนาดใหญ่อาจเป็นรูปภาพ "หลัก" ของหน้าเว็บหรือองค์ประกอบที่สำคัญที่สุดในวิวพอร์ตซึ่งมีหน้าที่ทริกเกอร์ Largest Contentful Paint (LCP) รูปภาพที่เป็นส่วนหนึ่งของเนื้อหาที่สำคัญและใช้เวลาดาวน์โหลดนานจะทำให้ LCP ล่าช้า
ในหลายกรณี นักพัฒนาซอฟต์แวร์สามารถลดขนาดรูปภาพด้วยการบีบอัดที่ดีขึ้นและการใช้รูปภาพที่ปรับเปลี่ยนตามอุปกรณ์ได้ แอตทริบิวต์ srcset
และ sizes
ขององค์ประกอบ <img>
ช่วยในการสร้างไฟล์ภาพขนาดต่างๆ จากนั้นเบราว์เซอร์จะสามารถเลือกหน้าจอที่เหมาะสมได้โดยขึ้นอยู่กับขนาดของหน้าจอและความละเอียด
การบีบอัดรูปภาพที่ไม่ดีอาจส่งผลเสียต่อ LCP
รูปแบบรูปภาพที่ทันสมัย เช่น AVIF หรือ WebP ให้การบีบอัดที่ดีกว่ารูปแบบ JPEG และ PNG ที่ใช้กันโดยทั่วไป การบีบอัดที่ดีขึ้นจะช่วยลดขนาดไฟล์ลง 25% ถึง 50% ในบางกรณีเพื่อให้ได้ภาพที่มีคุณภาพเท่ากัน การลดนี้ช่วยให้ดาวน์โหลดได้เร็วขึ้นและใช้อินเทอร์เน็ตน้อยลง แอปควรให้บริการรูปแบบรูปภาพที่ทันสมัยแก่เบราว์เซอร์ที่รองรับรูปแบบเหล่านี้
การโหลดรูปภาพที่ไม่จำเป็นจะส่งผลเสียต่อ 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 เพื่อออกแบบและimplementคอมโพเนนต์รูปภาพ ซึ่งใช้แทนดรอปอินสำหรับองค์ประกอบ <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 ส่วน ดังนี้
- พร็อพเพอร์ตี้
deviceSizes
: พร็อพเพอร์ตี้นี้ใช้กำหนดค่าเบรกพอยท์ 1 ครั้งตามอุปกรณ์ที่ใช้ร่วมกับฐานผู้ใช้แอปพลิเคชันได้ ค่าเริ่มต้นของเบรกพอยท์จะรวมอยู่ในไฟล์การกำหนดค่า - พร็อพเพอร์ตี้
imageSizes
: และยังเป็นพร็อพเพอร์ตี้ที่กำหนดค่าได้ซึ่งใช้เพื่อรับขนาดรูปภาพที่สอดคล้องกับเบรกพอยท์ขนาดอุปกรณ์ด้วย - แอตทริบิวต์
layout
ในแต่ละรูปภาพ: ใช้เพื่อระบุวิธีใช้พร็อพเพอร์ตี้deviceSizes
และimageSizes
สำหรับแต่ละรูปภาพ ค่าที่รองรับสำหรับโหมดเลย์เอาต์คือfixed
,fill
,intrinsic
และresponsive
เมื่อมีการขอรูปภาพด้วยโหมดเลย์เอาต์ปรับเปลี่ยนตามพื้นที่โฆษณาหรือ fill Next.js จะระบุรูปภาพที่จะแสดงโดยอิงตามขนาดของอุปกรณ์ที่ขอหน้า และตั้งค่า srcset
และ sizes
ในรูปภาพอย่างเหมาะสม
การเปรียบเทียบต่อไปนี้แสดงวิธีใช้โหมดเลย์เอาต์เพื่อควบคุมขนาดของรูปภาพในหน้าจอต่างๆ เราใช้รูปภาพสาธิตที่แชร์ในเอกสาร Next.js โดยดูบนโทรศัพท์และแล็ปท็อปมาตรฐาน
หน้าจอแล็ปท็อป | หน้าจอโทรศัพท์ |
---|---|
เลย์เอาต์ = ภายใน: ลดขนาดลงให้พอดีกับความกว้างของคอนเทนเนอร์ในวิวพอร์ตขนาดเล็ก ไม่ขยายเกินกว่าขนาดภายในของรูปภาพในวิวพอร์ตที่ใหญ่ขึ้น ความกว้างของคอนเทนเนอร์อยู่ที่ 100% | |
เลย์เอาต์ = คงที่: รูปภาพไม่ตอบสนอง ความกว้างและความสูงคงที่คล้ายกับองค์ประกอบ "" โดยไม่คำนึงถึงอุปกรณ์ที่แสดงภาพ | |
เลย์เอาต์ = ปรับเปลี่ยนตามพื้นที่โฆษณา: ปรับขนาดลงหรือปรับขนาดตามความกว้างของคอนเทนเนอร์ในวิวพอร์ตต่างๆ โดยคงสัดส่วนภาพไว้ | |
เลย์เอาต์ = เติมพื้น: ความกว้างและความสูงที่ยืดจนเต็มคอนเทนเนอร์หลัก (ระดับบนสุด " " ในตัวอย่างนี้กำหนดความกว้างเป็น 300*500)
|
|
มีการโหลดแบบ Lazy Loading ในตัว
คอมโพเนนต์รูปภาพมีโซลูชันการโหลดแบบ Lazy Loading ที่มีประสิทธิภาพในตัวโดยค่าเริ่มต้น เมื่อใช้องค์ประกอบ <img>
จะมีตัวเลือกแบบเนทีฟอยู่ 2-3 ตัวเลือกสำหรับการโหลดแบบ Lazy Loading แต่ทั้งหมดมีข้อด้อยที่ทำให้ใช้งานได้ยาก นักพัฒนาแอปอาจใช้วิธีใดด้านหนึ่งในการโหลดแบบ Lazy Loading ต่อไปนี้
- ระบุแอตทริบิวต์
loading
: วิธีนี้ใช้งานง่าย แต่ปัจจุบันยังไม่รองรับในบางเบราว์เซอร์ - ใช้ Intersection Observer API: การสร้างโซลูชันการโหลดแบบ Lazy Loading ที่กำหนดเองต้องใช้ความพยายามและการออกแบบและการนำไปใช้อย่างรอบคอบ นักพัฒนาแอปอาจไม่มีเวลาดูแลเรื่องนี้เสมอไป
- นำเข้าไลบรารีของบุคคลที่สามเพื่อโหลดรูปภาพแบบ 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 รูปภาพเพื่อการเพิ่มประสิทธิภาพรูปภาพอัตโนมัติ ทั้งยังรองรับรูปแบบรูปภาพที่ทันสมัย เช่น 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 เพื่อเปลี่ยนรูปแบบรูปภาพที่ใช้งานจริงหากมีการติดตั้งไว้ในเซิร์ฟเวอร์ ไลบรารีนี้เป็นตัวเลือกที่ดีสำหรับทุกคนที่ต้องการสร้างไปป์ไลน์การเพิ่มประสิทธิภาพรูปภาพของตนเอง
รองรับการโหลดแบบต่อเนื่อง
การโหลดแบบโพรเกรสซีฟเป็นเทคนิคที่ใช้ดึงความสนใจของผู้ใช้ด้วยการแสดงรูปภาพตัวยึดตําแหน่งซึ่งมักจะมีคุณภาพต่ำกว่ามากในขณะที่รูปภาพจริงโหลดขึ้น ปรับปรุงประสิทธิภาพที่รับรู้ไปแล้วและปรับปรุงประสบการณ์ของผู้ใช้ โดยสามารถใช้ร่วมกับการโหลดแบบ Lazy Loading สำหรับรูปภาพครึ่งหน้าล่างหรือครึ่งหน้าบนได้
คอมโพเนนต์รูปภาพ Next.js รองรับการโหลดแบบโพรเกรสซีฟสำหรับรูปภาพผ่านพร็อพเพอร์ตี้ placeholder ซึ่งใช้เป็น LQIP (ตัวยึดตำแหน่งรูปภาพคุณภาพต่ำ) สำหรับแสดงรูปภาพคุณภาพต่ำหรือเบลอขณะที่รูปภาพจริงโหลดได้
มีอิทธิพล
เมื่อผสานการเพิ่มประสิทธิภาพข้างต้นทั้งหมดแล้ว เราพบว่าคอมโพเนนต์รูปภาพ Next.js ในเวอร์ชันที่ใช้งานจริงประสบความสำเร็จ และยังทำงานร่วมกับชุดซอฟต์แวร์อื่นๆ ในองค์ประกอบรูปภาพที่คล้ายกันอีกด้วย
เมื่อ Leboncoin ย้ายข้อมูลฟรอนท์เอนด์ของ JavaScript เดิมไปยัง Next.js องค์กรก็ได้อัปเกรดไปป์ไลน์รูปภาพเพื่อใช้คอมโพเนนต์รูปภาพ Next.js ในหน้าเว็บที่ย้ายข้อมูลจาก <img>
ไปยังรายการถัดไป/รูปภาพ LCP ลดลงจาก 2.4 วินาทีเป็น 1.7 วินาที ไบต์รวมของรูปภาพที่ดาวน์โหลดสำหรับหน้าเว็บเปลี่ยนจาก 663kB เป็น 326kB (โดยประมาณ 100kB ของไบต์รูปภาพที่โหลดแบบ Lazy Loading)
บทเรียนที่ได้เรียนรู้
ทุกคนที่สร้างแอป Next.js จะได้รับประโยชน์จากการใช้คอมโพเนนต์รูปภาพ Next.js เพื่อเพิ่มประสิทธิภาพ อย่างไรก็ตาม หากคุณต้องการสร้างบทคัดย่อด้านประสิทธิภาพที่คล้ายกันสำหรับเฟรมเวิร์กหรือ CMS อื่น เรามีบทเรียนบางส่วนที่เราได้เรียนรู้จากวิธีการนี้ซึ่งอาจเป็นประโยชน์กับคุณ
วาล์วความปลอดภัยก่อให้เกิดอันตรายมากกว่าผลดี
ในการเปิดตัวคอมโพเนนต์รูปภาพ Next.js ก่อนเปิดตัว เราได้ระบุแอตทริบิวต์ unsized
ที่อนุญาตให้นักพัฒนาซอฟต์แวร์ข้ามข้อกำหนดด้านขนาด และใช้รูปภาพที่มีขนาดที่ไม่ระบุได้ เราคิดว่านี่จะเป็นสิ่งจำเป็นในกรณีที่ไม่สามารถทราบความสูงหรือความกว้างของรูปภาพล่วงหน้าได้ อย่างไรก็ตาม เราพบว่าผู้ใช้แนะนำให้ใช้แอตทริบิวต์ unsized
ในปัญหา GitHub เป็นโซลูชันที่ครอบคลุมทั้งหมดสำหรับปัญหาข้อกำหนดด้านขนาด แม้ในกรณีที่ผู้ใช้อาจแก้ปัญหาด้วยวิธีที่ไม่ได้ทำให้ CLS แย่ลง หลังจากนั้น เราได้เลิกใช้งานและนำแอตทริบิวต์ unsized
ออก
แยกอุปสรรคที่เป็นประโยชน์ออกจากความน่ารำคาญไร้สาระ
ข้อกำหนดสำหรับการปรับขนาดรูปภาพคือตัวอย่างของ "จุดติดขัดที่เป็นประโยชน์" จำกัดการใช้คอมโพเนนต์ แต่ให้ประโยชน์ด้านประสิทธิภาพมากกว่าเพื่อแลกเปลี่ยน ผู้ใช้จะยอมรับข้อจำกัดได้ทันทีหากมองเห็นประโยชน์ด้านประสิทธิภาพที่เป็นไปได้อย่างชัดเจน ดังนั้นจึงควรอธิบายข้อดีข้อเสียนี้ไว้ในเอกสารประกอบและเนื้อหาที่เผยแพร่อื่นๆ เกี่ยวกับคอมโพเนนต์นั้นๆ
อย่างไรก็ตาม คุณสามารถค้นหาวิธีแก้ปัญหาเฉพาะหน้าสำหรับอุปสรรคดังกล่าวได้โดยที่ไม่กระทบต่อประสิทธิภาพ ตัวอย่างเช่น ในระหว่างการพัฒนาคอมโพเนนต์รูปภาพ Next.js เราได้รับการร้องเรียนว่าการค้นหาขนาดรูปภาพที่จัดเก็บอยู่ในเครื่องเป็นเรื่องน่ารำคาญ เราได้เพิ่มการนำเข้าภาพนิ่ง ซึ่งช่วยลดความซับซ้อนของกระบวนการนี้โดยการดึงข้อมูลขนาดสำหรับรูปภาพในเครื่องโดยอัตโนมัติในขณะสร้างโดยใช้ปลั๊กอิน Babel
หาสมดุลระหว่างฟีเจอร์อำนวยความสะดวกและการเพิ่มประสิทธิภาพ
หากคอมโพเนนต์รูปภาพไม่ทำอะไรเลยนอกจากทำให้ผู้ใช้มี "จุดรบกวนที่เป็นประโยชน์" นักพัฒนาซอฟต์แวร์ก็มีแนวโน้มที่จะไม่อยากใช้คอมโพเนนต์นี้ เราพบว่าแม้ฟีเจอร์ด้านประสิทธิภาพ เช่น การปรับขนาดรูปภาพและการสร้างค่า srcset
โดยอัตโนมัติจะเป็นสิ่งที่สำคัญที่สุด ฟีเจอร์อำนวยความสะดวกของนักพัฒนาซอฟต์แวร์ เช่น การโหลดแบบ Lazy Loading อัตโนมัติและตัวยึดตำแหน่งที่เบลอในตัวยังช่วยเพิ่มความสนใจในคอมโพเนนต์รูปภาพ Next.js ได้อีกด้วย
กำหนดแผนกลยุทธ์สำหรับฟีเจอร์ต่างๆ เพื่อกระตุ้นการนำไปใช้
การสร้างโซลูชันที่ลงตัวกับทุกสถานการณ์เป็นเรื่องที่ยากมาก คุณอาจอยากออกแบบบางสิ่งที่ทำงานได้ดีสำหรับผู้คน 75% แล้วบอกคนอีก 25% ว่า "ในกรณีเหล่านี้ องค์ประกอบนี้ไม่เหมาะกับคุณ"
ในทางปฏิบัติ กลยุทธ์นี้ไม่สอดคล้องกับเป้าหมายของคุณในฐานะผู้ออกแบบคอมโพเนนต์ คุณต้องการให้นักพัฒนาซอฟต์แวร์นำคอมโพเนนต์ไปใช้เพื่อรับประโยชน์ด้านประสิทธิภาพ ปัญหานี้อาจทำได้ยากหากมีผู้ใช้ที่ไม่สามารถย้ายข้อมูลและรู้สึกว่าออกจากการสนทนาได้ ผู้คนมักจะแสดงออกถึงความผิดหวัง ซึ่งนำไปสู่การรับรู้ในเชิงลบที่ส่งผลต่อการนำไปใช้
ขอแนะนำให้มีแผนกลยุทธ์สำหรับคอมโพเนนต์ที่ครอบคลุมกรณีการใช้งานที่สมเหตุสมผลทั้งหมดในระยะยาว นอกจากนี้คุณควรระบุอย่างชัดเจนในเอกสารประกอบเกี่ยวกับสิ่งที่ไม่รองรับและเหตุผล เพื่อกำหนดความคาดหวังเกี่ยวกับปัญหาที่คอมโพเนนต์จะต้องแก้ไข
บทสรุป
การใช้และการเพิ่มประสิทธิภาพรูปภาพมีความซับซ้อน นักพัฒนาแอปต้องหาจุดสมดุลระหว่างประสิทธิภาพกับคุณภาพของรูปภาพ ขณะเดียวกันก็รักษาประสบการณ์ที่ยอดเยี่ยมของผู้ใช้ด้วย จึงทำให้การเพิ่มประสิทธิภาพรูปภาพเป็นความพยายามในการสร้างผลกระทบสูงและมีค่าใช้จ่ายสูง
แทนที่จะต้องคอยปรับเปลี่ยนแอปทุกครั้ง เราได้ออกแบบเทมเพลตแนวทางปฏิบัติแนะนำที่นักพัฒนาซอฟต์แวร์ เฟรมเวิร์ก และชุดซอฟต์แวร์โครงสร้างพื้นฐานอื่นๆ สามารถใช้เป็นข้อมูลอ้างอิงสำหรับการใช้งานของตนเองได้ ประสบการณ์นี้จะมีประโยชน์จริงๆ เพราะเราสนับสนุนเฟรมเวิร์กอื่นๆ เกี่ยวกับองค์ประกอบรูปภาพเหล่านั้น
คอมโพเนนต์ Next.js Image ช่วยปรับปรุงผลลัพธ์ด้านประสิทธิภาพในแอปพลิเคชัน Next.js ได้เป็นอย่างดี ทั้งยังช่วยปรับปรุงประสบการณ์ของผู้ใช้ เราเชื่อว่านี่เป็นโมเดลที่ยอดเยี่ยมซึ่งจะทำงานได้ดีในระบบนิเวศในวงกว้าง และเราอยากรับฟังความคิดเห็นจากนักพัฒนาซอฟต์แวร์ที่ต้องการนำโมเดลนี้ไปใช้ในโปรเจ็กต์ของตัวเอง