เรียนรู้วิธีการใช้ Next.js Layouts เพื่อสร้างแอปพลิเคชันที่แข็งแกร่ง ขยายขนาดได้ และรองรับการใช้งานทั่วโลก ค้นพบแนวทางปฏิบัติที่ดีที่สุดสำหรับคอมโพเนนต์ UI ที่ใช้ร่วมกัน
Next.js Layouts: การเรียนรู้รูปแบบคอมโพเนนต์ UI ที่ใช้ร่วมกันสำหรับแอปพลิเคชันระดับโลก
Next.js ได้กลายเป็นรากฐานที่สำคัญของการพัฒนาเว็บสมัยใหม่ มีชื่อเสียงในด้านความสามารถในการปรับปรุงกระบวนการสร้างแอปพลิเคชันที่มีประสิทธิภาพและเป็นมิตรต่อผู้ใช้ หัวใจสำคัญของความสามารถนี้คือการจัดการคอมโพเนนต์ UI อย่างมีประสิทธิภาพ และศูนย์กลางของสิ่งนี้คือพลังของ Next.js Layouts คู่มือฉบับสมบูรณ์นี้จะเจาะลึกถึงความซับซ้อนของการใช้ประโยชน์จาก Next.js Layouts เพื่อสร้างแอปพลิเคชันที่แข็งแกร่ง ขยายขนาดได้ และรองรับการใช้งานทั่วโลก เราจะสำรวจแนวทางปฏิบัติที่ดีที่สุดสำหรับการสร้างคอมโพเนนต์ UI ที่ใช้ร่วมกัน ซึ่งส่งเสริมการนำโค้ดกลับมาใช้ใหม่ ความสามารถในการบำรุงรักษา และประสบการณ์ผู้ใช้ที่ราบรื่นสำหรับผู้ใช้ทั่วโลก
ทำความเข้าใจความสำคัญของ Layouts ใน Next.js
ในแวดวงการพัฒนาเว็บ โดยเฉพาะกับเฟรมเวิร์กอย่าง Next.js เลย์เอาต์ทำหน้าที่เป็นรากฐานทางสถาปัตยกรรมที่ใช้สร้างส่วนต่อประสานผู้ใช้ของแอปพลิเคชันของคุณ มันคือพิมพ์เขียวสำหรับองค์ประกอบ UI ที่สอดคล้องและนำกลับมาใช้ใหม่ได้ ซึ่งเป็นตัวกำหนดประสบการณ์ผู้ใช้โดยรวม การคิดเกี่ยวกับเลย์เอาต์ในการออกแบบแอปพลิเคชันที่มีโครงสร้างที่ดีช่วยให้นักพัฒนาหลีกเลี่ยงการทำซ้ำของโค้ดและทำให้การบำรุงรักษาง่ายขึ้น โดยพื้นฐานแล้ว มันเป็นกรอบการทำงานสำหรับ:
- สร้างแบรนด์ที่สอดคล้องกัน: รักษาเอกลักษณ์ทางภาพที่เป็นหนึ่งเดียวกันในทุกหน้า
- การนำทางที่ใช้ร่วมกัน: การนำไปใช้และจัดการเมนูนำทาง ส่วนท้าย และองค์ประกอบ UI อื่นๆ ที่คงอยู่ซึ่งปรากฏในหลายหน้า
- การนำโค้ดกลับมาใช้ใหม่: ป้องกันความจำเป็นในการเขียนตรรกะ UI เดิมซ้ำแล้วซ้ำอีก
- การปรับปรุง SEO: การใช้เมตาแท็ก ไตเติ้ลแท็ก และองค์ประกอบ SEO อื่นๆ ที่สอดคล้องกันทั่วทั้งไซต์ของคุณ ซึ่งช่วยปรับปรุงอันดับในเครื่องมือค้นหา
- การปรับปรุงประสิทธิภาพ: การใช้ฟีเจอร์ต่างๆ เช่น Server-Side Rendering (SSR) และ Static Site Generation (SSG) ที่ Next.js นำเสนอด้วยการกำหนดค่าคอมโพเนนต์ที่เหมาะสมที่สุด
แนวคิดหลักและประโยชน์ของ Next.js Layouts
1. ไฟล์ `_app.js` และ `_document.js`
ใน Next.js มีไฟล์พิเศษสองไฟล์ที่มีบทบาทสำคัญในการกำหนดเลย์เอาต์และการกำหนดค่าส่วนกลาง: `_app.js` และ `_document.js` การทำความเข้าใจวัตถุประสงค์ของไฟล์เหล่านี้เป็นพื้นฐานที่สำคัญ
_app.js
: นี่คือคอมโพเนนต์ระดับบนสุดที่ครอบคลุมทุกหน้าในแอปพลิเคชันของคุณ โดยปกติคุณจะใช้ไฟล์นี้เพื่อ:- เริ่มต้น CSS ส่วนกลางหรือ styled components
- ส่งข้อมูลไปยังคอมโพเนนต์ของคุณโดยใช้ context providers
- ครอบแอปพลิเคชันของคุณด้วย providers เช่น Redux หรือ Zustand สำหรับการจัดการสถานะ
- กำหนดเลย์เอาต์ส่วนกลางที่ใช้กับทุกหน้า เช่น ส่วนหัวหรือส่วนท้ายที่คงอยู่
_document.js
: นี่เป็นไฟล์การกำหนดค่าขั้นสูงที่คุณสามารถควบคุมการเรนเดอร์ฝั่งเซิร์ฟเวอร์ของเอกสาร HTML ได้ ไฟล์นี้ช่วยให้คุณสามารถแก้ไขแท็ก<html>
,<head>
, และ<body>
ได้ โดยส่วนใหญ่จะใช้สำหรับการปรับปรุง SEO และประสิทธิภาพที่ซับซ้อนยิ่งขึ้น โดยปกติคุณจะใช้ `_document.js` เพื่อ:- รวมฟอนต์ สคริปต์ และสไตล์ชีตภายนอก
- ตั้งค่าโครงสร้างเริ่มต้นสำหรับเอกสาร HTML ของคุณ
- ปรับแต่งกระบวนการเรนเดอร์ฝั่งเซิร์ฟเวอร์
2. ข้อดีของการใช้ Layouts
การใช้เลย์เอาต์มีข้อดีมากมาย โดยเฉพาะอย่างยิ่งเมื่อสร้างเว็บแอปพลิเคชันขนาดใหญ่และซับซ้อน:
- การจัดระเบียบโค้ดที่ดีขึ้น: ด้วยการแยกคอมโพเนนต์ UI ออกเป็นโมดูลที่นำกลับมาใช้ใหม่ได้ คุณจะเพิ่มความสามารถในการอ่านและบำรุงรักษาโค้ด
- การบำรุงรักษาที่ง่ายขึ้น: เมื่อต้องการการเปลี่ยนแปลง คุณเพียงแค่ต้องอัปเดตคอมโพเนนต์เลย์เอาต์ และการเปลี่ยนแปลงเหล่านั้นจะสะท้อนไปทั่วทั้งแอปพลิเคชัน
- ประสิทธิภาพที่เพิ่มขึ้น: เลย์เอาต์สามารถเพิ่มประสิทธิภาพการส่งมอบเนื้อหา ซึ่งนำไปสู่เวลาในการโหลดหน้าที่เร็วขึ้นและประสบการณ์ผู้ใช้ที่ดีขึ้น
- ประสบการณ์ผู้ใช้ที่สอดคล้องกัน: เลย์เอาต์ที่สอดคล้องกันรับประกันว่าผู้ใช้จะได้รับประสบการณ์ที่คุ้นเคยขณะที่พวกเขานำทางผ่านแอปพลิเคชันของคุณ
- ประโยชน์ด้าน SEO: โครงสร้าง HTML และเมตาแท็กที่สอดคล้องกัน (ซึ่งมักจะจัดการภายในเลย์เอาต์) ช่วยปรับปรุงอันดับและการมองเห็นของเครื่องมือค้นหา
การนำรูปแบบคอมโพเนนต์ UI ที่ใช้ร่วมกันมาใช้
1. การสร้างคอมโพเนนต์ Layout พื้นฐาน
มาสร้างคอมโพเนนต์เลย์เอาต์แบบง่ายๆ กัน คอมโพเนนต์นี้จะรวมส่วนหัว พื้นที่เนื้อหาหลัก และส่วนท้าย ซึ่งออกแบบมาเพื่อใช้ร่วมกันในหลายๆ หน้า
// components/Layout.js
import Head from 'next/head';
function Layout({ children, title }) {
return (
<>
<Head>
<title>{title} | My App</title>
<meta name="description" content="My Next.js App" />
</Head>
<header>
<h1>My App Header</h1>
</header>
<main>{children}</main>
<footer>
<p>© {new Date().getFullYear()} My App. All rights reserved.</p>
</footer>
</>
);
}
export default Layout;
ในตัวอย่างนี้ คอมโพเนนต์ `Layout` จะได้รับ `children` และ `title` เป็น props `children` แทนเนื้อหาของหน้าที่จะถูกเรนเดอร์ภายในเลย์เอาต์ ในขณะที่ `title` จะตั้งค่าแท็กไตเติ้ลของหน้าสำหรับ SEO
2. การใช้คอมโพเนนต์ Layout ในหน้าเว็บ
ตอนนี้ เรามาใช้เลย์เอาต์นี้กับหน้าใดหน้าหนึ่งของคุณกัน (เช่น `pages/index.js`)
// pages/index.js
import Layout from '../components/Layout';
function HomePage() {
return (
<Layout title="Home">
<h2>Welcome to the Home Page</h2>
<p>This is the main content of the home page.</p>
</Layout>
);
}
export default HomePage;
ใน `pages/index.js` เรานำเข้าคอมโพเนนต์ `Layout` และครอบเนื้อหาของหน้าไว้ภายในนั้น เรายังระบุ `title` เฉพาะสำหรับหน้านั้นด้วย prop `children` ในคอมโพเนนต์ `Layout` จะถูกเติมด้วยเนื้อหาระหว่างแท็ก `<Layout>` ใน `index.js`
3. คุณสมบัติ Layout ขั้นสูง
- การดึงข้อมูลแบบไดนามิก: คุณสามารถใช้ `getServerSideProps` หรือ `getStaticProps` เพื่อดึงข้อมูลภายในคอมโพเนนต์เลย์เอาต์ของคุณได้ สิ่งนี้ช่วยให้คุณสามารถแทรกข้อมูลลงในส่วนหัวหรือการนำทางจากแหล่งข้อมูลได้
- Context Providers: ใช้ประโยชน์จาก React context เพื่อแชร์สถานะและข้อมูลข้ามคอมโพเนนต์ที่ครอบอยู่ในเลย์เอาต์ สิ่งนี้จำเป็นสำหรับการจัดการธีม การยืนยันตัวตนผู้ใช้ และสถานะส่วนกลางอื่นๆ ของแอปพลิเคชัน
- การเรนเดอร์แบบมีเงื่อนไข: นำการเรนเดอร์แบบมีเงื่อนไขมาใช้ภายในเลย์เอาต์ของคุณเพื่อแสดงองค์ประกอบ UI ที่แตกต่างกัน ขึ้นอยู่กับการยืนยันตัวตนผู้ใช้ ขนาดหน้าจอ หรือปัจจัยอื่นๆ
- การจัดสไตล์: รวม CSS-in-JS (เช่น styled-components, Emotion), CSS Modules หรือ CSS ธรรมดาโดยตรงภายในคอมโพเนนต์เลย์เอาต์ของคุณ
ข้อควรพิจารณาสำหรับแอปพลิเคชันระดับโลก
เมื่อสร้างเลย์เอาต์สำหรับผู้ชมทั่วโลก สิ่งสำคัญคือต้องพิจารณาแง่มุมต่างๆ ของการทำให้เป็นสากลและโลกาภิวัตน์ (i18n/g11n) แนวทางปฏิบัติเหล่านี้ช่วยให้แน่ใจว่าแอปพลิเคชันของคุณสามารถเข้าถึงได้และเป็นมิตรต่อผู้ใช้สำหรับบุคคลจากภูมิหลังทางวัฒนธรรมที่หลากหลาย
1. Internationalization (i18n) และ Localization (l10n)
- i18n (Internationalization): ออกแบบแอปพลิเคชันของคุณให้สามารถปรับให้เข้ากับภาษาและภูมิภาคต่างๆ ได้ ซึ่งรวมถึงการแยกข้อความ การจัดการรูปแบบวันที่และตัวเลข และการรองรับชุดอักขระที่แตกต่างกัน
- l10n (Localization): ปรับแอปพลิเคชันของคุณให้เข้ากับท้องถิ่นที่เฉพาะเจาะจง รวมถึงการแปลภาษา การจัดรูปแบบสกุลเงิน รูปแบบวันที่/เวลา และความชอบทางวัฒนธรรม
2. การนำ i18n มาใช้ใน Next.js Layouts
เพื่อนำ i18n มาใช้ใน Next.js คุณสามารถใช้ไลบรารีต่างๆ เช่น `next-i18next` หรือ `next/router` ในตัวสำหรับโซลูชันที่อิงตามการกำหนดเส้นทาง
นี่คือตัวอย่างแบบง่ายด้วย `next-i18next` โดยใช้ไฟล์ `_app.js` ซึ่งเป็นการตั้งค่า i18n ที่ระดับแอปพลิเคชัน ตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งแพ็คเกจที่จำเป็นโดยใช้ `npm install i18next react-i18next next-i18next` ตัวอย่างนี้แสดงให้เห็นถึงการผสานรวมที่เรียบง่ายและอาจต้องมีการปรับเปลี่ยนตามความต้องการเฉพาะ
// _app.js
import { appWithTranslation } from 'next-i18next';
import '../styles/global.css'; // นำเข้าสไตล์ส่วนกลางของคุณ
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export default appWithTranslation(MyApp);
ใน `_app.js` นี้ `appWithTranslation` จะให้บริบทการทำให้เป็นสากลแก่แอปพลิเคชัน
จากนั้น ในเลย์เอาต์ของคุณ ให้ใช้ hook `useTranslation` ที่จัดหาให้โดย `react-i18next`:
// components/Layout.js
import { useTranslation } from 'react-i18next';
import Head from 'next/head';
function Layout({ children, title }) {
const { t } = useTranslation(); // รับฟังก์ชันการแปล
return (
<>
<Head>
<title>{t('layout.title', { title })}</title>
<meta name="description" content={t('layout.description')} />
</Head>
<header>
<h1>{t('layout.header')}</h1>
</header>
<main>{children}</main>
<footer>
<p>{t('layout.footer', { year: new Date().getFullYear() })}</p>
</footer>
</>
);
}
export default Layout;
จากนั้นคุณจะต้องมีไฟล์การแปลของคุณ ซึ่งโดยทั่วไปจะเก็บไว้ในโครงสร้าง `public/locales/[locale]/[namespace].json` ตัวอย่างเช่น `public/locales/en/common.json` อาจมี:
{
"layout": {
"title": "{{title}} | แอปของฉัน",
"description": "คำอธิบายแอป Next.js ของฉัน",
"header": "ส่วนหัวของแอปของฉัน",
"footer": "© {{year}} แอปของฉัน สงวนลิขสิทธิ์"
}
}
และ `public/locales/fr/common.json` (สำหรับภาษาฝรั่งเศส) อาจมี:
{
"layout": {
"title": "{{title}} | Mon Application",
"description": "Description de mon application Next.js",
"header": "En-tête de mon application",
"footer": "© {{year}} Mon application. Tous droits réservés."
}
}
หมายเหตุ: ตัวอย่างนี้เป็นแนวทางพื้นฐานในการผสานรวม i18n และต้องการการกำหนดค่าเพิ่มเติม (เช่น การตรวจจับภาษา, การตั้งค่าการกำหนดเส้นทาง) โปรดศึกษาเอกสารของ `next-i18next` สำหรับคำแนะนำที่ครอบคลุม
3. การออกแบบที่ตอบสนองและเลย์เอาต์
การออกแบบที่ตอบสนองเป็นสิ่งสำคัญสำหรับผู้ชมทั่วโลก เลย์เอาต์ของคุณต้องปรับให้เข้ากับขนาดหน้าจอและอุปกรณ์ต่างๆ ใช้เฟรมเวิร์ก CSS เช่น Bootstrap, Tailwind CSS หรือสร้าง media queries แบบกำหนดเองเพื่อให้แน่ใจว่าได้รับประสบการณ์ที่สอดคล้องและเป็นมิตรต่อผู้ใช้ในทุกอุปกรณ์
4. ข้อควรพิจารณาด้านการเข้าถึงได้
ปฏิบัติตามแนวทางการเข้าถึงได้ (WCAG) เพื่อให้แอปพลิเคชันของคุณสามารถใช้งานได้สำหรับผู้ที่มีความพิการ ซึ่งรวมถึง:
- Semantic HTML: ใช้องค์ประกอบ HTML เชิงความหมาย (
<nav>
,<article>
,<aside>
) เพื่อจัดโครงสร้างเนื้อหาของคุณอย่างมีเหตุผล - ข้อความทางเลือกสำหรับรูปภาพ: ระบุแอตทริบิวต์ `alt` ที่สื่อความหมายสำหรับรูปภาพเสมอ
- การนำทางด้วยคีย์บอร์ด: ตรวจสอบให้แน่ใจว่าแอปพลิเคชันของคุณสามารถนำทางได้โดยใช้เพียงคีย์บอร์ด
- ความคมชัดของสี: รักษาความคมชัดของสีที่เพียงพอระหว่างข้อความและพื้นหลัง
- แอตทริบิวต์ ARIA: ใช้แอตทริบิวต์ ARIA เพื่อเพิ่มความสามารถในการเข้าถึงในกรณีที่จำเป็น
5. การจัดรูปแบบวันที่และเวลา
ภูมิภาคต่างๆ มีแบบแผนที่แตกต่างกันสำหรับรูปแบบวันที่และเวลา ตรวจสอบให้แน่ใจว่าวันที่และเวลาแสดงอย่างถูกต้องตามท้องถิ่นของผู้ใช้ ไลบรารีอย่าง `date-fns` หรือ `Intl` API ในตัวของ JavaScript สามารถจัดการเรื่องนี้ได้
import { format } from 'date-fns';
import { useTranslation } from 'react-i18next';
function MyComponent() {
const { i18n } = useTranslation();
const currentDate = new Date();
const formattedDate = format(currentDate, 'MMMM d, yyyy', { locale: i18n.language });
return <p>{formattedDate}</p>;
}
6. การจัดรูปแบบสกุลเงิน
แสดงค่าเงินในรูปแบบที่ถูกต้องสำหรับแต่ละท้องถิ่น `Intl.NumberFormat` API มีประโยชน์อย่างมากสำหรับการจัดการการจัดรูปแบบสกุลเงิน
function MyComponent() {
const { i18n } = useTranslation();
const price = 1234.56;
const formattedPrice = new Intl.NumberFormat(i18n.language, { // ใช้ i18n.language สำหรับท้องถิ่น
style: 'currency',
currency: 'USD', // หรือกำหนดสกุลเงินแบบไดนามิกตามความชอบของผู้ใช้
}).format(price);
return <p>{formattedPrice}</p>
}
7. ภาษาที่เขียนจากขวาไปซ้าย (RTL)
หากแอปพลิเคชันของคุณต้องการรองรับภาษาต่างๆ เช่น ภาษาอาหรับหรือฮิบรู (ภาษา RTL) ให้ออกแบบเลย์เอาต์ของคุณเพื่อรองรับสิ่งนี้ พิจารณาใช้คุณสมบัติ CSS เช่น `direction: rtl;` และปรับตำแหน่งขององค์ประกอบ UI
8. Content Delivery Networks (CDNs) และประสิทธิภาพ
ใช้ CDN เพื่อให้บริการแอสเซทแบบคงที่ของแอปพลิเคชันของคุณ (รูปภาพ, CSS, JavaScript) จากเซิร์ฟเวอร์ที่อยู่ใกล้กับผู้ใช้ของคุณทางภูมิศาสตร์ ซึ่งจะช่วยลดเวลาแฝงและปรับปรุงเวลาในการโหลดหน้าเว็บสำหรับผู้ใช้ต่างชาติ การปรับปรุงรูปภาพในตัวของ Next.js และการรวม CDN สามารถปรับปรุงประสิทธิภาพได้อย่างมีนัยสำคัญ
9. การปรับปรุง SEO สำหรับตลาดโลก
การปรับปรุงให้เหมาะสมกับเครื่องมือค้นหา (SEO) เป็นสิ่งสำคัญสำหรับการดึงดูดผู้ใช้ทั่วโลก ใช้เทคนิคต่อไปนี้:
- URL เฉพาะภาษา: ใช้รหัสภาษาใน URL ของคุณ (เช่น `/en/`, `/fr/`, `/es/`) เพื่อระบุภาษาของเนื้อหา
- แท็ก hreflang: นำแท็ก `hreflang` มาใช้ในส่วน `` ของ HTML ของคุณ แท็กเหล่านี้จะบอกเครื่องมือค้นหาถึงภาษาและการกำหนดเป้าหมายตามภูมิภาคของหน้าเว็บ ซึ่งจำเป็นอย่างยิ่งเพื่อให้แน่ใจว่าเนื้อหาเวอร์ชันที่ถูกต้องจะแสดงในผลการค้นหา
- คำอธิบาย Meta และแท็ก Title: ปรับปรุงคำอธิบายเมตาและแท็กไตเติ้ลของคุณสำหรับแต่ละภาษาและภูมิภาค
- คุณภาพเนื้อหา: จัดหาเนื้อหาคุณภาพสูงและเป็นต้นฉบับที่เกี่ยวข้องกับกลุ่มเป้าหมายของคุณ
- ความเร็วของเว็บไซต์: ปรับปรุงความเร็วของเว็บไซต์เนื่องจากเป็นปัจจัยสำคัญในการจัดอันดับ ใช้ประโยชน์จากการปรับปรุงประสิทธิภาพของ Next.js
ตัวอย่างแท็ก hreflang ใน `
` ของคอมโพเนนต์ `Layout` ของคุณ:
<Head>
<title>{t('layout.title', { title })}</title>
<meta name="description" content={t('layout.description')} />
<link rel="alternate" href="https://www.example.com/" hreflang="x-default" /> {
<link rel="alternate" href="https://www.example.com/en/" hreflang="en" />
<link rel="alternate" href="https://www.example.com/fr/" hreflang="fr" />
// ตัวแปรภาษาเพิ่มเติม
</Head>
กลยุทธ์ Layout ขั้นสูง
1. Code Splitting กับ Layouts
Next.js ทำการแบ่งโค้ดโดยอัตโนมัติเพื่อปรับปรุงประสิทธิภาพ แต่คุณสามารถปรับแต่งพฤติกรรมนี้ได้โดยใช้ dynamic imports โดยเฉพาะภายในเลย์เอาต์ของคุณ ด้วยการนำเข้าคอมโพเนนต์ขนาดใหญ่แบบไดนามิก คุณสามารถลดขนาด JavaScript bundle เริ่มต้นได้ ซึ่งนำไปสู่เวลาในการโหลดเริ่มต้นที่เร็วขึ้น
import dynamic from 'next/dynamic';
const DynamicComponent = dynamic(() => import('../components/LargeComponent'));
function Layout({ children }) {
return (
<>
<header>...</header>
<main>
{children}
<DynamicComponent /> <!-- คอมโพเนนต์ที่โหลดแบบไดนามิก -->
</main>
<footer>...</footer>
</>
);
}
ในตัวอย่าง `LargeComponent` จะถูกโหลดแบบไดนามิก การนำเข้าแบบไดนามิกจะชะลอการดาวน์โหลดคอมโพเนนต์นี้จนกว่าจะจำเป็นต้องใช้จริงๆ
2. Layouts กับ Server-Side Rendering (SSR)
ความสามารถ SSR ของ Next.js ช่วยให้คุณสามารถเรนเดอร์เนื้อหาล่วงหน้าบนเซิร์ฟเวอร์ได้ ซึ่งช่วยปรับปรุง SEO และเวลาในการโหลดเริ่มต้น คุณสามารถนำ SSR มาใช้ภายในเลย์เอาต์ของคุณเพื่อดึงข้อมูลก่อนที่หน้าจะถูกส่งไปยังไคลเอ็นต์ ซึ่งมีความสำคัญอย่างยิ่งสำหรับเนื้อหาที่มีการเปลี่ยนแปลงบ่อยครั้งหรือที่ควรได้รับการจัดทำดัชนีโดยเครื่องมือค้นหา
การใช้ `getServerSideProps` ภายในหน้า คุณสามารถส่งข้อมูลไปยังเลย์เอาต์ได้:
// pages/posts/[id].js
import Layout from '../../components/Layout';
export async function getServerSideProps(context) {
const { id } = context.params;
const res = await fetch(`https://api.example.com/posts/${id}`);
const post = await res.json();
return {
props: {
post,
},
};
}
function PostPage({ post }) {
return (
<Layout title={post.title}>
<h1>{post.title}</h1>
<p>{post.content}</p>
</Layout>
);
}
export default PostPage;
ฟังก์ชัน `getServerSideProps` จะดึงข้อมูลโพสต์ จากนั้นข้อมูล `post` จะถูกส่งเป็น prop ไปยัง `Layout`
3. Layouts กับ Static Site Generation (SSG)
สำหรับเนื้อหาที่ไม่เปลี่ยนแปลงบ่อยครั้ง SSG ให้ประโยชน์ด้านประสิทธิภาพอย่างมาก มันจะเรนเดอร์หน้าล่วงหน้าในขณะสร้าง (build time) สร้างไฟล์ HTML แบบคงที่ซึ่งจะถูกให้บริการโดยตรงแก่ผู้ใช้ หากต้องการใช้ SSG ให้ใช้ฟังก์ชัน `getStaticProps` ในคอมโพเนนต์หน้าของคุณ และข้อมูลสามารถส่งไปยังเลย์เอาต์ได้
// pages/about.js
import Layout from '../components/Layout';
export async function getStaticProps() {
const aboutData = { title: 'About Us', content: 'Some information about our company.' };
return {
props: {
aboutData,
},
};
}
function AboutPage({ aboutData }) {
return (
<Layout title={aboutData.title}>
<h2>{aboutData.title}</h2>
<p>{aboutData.content}</p>
</Layout>
);
}
export default AboutPage;
ในตัวอย่าง SSG นี้ `getStaticProps` จะดึงข้อมูลในขณะสร้าง จากนั้นส่งต่อไปยัง `AboutPage` ซึ่งจะถูกเรนเดอร์โดยใช้คอมโพเนนต์ `Layout`
4. Nested Layouts
สำหรับแอปพลิเคชันที่ซับซ้อน คุณอาจต้องการเลย์เอาต์ซ้อน ซึ่งหมายถึงการมีเลย์เอาต์ภายในเลย์เอาต์ ตัวอย่างเช่น คุณอาจมีเลย์เอาต์หลักของแอปพลิเคชัน แล้วใช้เลย์เอาต์ที่แตกต่างกันสำหรับส่วนเฉพาะของเว็บไซต์ของคุณ ซึ่งช่วยให้สามารถควบคุมส่วนต่อประสานผู้ใช้ได้อย่างละเอียด
// components/MainLayout.js
function MainLayout({ children }) {
return (
<>
<header>Main Header</header>
<main>{children}</main>
<footer>Main Footer</footer>
</>
);
}
export default MainLayout;
// components/SectionLayout.js
function SectionLayout({ children }) {
return (
<div className="section-wrapper">
<aside>Section Navigation</aside>
<div className="section-content">{children}</div>
</div>
);
}
export default SectionLayout;
// pages/section/[page].js
import MainLayout from '../../components/MainLayout';
import SectionLayout from '../../components/SectionLayout';
function SectionPage({ page }) {
return (
<MainLayout>
<SectionLayout>
<h1>Section Page: {page}</h1>
<p>Content for section page {page}.</p>
</SectionLayout>
</MainLayout>
);
}
export async function getServerSideProps(context) {
const { page } = context.query;
return {
props: {
page,
},
};
}
export default SectionPage;
ในกรณีนี้ `SectionPage` จะถูกครอบด้วยทั้ง `MainLayout` และ `SectionLayout` เพื่อสร้างโครงสร้างเลย์เอาต์ซ้อน
แนวทางปฏิบัติที่ดีที่สุดและเคล็ดลับการปรับปรุงประสิทธิภาพ
1. Component Composition
ใช้การประกอบคอมโพเนนต์ แบ่งเลย์เอาต์และองค์ประกอบ UI ของคุณออกเป็นคอมโพเนนต์ขนาดเล็กที่นำกลับมาใช้ใหม่ได้ ซึ่งจะช่วยเพิ่มความสามารถในการอ่านและบำรุงรักษาโค้ด
2. การตรวจสอบประสิทธิภาพ
ตรวจสอบประสิทธิภาพของเลย์เอาต์และแอปพลิเคชันของคุณอย่างต่อเนื่องโดยใช้เครื่องมือเช่น Google Lighthouse หรือ WebPageTest เครื่องมือเหล่านี้สามารถช่วยคุณระบุปัญหาคอขวดด้านประสิทธิภาพและส่วนที่ต้องปรับปรุง
3. กลยุทธ์การแคช
นำกลยุทธ์การแคชมาใช้เพื่อลดภาระของเซิร์ฟเวอร์และปรับปรุงเวลาตอบสนอง พิจารณาการแคชข้อมูลที่เข้าถึงบ่อยครั้ง การใช้การแคชของเบราว์เซอร์สำหรับแอสเซทแบบคงที่ และการใช้ Content Delivery Network (CDN) เพื่อแคชเนื้อหาให้ใกล้กับผู้ใช้มากขึ้น
4. Lazy Loading
ใช้ lazy loading สำหรับรูปภาพและคอมโพเนนต์อื่นๆ ที่ไม่สำคัญ วิธีนี้จะชะลอการโหลดทรัพยากรจนกว่าจะจำเป็น ซึ่งจะช่วยลดเวลาในการโหลดหน้าเว็บเริ่มต้น
5. หลีกเลี่ยงการ Re-render ที่มากเกินไป
ปรับปรุงคอมโพเนนต์ของคุณเพื่อหลีกเลี่ยงการ re-render ที่ไม่จำเป็น ใช้ `React.memo`, `useMemo` และ `useCallback` เพื่อ memoize คอมโพเนนต์และฟังก์ชัน ใช้ prop `key` อย่างเหมาะสมเมื่อเรนเดอร์รายการคอมโพเนนต์เพื่อช่วยให้ React ระบุการเปลี่ยนแปลงได้อย่างมีประสิทธิภาพ
6. การทดสอบ
ทำการทดสอบคอมโพเนนต์เลย์เอาต์ของคุณอย่างละเอียด รวมถึงการทดสอบหน่วย (unit tests) และการทดสอบการรวม (integration tests) เพื่อให้แน่ใจว่าทำงานได้ตามที่คาดไว้และรักษพฤติกรรมที่สอดคล้องกัน ทดสอบเลย์เอาต์ในขนาดหน้าจอและท้องถิ่นที่แตกต่างกัน
บทสรุป
Next.js Layouts นำเสนอเครื่องมือที่มีประสิทธิภาพและหลากหลายเพื่อสร้างเว็บแอปพลิเคชันที่ยอดเยี่ยม ด้วยการเชี่ยวชาญเทคนิคที่กล่าวถึงในคู่มือนี้ คุณสามารถสร้าง UI ที่มีโครงสร้างดี บำรุงรักษาง่าย และมีประสิทธิภาพ อย่าลืมนำแนวทางปฏิบัติที่ดีที่สุดด้านการทำให้เป็นสากลและโลกาภิวัตน์มาใช้เพื่อให้แน่ใจว่าแอปพลิเคชันของคุณจะเข้าถึงผู้ชมทั่วโลก ด้วยการผสมผสานพลังของ Next.js เข้ากับแนวทางที่รอบคอบในการสร้างเลย์เอาต์ คุณจะพร้อมอย่างเต็มที่ในการสร้างประสบการณ์เว็บที่ทันสมัย ขยายขนาดได้ และเข้าถึงได้ในระดับสากล