React, Next.js ແລະ TypeScript ໄດ້ກາຍເປັນຊຸດເທັກໂນໂລຊີມາດຕະຖານສຳລັບເວັບແອັບລະດັບມືອາຊີບ. React ໃຫ້ໂມເດວແບບ component, Next.js ເພີ່ມລະບົບ routing, ການ render ແລະ ການດຶງຂໍ້ມູນ, ສ່ວນ TypeScript ຈັບຂໍ້ຜິດພາດໄດ້ທັງກຸ່ມກ່ອນທີ່ໂຄດຈະເຮັດວຽກ. ຖ້າໃຊ້ຢ່າງຖືກຕ້ອງ, ຈະໄດ້ເວັບໄຊທີ່ໄວສຳລັບຜູ້ເຂົ້າຊົມ ແລະ ບຳລຸງຮັກສາງ່າຍສຳລັບນັກພັດທະນາ.
ແຕ່ຖ້າໃຊ້ຢ່າງບໍ່ລະມັດລະວັງ, ຊຸດເທັກໂນໂລຊີດຽວກັນນີ້ກໍສ້າງໜ້າເວັບທີ່ຊ້າ ແລະ ເຕັມໄປດ້ວຍ JavaScript ຫຼາຍເມກາໄບ. ບົດຄວາມນີ້ອະທິບາຍແນວຄິດທີ່ສ້າງຄວາມແຕກຕ່າງ ພ້ອມໂຄດທີ່ນຳໄປໃຊ້ໃນໂປຣເຈັກ Next.js App Router ໄດ້ທັນທີ.
ເປັນຫຍັງຊຸດເທັກໂນໂລຊີນີ້ຈຶ່ງກາຍເປັນມາດຕະຖານ
- React ອະທິບາຍໜ້າຈໍເປັນຕົ້ນໄມ້ຂອງ component ທີ່ນຳກັບມາໃຊ້ຄືນໄດ້. ປຸ່ມ, ບັດ ຫຼື ທັງໜ້າ ລ້ວນເປັນຟັງຊັນຂອງຂໍ້ມູນ, ເຮັດໃຫ້ໜ້າຈໍຄາດເດົາໄດ້ ແລະ ທົດສອບງ່າຍ.
- Next.js ປ່ຽນ React ໃຫ້ເປັນເຟຣມເວີກເຕັມຮູບແບບ: routing ຕາມໄຟລ໌, ການ render ຝັ່ງເຊີບເວີ, ການເກັບແຄດ, ການປັບແຕ່ງຮູບພາບ ແລະ ຟອນ, ແລະ ຂັ້ນຕອນ build ສຳລັບ production.
- TypeScript ເພີ່ມ static type ໃຫ້ JavaScript. ໂປຣແກຣມແກ້ໄຂໂຄດຮູ້ໂຄງສ້າງຂອງທຸກອອບເຈັກ, ການ refactor ປອດໄພ, ແລະ ຂໍ້ຜິດພາດຕອນເຮັດວຽກຫຼາຍຢ່າງກາຍເປັນຂໍ້ຜິດພາດຕອນ compile.
ເມື່ອລວມກັນ, ທັງສາມຢ່າງຮອງຮັບທຸກຢ່າງຕັ້ງແຕ່ເວັບໄຊການຕະຫຼາດຈົນເຖິງແດຊບອດທີ່ຊັບຊ້ອນ, ດ້ວຍພາສາດຽວທັງຝັ່ງ frontend ແລະ ເຊີບເວີ.
Server Components ປ່ຽນຄ່າເລີ່ມຕົ້ນ
ໃນ Next.js App Router, ທຸກ component ແມ່ນ React Server Component ເວັ້ນເສຍແຕ່ທ່ານຈະເລືອກເປັນຢ່າງອື່ນ. Server Components ເຮັດວຽກຢູ່ເທິງເຊີບເວີເທົ່ານັ້ນ, ອ່ານຂໍ້ມູນຈາກຖານຂໍ້ມູນ ຫຼື ເອີ້ນ API ພາຍໃນໄດ້ໂດຍກົງ, ແລະ JavaScript ຂອງມັນບໍ່ເຄີຍຖືກສົ່ງໄປຫາບຣາວເຊີ. ມີພຽງຜົນທີ່ render ແລ້ວເທົ່ານັ້ນ.
ທ່ານໃສ່ directive 'use client' ສະເພາະ component ທີ່ຕ້ອງມີການໂຕ້ຕອບ ເຊັ່ນ: state, effect, event handler ຫຼື API ຂອງບຣາວເຊີ. ແນວທາງທີ່ດີທີ່ສຸດແມ່ນເຮັດໃຫ້ client component ມີຂະໜາດນ້ອຍ ແລະ ວາງໄວ້ທີ່ປາຍງ່າຂອງຕົ້ນໄມ້:
// app/blog/page.tsx: a Server Component (the default in the App Router)
import { getPosts } from '@/lib/posts'
import { LikeButton } from './like-button'
export default async function BlogPage() {
const posts = await getPosts() // runs on the server, so no extra API route is needed
return (
<ul>
{posts.map((post) => (
<li key={post.slug}>
<a href={`/blog/${post.slug}`}>{post.title}</a>
<LikeButton />
</li>
))}
</ul>
)
}// app/blog/like-button.tsx: only this small component ships JavaScript
'use client'
import { useState } from 'react'
export function LikeButton() {
const [liked, setLiked] = useState(false)
return (
<button type="button" aria-pressed={liked} onClick={() => setLiked((value) => !value)}>
{liked ? 'Liked' : 'Like'}
</button>
)
}ລາຍການ, ການເຂົ້າເຖິງຂໍ້ມູນ ແລະ markup ບໍ່ເພີ່ມພາລະໃຫ້ບຣາວເຊີເລີຍ. ມີພຽງປຸ່ມທີ່ຕ້ອງ hydrate. ສຳລັບໜ້າທີ່ເນັ້ນເນື້ອຫາ, ວິທີນີ້ມັກຕັດ JavaScript ຝັ່ງ client ອອກໄປໄດ້ເກືອບທັງໝົດ.
ເລືອກກົນລະຍຸດການ render ໃຫ້ຖືກຕ້ອງ
Next.js ໃຫ້ທ່ານກຳນົດໄດ້ໃນແຕ່ລະ route ວ່າຈະສ້າງ HTML ເມື່ອໃດ. ການເລືອກໃຫ້ຖືກແມ່ນການຕັດສິນໃຈດ້ານປະສິດທິພາບທີ່ສຳຄັນທີ່ສຸດທີ່ທ່ານເຮັດ:
- Static rendering: ສ້າງ HTML ຕອນ build ແລ້ວສົ່ງຈາກແຄດ ຫຼື CDN. ເໝາະກັບໜ້າການຕະຫຼາດ ແລະ ເອກະສານ.
- Incremental Static Regeneration (ISR): ໜ້າ static ທີ່ໂຫຼດໃໝ່ເມື່ອຄົບເວລາທີ່ກຳນົດ ຫຼື ເມື່ອສັ່ງດ້ວຍ
revalidatePath(). ເໝາະກັບບລັອກ, ລາຍການສິນຄ້າ ແລະ ໜ້າທີ່ດຶງເນື້ອຫາຈາກ CMS. - Dynamic rendering: ສ້າງ HTML ທຸກເທື່ອທີ່ມີຄຳຮ້ອງຂໍ. ຈຳເປັນສຳລັບໜ້າທີ່ປັບຕາມຜູ້ໃຊ້, ແດຊບອດ ແລະ ທຸກຢ່າງທີ່ຂຶ້ນກັບ cookie.
- Streaming: ຫໍ່ສ່ວນທີ່ຊ້າຂອງໜ້າດ້ວຍ
<Suspense>ເພື່ອໃຫ້ໂຄງໜ້າສະແດງທັນທີ ແລະ ຂໍ້ມູນທີ່ຊ້າຈະຕາມມາເມື່ອພ້ອມ.
route ບລັອກແບບ dynamic ທີ່ຖືກເກັບແຄດ ແລະ ໂຫຼດໃໝ່ທຸກໆຫ້ານາທີ ພ້ອມ metadata ດ້ານ SEO ແຍກຕາມບົດຄວາມ ມີລັກສະນະດັ່ງນີ້. ກະລຸນາສັງເກດວ່າໃນ Next.js ເວີຊັນປັດຈຸບັນ params ແມ່ນ Promise:
// app/blog/[slug]/page.tsx
import type { Metadata } from 'next'
import { notFound } from 'next/navigation'
import { getPost } from '@/lib/posts'
type Props = { params: Promise<{ slug: string }> }
// Serve the cached page, regenerating it at most every five minutes
export const revalidate = 300
export async function generateMetadata({ params }: Props): Promise<Metadata> {
const { slug } = await params
const post = await getPost(slug)
if (!post) return {}
return {
title: post.title,
description: post.excerpt,
openGraph: { type: 'article', title: post.title, images: [post.coverUrl] },
}
}
export default async function PostPage({ params }: Props) {
const { slug } = await params
const post = await getPost(slug)
if (!post) notFound() // renders the 404 page with the correct status code
return (
<article>
<h1>{post.title}</h1>
{/* … */}
</article>
)
}TypeScript ທີ່ຄຸ້ມຄ່າກັບການລົງທຶນ
ເປີດໂໝດ strict ຕັ້ງແຕ່ commit ທຳອິດ, ເພາະການມາເປີດພາຍຫຼັງແມ່ນລຳບາກຫຼາຍ. noUncheckedIndexedAccess ກໍຄວນເປີດເຊັ່ນກັນ ເພາະມັນບັງຄັບໃຫ້ທ່ານຈັດການກໍລະນີທີ່ສະມາຊິກຂອງອາເຣ ຫຼື ລາຍການໃນ map ບໍ່ມີຢູ່ແທ້:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"noImplicitOverride": true
}
}ຢ່າລືມວ່າ type ຈະຫາຍໄປຕອນເຮັດວຽກ. ຂໍ້ມູນທີ່ຂ້າມຂອບເຂດຂອງລະບົບ (ຂໍ້ມູນຈາກຟອມ, ຄຳຕອບຈາກ API, ພາລາມິເຕີໃນ URL, ຕົວແປສະພາບແວດລ້ອມ) ຕ້ອງຖືກກວດສອບຄວາມຖືກຕ້ອງ ບໍ່ແມ່ນພຽງກຳນົດ type. ໄລບຣາຣີ schema ເຊັ່ນ zod ໃຫ້ທັງສອງຢ່າງຈາກນິຍາມດຽວ:
import { z } from 'zod'
export const PostSchema = z.object({
slug: z.string().regex(/^[a-z0-9-]+$/),
title: z.string().min(1).max(200),
publishedAt: z.coerce.date(),
tags: z.array(z.string()).default([]),
})
// One source of truth for the runtime check and the compile-time type
export type Post = z.infer<typeof PostSchema>
export function parsePost(input: unknown): Post {
return PostSchema.parse(input) // throws a descriptive error for invalid data
}ສ້າງໂມເດວຂອງສະຖານະຢ່າງຊັດເຈນດ້ວຍ discriminated union ເຊັ່ນ: { status: 'loading' } | { status: 'error'; message: string } | { status: 'ready'; data: Post[] }. ແລ້ວ compiler ຈະບັງຄັບໃຫ້ທຸກ component ຈັດການສະຖານະກຳລັງໂຫຼດ ແລະ ສະຖານະຂໍ້ຜິດພາດ ແທນທີ່ຈະຄິດວ່າທຸກຢ່າງຈະລຽບງ່າຍສະເໝີ.
ແກ້ໄຂຂໍ້ມູນດ້ວຍ Server Actions
Server Actions ໃຫ້ຟອມເອີ້ນຟັງຊັນເທິງເຊີບເວີໄດ້ໂດຍກົງ ໂດຍບໍ່ຕ້ອງຂຽນ API route ເອງ. ມັນສະດວກແທ້, ແຕ່ເບື້ອງຫຼັງມັນແມ່ນ HTTP endpoint ສາທາລະນະ. ຈົ່ງປະຕິບັດຕໍ່ທຸກ action ຄືກັບ API: ກວດສອບຂໍ້ມູນທີ່ສົ່ງເຂົ້າມາ, ກວດສອບການຢືນຢັນຕົວຕົນ ແລະ ສິດທິເທິງເຊີບເວີ, ແລະ ສົ່ງຂໍ້ຜິດພາດທີ່ມີໂຄງສ້າງກັບຄືນໄປໃຫ້ຟອມສະແດງ. ການເຊື່ອງປຸ່ມໃນໜ້າຈໍບໍ່ແມ່ນຄວາມປອດໄພ.
ລາຍການກວດດ້ານປະສິດທິພາບ ແລະ ການເຂົ້າເຖິງ
- ໃຊ້
next/imageພ້ອມ attributesizesທີ່ຖືກຕ້ອງ ເພື່ອບໍ່ໃຫ້ມືຖືໂຫຼດຮູບຂະໜາດຄອມພິວເຕີ, ແລະ ກຳນົດpriorityໃຫ້ສະເພາະຮູບຫຼັກທີ່ຢູ່ສ່ວນເທິງຂອງໜ້າຈໍ. - ໂຫຼດຟອນດ້ວຍ
next/fontເພື່ອໂຮສຟອນເອງ ແລະ ຫຼີກລ່ຽງການເລື່ອນຂອງ layout. - ດຶງຂໍ້ມູນທີ່ບໍ່ຂຶ້ນກັບກັນແບບຂະໜານດ້ວຍ
Promise.allແທນການawaitຕໍ່ກັນເທື່ອລະຂັ້ນ. - ເຮັດໃຫ້ client component ນ້ອຍ ແລະ ຢູ່ປາຍງ່າ, ແລະ ໂຫຼດວິດເຈັດທີ່ໜັກເຊັ່ນ ແຜນທີ່, ກຣາຟ ແລະ ໂປຣແກຣມແກ້ໄຂ ແບບ lazy.
- ຕິດຕາມ Core Web Vitals ໃນ production. ລະດັບ "ດີ" ໝາຍເຖິງ Largest Contentful Paint ຕ່ຳກວ່າ 2.5 ວິນາທີ, Interaction to Next Paint ຕ່ຳກວ່າ 200 ມິລລິວິນາທີ ແລະ Cumulative Layout Shift ຕ່ຳກວ່າ 0.1 ທີ່ເປີເຊັນໄທລ໌ທີ 75.
- ໃຊ້ HTML ທີ່ມີຄວາມໝາຍ (
<nav>,<main>,<article>,<button>ແທ້ໆ), ໃສ່ label ໃຫ້ທຸກຊ່ອງໃນຟອມ, ເຮັດໃຫ້ສະຖານະ focus ເບິ່ງເຫັນໄດ້ສະເໝີ ແລະ ກວດຄວາມຄົມຊັດຂອງສີ.
ປະເດັນສຳຄັນ
- ໃຊ້ Server Components ເປັນຄ່າເລີ່ມຕົ້ນ, ແລະ ເພີ່ມ
'use client'ສະເພາະບ່ອນທີ່ຕ້ອງໂຕ້ຕອບ. - ເລືອກກົນລະຍຸດການ render ຕາມແຕ່ລະ route: static ເມື່ອເຮັດໄດ້, ISR ສຳລັບເນື້ອຫາ, ແລະ dynamic ເມື່ອຈຳເປັນເທົ່ານັ້ນ.
- ໃຊ້ TypeScript ແບບ strict ຄູ່ກັບການກວດສອບຂໍ້ມູນຕອນເຮັດວຽກຢູ່ທຸກຂອບເຂດຂອງລະບົບ.
- ວັດປະສິດທິພາບຈາກຜູ້ໃຊ້ຕົວຈິງ, ແລະ ຖືວ່າການເຂົ້າເຖິງໄດ້ເປັນສ່ວນໜຶ່ງຂອງຄຳວ່າ "ສຳເລັດ".
ສະຫຼຸບ
ຊຸດເທັກໂນໂລຊີ React ສະໄໝໃໝ່ໃຫ້ລາງວັນແກ່ທີມທີ່ເຂົ້າໃຈວ່າໂຄດຂອງຕົນເຮັດວຽກຢູ່ໃສ. ການ render ເທິງເຊີບເວີເປັນຄ່າເລີ່ມຕົ້ນ, ການສົ່ງ JavaScript ສະເພາະສຳລັບການໂຕ້ຕອບແທ້ໆ, ແລະ ການບັງຄັບໃຊ້ type ກັບການກວດສອບຂໍ້ມູນຢູ່ຂອບເຂດຂອງລະບົບ ຈະເຮັດໃຫ້ແອັບຂອງທ່ານໂຫຼດໄວ, ຕິດອັນດັບດີ ແລະ ຍັງແກ້ໄຂໄດ້ງ່າຍເຖິງວ່າລະບົບຈະເຕີບໂຕຂຶ້ນ.
ອ່ານເພີ່ມເຕີມ
- #Next.js
- #React
- #TypeScript
- #Web Performance




