將你寫的 react code 轉換成 html 顯示在 UI 上的過程分為:
Client Side Render: 傳入空的html ,透過 bundel後的js 將頁面加載
Server Side Rendering: 對於client 請求,server 都會回傳 render 完的 HTML
Static Side Generation: 在server build時候就產生出 HTML
Incremental Static Regneration: 部分頁面由SSG產生,但 request 找不到對應靜態頁面,會透過SSR 產生,並快取起來。也可透過 revalidate 定期去更新 SSR 快取出來的頁面
如何判斷頁面為 SSR CSR:
Server Components 目前並不支援 CSS-in-JS,可以考慮使用 styled-component
透過 tsconfig.json 中的 compilerOptions 去修改 import 時的 alias
*// before*
import { Button } from '@/components/button'
*// after*
import { Button } from '@/button';
page.tsx 就不會被當成 router segment,就可以開/components、/utils 放一些共用元件layout.tsx template.tsx ,可以共用讓子segment 共用元件,layout.tsx 在頁面切換不會重新渲染,而 template.tsx 會重新渲染。只有root layout可以包含, html body taguseSelectedLayoutSegment() 可以抓到這個 元件/layout 現在在哪個 segment (同一層會回傳 null,最多只能回傳到下一層的 segment)vercel 新開發出來的打包工具(Rust 寫的),目前僅能用在 nextjs,速度在大規模的component 上快很多
page.tsx 使用來定義 UI 的檔案
layout.tsx:
'use client' 可轉換為 Client Component'use client' ,在Root 的 Server Component 再 import 近來找不到 [id] 還可以有default page
<Link> 是一個元件,useRouter: 比較像是不用透過使用者互動,直接在程式碼控制const router = useRouter();
....
router.push('/');
router.replace() // 不要有紀錄
roouter.prefetch()
router.back() // 上一頁
router.forward() // 下一頁
官方說能用 就用 不能用在用 useRouter
(xxxx) : 作為實體檔案分類,但卻不會被判定為路由
Root Layout
可以在app 層建立 (xxxx) 底下的segment,就不會吃到 app 的 layout 了
folder 命名為 @xxxx 可以在 page 中的 props 載入該頁面,包含他的 error loading
在目前頁面跳出 類似 modal 的頁面
命名方式
建立 routs.js
提供了 GET、POST、PUT、PATCH、DELETE、HEAD、OPTIONS 方法
??
https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations#cookies
呼叫完 action,可用 revalidatePath 清除快取重新讀取渲染頁面
Form Actio
export default function ToDo() {
const addTasks = async () => {
'use server';
...
};
const onSubmit = async () => {
'use server';
...
};
return (
<form action={onSubmit}>
<button formAction={addTask}>Add a Task</button> // 呼叫額外的 server action
<button type='submit'>Submit</button> // 觸發 onSubmit
</form>
);
}
將圖檔轉成 webp/avif,更小的檔案但品質還不錯
//local image
const nextConfig = {
images: {
formats: ['image/avif', 'image/webp'],
},
};
module.exports = nextConfig;
避免 loading shift: 圖檔讀取完後,擠壓到其他元件
預設 lazy loading
placeholder='blur’,載入完成前先顯示
<img> 並非 (<Image>) 加上loading="lazy",viewport 靠近才會載入
// remote
const nextConfig = {
images: {
remotePatterns: [{
protocol: 'https',
hostname: 's3.amazonaws.com',
port: '',
pathname: '/my-bucket/**',
}],
},
};
module.exports = nextConfig;
不知道圖片尺寸,可以先用 div 開一個確定的長寬,再包裹 Image ,避免 loading shift
{/* 父層必須是 position relative */}
<div className='w-[500px] h-[500px] relative'>
<Image
src='...'
alt='hero image'
fill
/>
</div>
將bundle 拆成小一點的過程,可以觀察 /.next/static/chunks/app 打包完的資料大小
用意減少向 Data Source 要資料(並非 rendering 階段)
解除 Data Cache 方法:
每次清除快取
定時清除快取
將 Fetch 回來的資料 放在記憶體,若有其他 component 也打了一樣 API,實際上不會送request 而是去記憶體拿 (在server rendering 階段)
禁用 request memoization
使用,假設 A B C 三頁面都有各打API去取得隨機動態資料,但使用 在這三個頁面輪替,資料並沒有改變,因為next 對於 segment 靜態頁面(Server 在 build 時就產生出來)的快取,如果是每次打 request 動態渲染就不會
https://ithelp.ithome.com.tw/users/20161853/ironman/6122