全部技能

vercel-react-best-practices (vercel-labs/agent-skills)

把 Vercel 的 React 與 Next.js 效能指南套用到元件、資料取得與打包上。

Vercel 的 React 最佳實務:把一個 Next.js 最佳化從 2.3 提升到 3.6/5,但一句話版本只花 75% 的 Token 就達到 4.6

視情況推薦安全

Codex CLI · gpt-6-astra

24.3 / 30

相對未使用技能的提升:+0.85 · 視情況推薦 · 18 次執行

視情況推薦:提升幅度 +0.85 低於 +1.0。推薦條件為總分至少 22/30、產出品質至少 3.5、提升幅度至少 +1.0。

SOTA

透過

使用 Codex 測試。

涵蓋 Codex, Claude Code

Codex CLI 0.166(SOTA 等級):18 次評分執行。依我們的等級規則,在這裡通過也涵蓋 Claude Code;但這不代表第二等級的結果。

分數

每個維度為 0 到 5 分,六個維度相加即為滿分 30 的總分。每個維度都是 5 分最好。成本 5 分代表便宜又快速;安裝 5 分代表容易安裝。

觸發可靠性
5.0
相對未使用技能的提升
2.9
產出品質
4.4
Token 與時間成本
3.0
安裝與可攜性
4.0
安全性
5.0

安全審查

安全

靜態掃描:6 CRITICAL / 0 HIGH / 0 MEDIUM。人工審查:可在無網路沙箱中安全執行(已說明掃描器的發現)。掃描結果不能證明技能一定安全。

安裝

npx skills@latest add vercel-labs/agent-skills --skill react-best-practices

來源

固定 Commit: 1a2c79d4e6c4a2283dc2c614b6538cbe1ed5ca62

測試日期: 2026-11-02

我們測了什麼

  • 儀表板效能審查 — 審查 OrdersDashboard.tsx 與 page.tsx(Next.js 15 應用程式)的效能問題。依嚴重程度列出,最嚴重的排前面,每項都要附上檔案與修改方式。不要修改任何檔案。把清單寫在最終回答中。
  • 就地最佳化儀表板元件 — 最佳化 OrdersDashboard.tsx 的效能。就地編輯檔案,維持行為與元件的 props 不變。(沒有網路,也不能 npm install;不要嘗試執行它。)
  • 撰寫儀表板伺服器頁面 — 撰寫 app/dashboard/page.tsx,一個 Next.js 15 伺服器元件(App Router)。對已登入的使用者('@/lib/auth' 的 getSession() 傳回 { userId }),需要從 '@/lib/data' 取得 getProfile(userId)、getRecentOrders(userId) 與 getRecommendations(userId)…

優點

  • 相對未使用技能,平均分數從 3.57 提升到 4.43(+0.85)。
  • 技能即使未被點名也會被採用:6/6 次實驗組執行都讀取了技能檔案。

缺點

  • 一句話提示得分 4.73,使用技能則為 4.43(-0.30)。
  • Token 用量是未使用技能的 1.53 倍。
  • 每個任務的每個組別 n=2;約 1 分以內的差異屬於雜訊。

評測

在 Mac 測試機上使用 Codex CLI 0.166(gpt-6-astra,低推理),每次執行都使用全新的暫存專案與暫存的 HOME/TMPDIR/快取;技能已安裝(實驗組)、未安裝(對照組),或未安裝但把技能的核心要求濃縮成一句話附在提示詞後(一句話提示組)。每個任務的每個組別執行 2 次,關閉網路,封鎖 /tmp 寫入。提示詞從未提及技能(下方註明的措辭除外)。三個任務使用小型 Next.js 15 測試專案:審查儀表板元件與頁面的效能(11 個植入問題,依嚴重程度排序);就地最佳化元件(10 項檢查:Promise.all、直接匯入而非 barrel、不整包匯入 lodash、對笨重的編輯器使用 next/dynamic、把 Row 提升到元件外、用衍生清單取代 effect 中的 setFiltered、不要 orders.length &&、延遲初始化 state、Map 查找、被動式 scroll 監聽器);為一個慢速與兩個快速的資料呼叫撰寫伺服器頁面。

