[Next.JS] การมาของ Image Optimization แบบ Native 😍

W.Songsak
3 min readNov 2, 2020

--

หลังจากได้นั่งดู live ของงาน Next.js conf มีอันนึงที่ถูกเพิ่มเข้ามาใน Next.js version 10 แล้วรู้สึกว่านี่และคือสิ่งที่ Framework สมัยใหม่ควรใส่มาเป็น Default

👉TLDR;

- ตั้งแต่ Next.js เวอร์ชั่น 10.0.0 เป็นต้นไป จะมี built-in Image component และการทำ Image Optimize ให้อัตโนมัติ

- เจ้า Image Component (next/image) เนี่ย ถูกเขียนโดยการ extends จากแท็ก <img> ของ HTML อีกทีนึง

- Next.js จะทำการ Optimize รูปให้เราอัตโนมัติ โดยหลังการทำงานคร่าว ๆ คือ การปรับรูปให้เหมาะสมกับการใช้งานมากขึ้น เช่น format, resize, lazy load etc..

👉 เกริ่นสักนิด 👈

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

https://kinsta.com/blog/optimize-images-for-web/

อีกทั้งยังมีปัญหามากมาย ทั้งการใช้รูปที่ไม่เหมาะสม เช่น ฟอร์เมทของรูปที่ยังใช้เป็นแบบเก่า ไม่ว่าจะเป็น .png หรือ .jpg ซึ่งมีขนาดใหญ่เมื่อเทียบกับฟอร์เมทรูปภาพสมัยใหม่เช่น .webp เป็นต้น

https://crystallize.com/comics/png-vs-webp

รวมไปถึงปัญหาเวลาที่รูปยังโหลดไม่เสร็จแต่เว็บได้ถูก paint ไปเรียบร้อย พอได้รูปมาเว็บของเราก็จะเกิดอาการ layout เลื่อน(Cumulative Layout Shift: CLS) และปัญหาอื่น ๆ อีกมากมาย 🙄

Cumulative Layout Shift: CLS

Image Compoent By Next.js In a Nutshell

  • การ optimize โดยการ compression
  • การทำ image resizing แยกเซตของรูปตามขนาดหน้าจอ(Responsive images: srcset,sizes)
  • ทำ lazy loading ให้อัตโนมัติ ง่ายๆ คือ ถ้ารูปไหนยังไม่โชว์ที่หน้าจอของผู้ใช้รูปนั้นจะยังไม่ถูกโหลดให้เปลือง bandwidth ช่วยลด Largest Contentful Paint(LCP)
  • แปลงรูปให้เป็นฟอร์เมท WebP อัตโนมัติ

ลองใช้งาน 💅

ก่อนที่เราจะสามารถใช้งาน Image ที่มาจาก Next.js ได้เราต้องลง Next.js version 10.0.0+ ก่อน ซึ่งถ้าหากเราขึ้นโปรเจคใหม่ด้วยคำสั่ง npx create-next-app เราจะได้เวอร์ชั่นล่าสุดมาโดยอัตโนมัติครับ

สิ่งที่ Image Compent provide ให้ผ่าน props มีหลักๆ ดังนี้ครับ

  • src — [required]กำหนด path ของรูปภาพ รองรับทั้ง static path และ URL path
  • width and height —[required] ใช้สำหรับกำหนดขนาดของรูปภาพ โดยมีหน่วยเป็น pixel(ตอนใช้ให้ใส่เป็นตัวเลขนะ ไม่ต้องมีหน่วยต่อท้าย) การกำหนดขนาดของรูปมีข้อดีคือ ช่วยกัน Layout เลื่อนหลังจากที่รูปภาพถูกโหลดเสร็จ(Cumulative Layout Shift: CLS) ได้อีกด้วยนะ
  • sizes — ใช้กำหนดว่ารูปขนาดเท่าไหร่ที่จะโชว์สำหรับแต่ละขนาดหน้าจอ
  • quality — ใช้กำหนดว่าเราต้องการลดคุภาพของรูปไปกี่เปอร์เซ็น ซึ่งขนาดไฟล์จะลดลงตามจำนวน % ที่มากขึ้น(แต่สิ่งที่ต้องแลกคือ คุณภาพของรูปจะลดลงตามไปด้วย), ค่าที่เขาตั้งเริ่มต้นให้ คือ 75

การใช้งาน

ให้ทำการ import component เข้ามา ตามคำสั่งด้านล่าง

import Image from 'next/image'

หลังจากนั้นเวลาที่เราต้องการจะใช้ก็แค่จากเดิมที่ใช้แท็ก <img> เราก็แค่เปลี่ยนมาเป็น <Image> แทน พร้อมกับ props ที่ required

<Image
src="/me.png"
alt="Picture of the author"
width={500}
height={500}
/>

ตัวอย่างเช่น ผมสร้างไฟล์ Home.js

import Image from 'next/image'

function Home() {
return (
<>
<h1>My Homepage</h1>
<Image
src="/me.png"
alt="Picture of the author"
width={500}
height={500}
/>
<p>Welcome to my homepage!</p>
</>
)
}

export default Home

ถ้าต้องการใช้รูปจาก external source ให้ทำดังนี้

  • สร้างไฟล์ next.config.js ที่ root ของโปรเจค
  • เพิ่ม images config เข้าไปภายใต้ไฟล์ next.config.js
module.exports = {
images: {
domains: ['example.com', 'images.unsplash.com'], //ระบุ domain ที่ต้องการ, ใส่ได้หลาย domain
},
}

ตัวอย่างผลลัพธ์บนหน้าเว็บ 😎

จบแล้วครับ 🎉🎉🎉

หากสนใจสามารถอ่านต่อได้ตามลิงค์ด้านล่างครับ

--

--

W.Songsak
W.Songsak

Written by W.Songsak

Software Engineer 👩‍💻 Doing: React, React Native & NextJS also Flutter(Side projects) 💅 Todo: UI/UX

No responses yet