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

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

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

รูปภาพเป็นสาเหตุที่พบบ่อยของจุดคอขวดด้านประสิทธิภาพสำหรับเว็บแอปพลิเคชัน และสิ่งสำคัญสำหรับการเพิ่มประสิทธิภาพ รูปภาพที่ไม่ได้เพิ่มประสิทธิภาพมีส่วนทำให้เกิดการขยายหน้าเว็บ และปัจจุบันคิดเป็นกว่า 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 ส่วน ดังนี้

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

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

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

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