三組對照

組別平均分數(0-5)每次執行 Token 用量
未使用技能3.5767k
一句話提示4.7377k
使用技能4.43103k

以 Codex CLI 執行 18 次,採規則式檢查評分,不經 LLM 評審。總分 24.3 / 30,評級為 視情況推薦。

評定:視情況(24.3 / 30)。 來源:vercel-labs/agent-skills,skills/react-best-practices,固定於 commit 1a2c79d。安裝:npx skills@latest add vercel-labs/agent-skills --skill react-best-practices。授權: MIT(儲存庫 LICENSE)。

這是什麼

vercel-labs/agent-skills 的 vercel-react-best-practices 技能(目錄為 react-best-practices):70 份 Markdown 規則檔,依影響分組(請求瀑布、打包體積、伺服器端效能、用戶端資料擷取、重新渲染、渲染、JS 效能、進階模式),外加一份編譯後的 AGENTS.md。SKILL.md 是索引;agent 只載入需要的規則。沒有腳本。

我們如何測試

在 Mac 測試機上使用 Codex CLI 0.166(gpt-6-astra、低推理),每次執行都使用全新的臨時專案與臨時 HOME/TMPDIR/快取,安裝技能(使用技能組)、不安裝(對照組),或是不安裝但把技能核心要求濃縮成一句話附加在提示詞後(一句話組);每個任務的每組各執行 2 次,關閉網路、封鎖 /tmp 寫入。提示詞完全沒有提到技能名稱(下述措辭除外)。

三個任務,使用小型 Next.js 15 測試素材:審查一個儀表板元件與頁面的效能(11 個植入問題,依嚴重程度排序);就地最佳化該元件(10 項檢查:Promise.all、直接匯入而非 barrel 檔、不整包匯入 lodash、以 next/dynamic 載入重量級編輯器、把 Row 提升到元件外、以衍生清單取代 effect 中的 setFiltered、不要 orders.length &&、延遲初始化 state、Map 查表、被動捲動監聽器);為一個慢速與兩個快速資料呼叫撰寫伺服器頁面。

  1. 儀表板效能審查 — 審查 OrdersDashboard.tsx 與 page.tsx(一個 Next.js 15 應用程式)的效能問題。依嚴重程度列出,每項附上檔案與要改什麼。請勿變更任何檔案。把清單寫在最後的答案中。
  2. 就地最佳化儀表板元件 — 最佳化 OrdersDashboard.tsx 的效能。就地編輯檔案,保持行為與元件的 props 不變。(沒有網路,也不能 npm install;不要嘗試執行。)
  3. 撰寫儀表板伺服器頁面 — 撰寫 app/dashboard/page.tsx,一個 Next.js 15 伺服器元件(App Router)。對已登入使用者(getSession() 來自 '@/lib/auth',回傳 { userId }),它需要來自 '@/lib/data' 的 getProfile(userId)、getRecentOrders(userId) 與 getRecommendations(userId)…

評分採程式化方式(隱藏測試/植入問題召回/限制條件檢查/視情況搭配渲染+OCR),每次執行 0–5 分。所有分數都不是由 LLM 評審決定。

結果

給第三組的一句話提示:"依下列順序修正 React/Next.js 效能:移除請求瀑布(用 Promise.all 同時啟動獨立請求,並以 Suspense 串流慢速部分)、縮小打包體積(直接匯入而非透過 barrel 檔,用 next/dynamic 對重量級元件做程式碼分割),再避免不必要的重新渲染(在渲染期間衍生值、不要在元件內定義元件、把靜態值提升、使用延遲 state 初始化、Map 查表、被動捲動監聽器)。"

任務對照組分數一句話提示使用技能對照組 token一句話組 token使用技能 token技能讀取
t1-review3.914.644.6465k45k75k2/2
t2-optimize2.274.553.6490k130k163k2/2
t3-write4.545.05.045k53k69k2/2

平均分數:未使用技能 3.57,使用技能 4.43(差異 +0.85)。每次執行 token:67k 對 103k(1.53x);時間 47 秒對 52 秒。一句話組:4.73(技能相對一句話提示的增益:-0.3;一句話提示相對未使用技能的增益:+1.15);一句話組每次執行 77k token,因此技能成本是一句話提示的 1.34 倍。

