มีอะไรใหม่บ้างใน Next.js 9
เป็นเวลากว่า 1 วันแล้วที่ Next.js ได้ปล่อยเวอร์ชัน 9 ออกมา คงถึงเวลาที่เราต้องอัพเดทกันแล้วซินะครับ ถ้างั้นไปดูสรุปสั้น ๆ จาก Next.js 9 กันดีกว่าว่ามีฟีเจอร์อะไรใหม่ ๆ บ้าง
Dynamic Routing จะไม่ใช่เรื่องยากอีกต่อไป
เราทราบกันดีว่าถ้า URL ของเราคือ /articles/intro-to-nextjs
เราจำเป็นต้องสร้างไฟล์ intro-to-nextjs.js ใต้โฟลเดอร์ pages/articles
การทำงานถึงจะถูกต้อง แต่หาก URL ของเราเป็น /articles/:slug
โดยส่วนของ :slug
สามารถเปลี่ยนแปลงได้ เราจะต้องออกแบบโฟลเดอร์ pages
อย่างไรให้ Next.js
เข้าใจ?
วิธีดั้งเดิมของ Next.js นั้นเราต้องทำการ ปรับแต่งเซิฟเวอร์ ด้วยตนเองซึ่งเป็นอะไรที่ค่อนข้างยุ่งยาก แพคเกจอย่าง next-routes จึงดูเป็นทางออกมากกว่า
สำหรับ Next.js 9 ที่พึ่งคลอดนั้นสนับสนุนการทำงานแบบ Dynamic Routing แต่ต้น ไม่แน่ใจว่าได้แรงบันดาลใจมาจาก Nuxt.js ของ Vue ที่ทำแบบนี้มาได้ชาติเศษแล้วรึเปล่า เพราะตัววิธีการนั้นมีความคล้ายคลึงกัน
สำหรับ Next นั้นถ้าอยากได้ URL เป็น /articles/:slug
สิ่งที่เราต้องทำคือสร้างโฟลเดอร์ pages/articles/[slug].js
จุดสำคัญอยู่ที่ส่วนเปลี่ยนแปลงได้ (dynamic segment) ต้องนิยามใต้เครื่องหมาย []
Next ไม่ได้จำกัดว่าคุณจะมี dynamic segment กี่จุดขอแค่ทุกจุดอยู่ใต้ []
ก็พอ เช่น /articles/[articleSlug]/comments/[commentId].js
ประกอบด้วย dynamic segments สองจุดคือ :articleSlug
ที่เป็นชื่อโฟลเดอร์ และ :commentId
ที่เป็นไฟล์
การจะดึงส่วนของ dynamic segments มาใช้นั้น ให้ดึงจากค่าของ query
ออกมาได้เลยครับ เช่น
1// URL: /articles/intro-to-next2// File: pages/articles/[slug].js3static async getInitialProps({ query }) {4 // slug = 'intro-to-next'5 const { slug } = query67 // นำค่า slug ไปใช้งานต่อได้8}
สร้างส่วนของ Backend API ใน Next.js ได้เลย
บางครั้งเราอยากสร้างส่วนของ API ผูกติดไว้กับการทำ Server-Side Rendering (SSR) ของ Next.js เราจึงทำการ ปรับแต่งเซิฟเวอร์ เพิ่มเติมให้ทั้งทำงานแบบ SSR ของ Next และสนับสนุนการให้บริการ API ที่เราเขียนเพิ่มเติม
Next 9 นั้นเพียงแค่เราสร้างโฟลเดอร์ api
ภายใต้โฟลเดอร์ pages
เราจะสามารถเรียกใช้ไฟล์ภายใต้ pages/api
นั้นได้เสมือนเป็น API ของเรา เช่นสร้างไฟล์ชื่อ pages/api/articles.js
เราจะได้ URL ไว้เรียกใช้คือ /api/articles
แน่นอนว่าการสร้างโฟลเดอร์และไฟล์นั้นอยู่ใต้ pages
เราจึงสามารถใช้ []
เพื่อทำ dynamic routing ได้ด้วย เช่น URL ที่ระบุเป็น /api/articles/intro-to-next
จะเข้าเรียกไฟล์ pages/api/articles/[slug].js
เป็นต้น
สิ่งหนึ่งที่ไฟล์ใต้ api
แตกต่างจากเพจทั่วไปคือต้องคืนกลับเป็น request handler function ไม่ใช่ React Component เช่น
1// pages/api/articles.js2export default function handle(req, res) {3 res.json({ articles: [] })4}
Prefetch เมื่อ Link นั้นแสดงผลใน Viewport
Next 9 นั้นจะใช้เทคนิคของ Intersection Observer เพื่อทำการ Prefetch Link ที่ปรากฎบนหน้าจอแล้ว ความหมายคือถ้าเรามี Link อยู่ในเพจของเรา แต่ Link นั้นยังไม่โผล่เข้ามาในส่วนแสดงผล (Viewport) Next ก็จะยังไม่ทำอะไร หากแต่เมื่อสิ่งนั้นปรากฎบน Viewport แล้วไซร์ Next.js ก็จะทำการ Prefetch ข้อมูลล่วงหน้า เมื่อผู้ใช้งานตัดสินใจคลิกลิงก์นี้ในภายหลังจะทำให้รู้สึกโหลดไวขึ้น เพราะ assets ที่จำเป็นนั้นถูกโหลดมาแล้ว
เราป้องกันการทำ prefetch ได้ด้วยการระบุค่า false ลงไปใน Link ดังนี้
1<Link href="/terms" prefetch={false}>2 <a>About US</a>3</Link>
สร้าง static pages ควบคู่ไปกับการทำ server-side rendeing แบบอัตโนมัติ
static site นั้นเร็ว Next.js ก็สนับสนุนการสร้าง static site ผ่านตัวมันมานานแล้วเช่นกัน แต่นั่นทำให้คุณต้องเลือก เพราะถ้าคุณสร้างเว็บไซต์แบบ static ด้วย Next แล้ว คุณจะทำ server-side rendering ไปด้วยไม่ได้
ทำไมฉันต้องเลือกหละ? Next 9 ตัดสินใจที่จะพิจารณาส่วนของ getInitialProps
จากไฟล์ต่าง ๆ ในโฟลเดอร์ pages
หากไฟล์ไหนไม่ได้มีการ "หยุด" การทำงานเพื่อไปรอการร้องขอข้อมูลจาก API server นั่นแสดงว่าไฟล์นี้ทำเป็น static page ได้ Next จะดำเนินการสร้างไฟล์นี้ให้เป็น static page ในขณะที่เพจอื่นที่ยังต้องการรอข้อมูลจาก API มาทำ SSR ก็ยังคงได้รับการทำงานแบบ SSR จาก Next เช่นเดิม
ไม่ยุ่งยากกับการใช้ TypeScript อีกต่อไป
ไม่จำเป็นต้องใช้ @zeit/next-typescript
ตั้งค่า .babelrc
หรือ next.config.js
อีกต่อไป เพราะ Next.js จะจัดการไฟล์ TypeScript ให้กับคุณอัตโนมัติ เพียงแค่เปลี่ยนนามสกุลไฟล์จาก .js
เป็น .tsx
แถมยังสร้างไฟล์ tsconfig.json
ให้อัตโนมัติด้วยหากในโปรเจคของเราไม่มีไฟล์นี้มาก่อน
อื่น ๆ
Next.js 9 นั้นไม่ได้มีแค่สิ่งที่ผมได้แสดงในบทความนี้ หากแต่ยังมีการปรับปรุงประสิทธิภาพอื่น ๆ อีกมาก เช่น
- มีการแสดงผลไอคอนเล็ก ๆ ด้านล่างขวาของเพจเมื่อมีการคอมไพล์โค้ดใหม่
- ลบโค้ดของเซิฟเวอร์ที่ไม่ได้ใช้ออกไปจากโค้ดส่วนไคลเอนต์ ทำให้ bundle size ของไคลเอนต์มีขนาดเล็กลง
- เพิ่มประสิทธืภาพการทำงานกับ AMP
- การรายงานข้อมูลของการ build ที่ดีขึ้น
การปรับปรุงประสิทธิภาพที่น่าสนใจในอนาคต
Google ได้ร่วมมือกับ Next ด้วยการเสนอ RFC และ pull requests ที่ช่วยปรับปรุงประสิทธิภาพของ Next มีหลายตัวมากที่น่าสนใจครับ และตัวอย่างหนึ่งที่อยากนำเสนอก็คือ module/nomodule pattern
เราทราบกันดีว่ามีหลายสิ่งที่เราต้องการเขียนแต่ไม่สนับสนุนให้ทำในเบราเซอร์รุ่นเก่า แต่นั่นไม่เป็นปัญหาสำหรับเบราเซอร์ที่ใหม่กว่า เช่น เบราเซอร์เก่า ๆ ไม่สนับสนุนการทำงานกับ Async/Await แต่เบราเซอร์ยุคใหม่นั้นสนับสนุน ครั้นจะเอา polyfills ใส่ลงไปเพื่อให้เบราเซอร์เก่าทำงานได้ มันกลับเป็นหอกสองคมที่เบราเซอร์ใหม่ต้องรับภาระในการโหลดโค้ดส่วนเกิดแทน Next จึงมี RFC ที่เสนอให้ใช้หลักการของ module/nomodule pattern เพื่อสร้าง build แยกสำหรับเบราเซอร์ใหม่และเก่า ซึ่งหลักการนี้ทำมาใน Vue/Nuxt.js มาสามชาติเศษแล้ว
สรุป
Next.js 9 นั้นยังมีการปรับปรุงเรื่องอื่นอีก เพื่อน ๆ ที่สนใจสามารถเข้าไปอ่านได้จากเอกสารอ้างอิงท้ายบทความครับ
เอกสารอ้างอิง
Next.js 9. Retrieved July, 9, 2019, from https://nextjs.org/blog/next-9
สารบัญ
- Dynamic Routing จะไม่ใช่เรื่องยากอีกต่อไป
- สร้างส่วนของ Backend API ใน Next.js ได้เลย
- Prefetch เมื่อ Link นั้นแสดงผลใน Viewport
- สร้าง static pages ควบคู่ไปกับการทำ server-side rendeing แบบอัตโนมัติ
- ไม่ยุ่งยากกับการใช้ TypeScript อีกต่อไป
- อื่น ๆ
- การปรับปรุงประสิทธิภาพที่น่าสนใจในอนาคต
- สรุป
- เอกสารอ้างอิง