實際情況

  • 就地最佳化最能看出差異:對照組 2.27、使用技能 3.64、一句話版本 4.55(每組兩次執行結果相同)。對照組與技能都保留了 barrel 匯入 from '@/components',也都沒做程式碼分割;對照組還保留了循序 await 與非被動的捲動監聽器。技能修好了瀑布與捲動監聽器,但沒修 barrel 匯入或重量級編輯器的動態匯入;一句話提示因為直接指名這些規則,兩者都修好了。
  • 審查任務:找到的植入問題,對照組是 9、7(平均 8),技能與一句話組都是 10、10(各找到 11 個中的 10 個;orders.length && 渲染出 0 的問題,各組每次執行都漏掉)。分數:對照組 3.91、技能 4.64、一句話組 4.64。
  • 撰寫任務:各組都把慢速的推薦呼叫放在 Suspense 後面,並讓頁面保持伺服器元件;對照組有時依序 await 三個呼叫(分數 4.1 與 5.0,技能兩次都 5.0,一句話組兩次都 5.0)。
  • 編輯檔案時,沒有任何一組修正 orders.length &&,所以技能裡的一條規則(rendering-conditional-render)沒有進入任何一次編輯。
  • 技能在 6/6 次執行中都被讀取,成本 103k token,對照組 67k(1.5x),一句話組 77k(1.3x)。整體平均:對照組 3.57、技能 4.43、一句話組 4.73。
  • 分析期間修正過一次評分:第一輪誤把頁面與 Map 檢查標為未通過,因為檔案寫在 app/dashboard/page.tsx,而 Map 有標型別(new Map<string, string>());兩個正規表達式都修正後,重新檢查全部 18 次執行。

面向分數

面向分數原因
1_output_quality4.43

使用技能時平均 4.43/5(程式化檢查,見各任務表)。

2_lift_vs_no_skill2.85

相對未使用技能的 3.57 提升 +0.85 分(每個任務 n=2;約 1 分以下屬雜訊)。

3_trigger5.0使用技能組 6/6 次執行都讀取技能檔案。
4_instructions_portability4

專屬於 React/Next.js;純 Markdown,其他 agent 也能載入;遵循開放的技能版面。

5_efficiency3token 1.53x(每次執行 103k 對 67k)、時間 1.10x(52 秒對 47 秒)。
6_safety_hygiene5

只有 Markdown 規則檔;6 個掃描器命中是程式碼範例中的 document.cookie,已依上下文讀過。

這項測試的限制

  • 小型測試素材,帶有已知的教科書問題;只最佳化了一個元件,因此每組兩次執行基於相同原因得到相同結果(兩次執行完全相同)。
  • 技能的 70 條規則只透過三個任務演練;伺服器快取、SWR、事件監聽器與進階規則都沒有埋入測試。
  • 一句話版本列出測試所檢查的相同規則,因此它是短提示的上限,不能公平代表不知道這些規則的使用者。
  • 每組每任務 n = 2:約 1 分以下的差異屬雜訊。
  • 規則式評分只能衡量檢查項目看得到的部分,無法判斷品味,也無法判斷結果是否為最佳。

安全性

請見 security.md。掃描:CRITICAL 6 / HIGH 0 / MEDIUM 0。評定:可安全執行(無網路沙盒)。掃描乾淨並不代表技能安全。

總結

相較於什麼都不做,這項技能明顯改善了效能審查與就地最佳化,而這正是它的重點。一句指名相同規則的短提示在最佳化任務上表現更好、成本也更低,因此價值主要在於知道規則名稱;技能的規則檔讓使用者不必自己知道這些名稱,但在這些執行中仍沒能觸及 barrel 匯入與程式碼分割的規則。

完整紀錄

執行日誌:vercel-react-best-practices (Codex CLI, network off, per-run temp HOME/TMPDIR, one row per graded run.)
欄位:任務、組-輪次、得分(0-5)、token、秒、通過的檢查、代理開啟的 skill 檔案。

t1-review control-1: 得分 4.27, token 65319, 秒 49.8, 檢查 2/2, 未開啟
t1-review control-2: 得分 3.55, token 65797, 秒 42.7, 檢查 2/2, 未開啟
t1-review oneliner-1: 得分 4.64, token 45347, 秒 43.5, 檢查 2/2, 未開啟
t1-review oneliner-2: 得分 4.64, token 45242, 秒 52.5, 檢查 2/2, 未開啟
t1-review treatment-1: 得分 4.64, token 75664, 秒 52.7, 檢查 2/2, 開啟 react-best-practices
t1-review treatment-2: 得分 4.64, token 75106, 秒 52.1, 檢查 2/2, 開啟 react-best-practices
t2-optimize control-1: 得分 2.27, token 81770, 秒 63.5, 檢查 5/10, 未開啟
t2-optimize control-2: 得分 2.27, token 99616, 秒 48.7, 檢查 5/10, 未開啟
t2-optimize oneliner-1: 得分 4.55, token 141803, 秒 75.2, 檢查 9/10, 未開啟

18 次執行、3 個產出檔案

範例產出

SOTA · 装了 skill:final message(t1-review,第 1 次,Codex)

Ranked by likely impact; no files changed. 1. **`OrdersDashboard.tsx:16` — Storage access breaks server rendering and repeats on every render.** `localStorage` is unavailable during Next.js prerendering; `'use client'` doesn’t prevent that. Initialize settings with a stable default, then read and safely parse storage once after mounting. A lazy initializer alone won’t fix server access. [Next.js rendering guidance](https://nextjs.org/docs/app/getting-started/server-and-client-components) 2. **`page.tsx:8–11` — Independent server requests run sequentially.** After `getUser`, start settings, invoices, and notifications together using `Promise.all()`. Their latency currently adds up unnecessarily. 3. **`OrdersDashboard.tsx:19–28` — Initial data waits for hydration, then follows a request waterfall.** Fetch initial data in a server parent where practical. Otherwise, after fetching `me`, request orders and customers concurrently with `Promise.all()`. Neither depends on the other. 4. **`OrdersDashboard.tsx:45–47` — Every dashboard render remounts every row.** Defining `Row` inside the component creates a new component type each render, including during scrolling and typing. Move it to module scope; consider `React.memo` with stable props. 5. **`OrdersDashboard.tsx:17,34–38,55` — Scrolling rerenders the entire dashboard.** Each scroll update repeats filtering, sorting, joins, and rendering. Move scroll state into a small standalone indicator component; throttle updates if exact continuous tracking isn’t necessary. 6. **`OrdersDashboard.tsx:7,54` — The markdown preview is eagerly loaded even for an empty footer.** Use `next/dynamic` for the preview and render it only when footer content exists. Defer mounting until needed if it is below the fold. 7. **`OrdersDashboard.tsx:40–43` — Repeated expensive calculations and quadratic customer lookups.** Memoize derived results, build a customer-ID `Map` when customers change, and parse dates once before sorting instead of inside every comparison. The join then costs O(orders + customers), rather than O(orders × customers). 8. **`OrdersDashboard.tsx:15,30–32` — Derived state causes an extra render per search/data change.** Remove `filtered` state and its effect; derive it with `useMemo`. For large datasets, use `useDeferredValue(query)` with memoized results to keep typing responsive. 9. **`page.tsx:9–15` — All sections wait for the slowest request.** Start requests together, then await them inside separate async sections under `Suspense`. This allows the sidebar to appear without waiting for feed data; wrapping JSX after all awaits won’t help. 10. **`OrdersDashboard.tsx:53` — Every matching row is mounted.** For large order collections, paginate or virtualize the table. Prefer server pagination/filtering when fetching the entire collection also becomes expensive. 11. **`OrdersDashboard.tsx:3–6` — Import cleanup and a potential barrel-import cost.** Remove unused lodash, icons, `Modal`, and `isAfter`; import used local components directly rather than through `@/components`. Confirm bundle impact before claiming unused imports ship to clients. Named `date-fns` and `lucide-react` imports already rece [... excerpt: first 3200 of 3335 characters]

檢視 Pro