AI 工具 24 min read

review-animations skill 實測:8 條意見零誤報,漏了 3 處

review-animations 是 Emil Kowalski 以 MIT 開源的動畫審查 skill,拿 10 條標準比對 diff、一定判 Block 或 Approve,只能打 /review-animations 點名。我拿它審部落格剛上線的動畫 commit,8 條意見 3 條在正式站重現、0 條誤報——但漏了 3 個量得到的問題,適合當第二雙眼睛。

review-animations skill 實測:8 條意見零誤報,漏了 3 處
本文目錄 · 11
懶人包
  • review-animations 是 Emil Kowalski 開源在 emilkowalski/skills(MIT)裡的動畫審查 skill,2026-06-18 加入 repo。它只審動畫:拿 10 條標準逐條比對一份 diff,輸出「修改前/修改後/原因」對照表,最後一定給 Block 或 Approve。
  • 它的 frontmatter 設了 disable-model-invocation: true:裝了模型也不會自己叫它,一定要打 /review-animations 點名。我在同一個資料夾拿掉斜線再跑一次,模型改去載入 apple-design。
  • 我拿它審部落格 2026-10-21 剛上線的動畫 commit 07d7267:它提 8 條意見、判 Block。到正式站用 Playwright 逐條驗,3 條實際重現、沒有一條是誤報,但它漏了 3 個量得到的問題。
  • 最值得看的一條:減少動態模式下改成「全站 150ms 過渡」,實測有 transition 的元素從 714 個裡的 64 個變成 714 個全部,開了減少動態的人反而看到更多動畫。
  • repo 在 2026-10-21 是 48,156 stars、2,785 forks,這是整個 repo 15 支 skill 共用的數字。
  1. review-animations 是什麼、解決什麼問題?
  2. 10 條標準在審什麼?
  3. 它會輸出什麼格式?
  4. 為什麼它預設就是擋下?
  5. 跟 improve-animations 怎麼分工?
  6. disable-model-invocation 是什麼意思?
  7. 怎麼安裝到 Claude Code?
  8. 實測:拿它審我部落格剛上線的動畫
  9. 限制與踩坑
  10. 適合誰、不適合誰?
  11. 延伸資源

🔍 review-animations 是什麼、解決什麼問題?

review-animations 是兩個檔案:SKILL.md(120 行)講審查方法,STANDARDS.md(187 行)是規則與數值的查表。作者在 SKILL.md 開頭就把範圍鎖死:它只做一件事,審動畫和動效程式碼;不寫功能、不修無關的 bug,被要求審一般程式碼時要拒絕,改推薦一般的 review skill。

它要擋的是「能動,但手感不對」的動畫。原文的說法是:一個能跑、卻感覺遲鈍、從錯的位置長出來、觸發太頻繁或掉幀的過場,算回歸,不算通過。一般的 code review 看的是邏輯對不對;動畫用了 ease-in、選單從中心縮放、篩選每點一次都跑 220ms,這類問題測試抓不到,畫面也「沒有壞」,最容易一路被 merge 進去。

作者 Emil Kowalski 的個人網站寫他目前在 Linear 的 Web team,前端圈較熟悉的作品是 sonner 和 vaul。SKILL.md 寫明,標準本身來自他在 animations.dev 的動畫理念,審查的「方法」(不可妥協的標準、升級觸發條件、修正優先順序、分層輸出、明確的核准條件)則是借自嚴格的程式碼品質審查。

📏 10 條標準在審什麼?

SKILL.md 列了 10 條「不可妥協的標準」,diff 裡每段動畫都要逐條比對,違反任何一條就算一個 finding。我依原文轉述,數值從 STANDARDS.md 補上:

#標準審什麼(附原文給的數值)
1動畫要有理由每段動畫都要答得出「為什麼要動」:空間一致、狀態提示、回饋、說明、避免突兀。常看到的元素只因為「好看」就動,直接擋
2依頻率決定一天 100 次以上或鍵盤觸發的動作不做動畫;一天幾十次的(hover、列表導覽)刪掉或大幅縮減;偶爾出現的(modal、drawer、toast)用標準動畫;第一次或很少見的才能加驚喜
3曲線要快速回應進出場用 ease-out 或自訂強曲線,UI 上用 ease-in 一律擋。內建的 CSS 曲線太弱,建議 cubic-bezier(0.23, 1, 0.32, 1)
4UI 動畫低於 300ms按鈕回饋 100–160ms、tooltip 125–200ms、下拉選單 150–250ms、modal 與 drawer 200–500ms
5起點與物理正確popover、dropdown、tooltip 要從觸發點縮放,不是從中心;永遠不要從 scale(0) 開始,改用 scale(0.9–0.97) 加透明度。modal 例外,維持置中
6可中斷快速連點或手勢驅動的動畫要能從當下狀態轉向,用 CSS transition 或 spring,不要用每次都從頭播的 keyframes
7只動 GPU 屬性只動 transform 和 opacity,動 width、height、margin、top 這類版面屬性算效能問題
8無障礙要處理 prefers-reduced-motion,而且是「更溫和」不是「歸零」:保留透明度與顏色,拿掉位移。hover 動畫要包在 (hover: hover) and (pointer: fine) 裡
9進出不對稱刻意的動作(按住、確認刪除)可以慢,系統回應要快。按下與放開用同樣時間算一個 finding
10風格一致動畫個性要跟元件和產品一致,活潑的可以彈一點,儀表板要俐落。拿不定主意時,最有力的做法常常是刪掉
另外有一份「看到就重判」的清單,包括 transition: all、scale(0)、UI 上的 ease-in、超過 300ms 沒說明理由、沒處理減少動態、沒包條件的 :hover、該加 30–80ms stagger 卻全部同時出現。

修正建議也有排序,共 9 級,越前面越優先:先考慮刪掉,再來是縮減,然後才是改曲線、改起點、改成可中斷、搬到 GPU、調不對稱時序,最後才是加 stagger 或 @starting-style 這類潤飾。這個順序代表它的第一建議常常是「拿掉」,而不是再補一層效果。

🧾 它會輸出什麼格式?

輸出固定兩段,順序不能換:

  • 第一部分:一張表。欄位是 Before | After | Why,一個問題一列,原文特別寫「不要用 Before:/After: 條列」。要附 檔案:行號,需要具體數值(曲線、時間、spring 參數)時要從 STANDARDS.md 抄,不准估。
  • 第二部分:分層結論。依影響排序:手感劣化、該刪沒刪、效能、可中斷與時序、起點與風格、無障礙,空的層級省略。
最後一定要給二選一的判定:
  • Block:只要有一個手感劣化、在鍵盤或高頻動作上加了動畫、UI 用了 scale(0) 或 ease-in,或有容易改成 GPU 屬性卻沒改的非 GPU 動畫,就擋。
  • Approve:沒有手感劣化、沒有該刪的動畫、時間與曲線都在範圍內、該可中斷的有處理、有顧到減少動態,全部成立才放行。
另一個小細節:如果只打 /review-animations 不帶任何問題,SKILL.md 規定它只回一句「準備好用高標準審你的動畫了」,其他什麼都不說,要你再丟問題。

🧱 為什麼它預設就是擋下?

frontmatter 的 description 最後一句是「Default to flagging; approval is earned.」,正文的「Operating Posture」也寫:預設是標記問題,核准要靠自己爭取,不是預設給的。

我讀完兩份檔案,認為嚴格有它的道理,理由寫在規則本身:

  • 動畫的回歸很安靜。功能壞掉有測試會紅,動畫手感變差只會讓人「覺得有點卡」。審查如果預設放行,這類問題幾乎不會被擋。
  • Block 條件是可檢查的。ease-in、scale(0)、transition: all 都是 grep 得到的字面值,不是審查者的心情。嚴格加上具體條件,比「感覺還行」更容易重現。
  • 它的修正方向偏向刪減。預設擋下配上「先刪再改」的優先序,結果常常是程式碼變少,而不是多加一層動畫庫。
代價是它會擋下一些屬於設計取向的寫法。我的實測裡就有這種:退場用 ease-in 在不少設計系統裡是刻意的選擇,這支一律判違規。要不要照做,需要人來決定。

🤝 跟 improve-animations 怎麼分工?

同 repo 的 improve-animations 也在管動畫品質,兩支的 SKILL.md 自己把界線寫清楚了:

比較review-animationsimprove-animations
審查範圍一份 diff 或指定的幾段動畫整個 codebase 的動畫與動效程式碼
產出對照表加 Block/Approve 判定依優先排序的稽核結果,加上一份份實作計畫,寫在 plans/ 資料夾
會不會改程式碼不會,只給意見不會改原始碼,只寫 plans/ 底下的檔案
觸發方式只能 /review-animations 點名模型可依 description 自動判斷
典型時機PR 送出前、merge 前想知道「整個產品的動畫哪裡該改」
improve-animations 的 SKILL.md 直接寫它「不審單一 diff(那是 review-animations 的事)」。兩支還有一個接點:improve-animations 的 execute <plan> 會派子 agent 去實作計畫,做完再用 review-animations 的標準審那份 diff、給判定。也就是說,improve-animations 負責找出要改什麼、寫成計畫,review-animations 負責驗收改完的結果。

🔒 disable-model-invocation 是什麼意思?

review-animations 的 frontmatter 有一行:

disable-model-invocation: true

Claude Code 平常會把每支 skill 的 description 列給模型看,由模型判斷要不要載入。這行設成 true 之後,模型就不能自己決定叫它,只有使用者打 /review-animations 才會執行。同 repo 15 支裡設了這行的有 3 支:pick-ui-library、prototype、review-animations。

我從實驗的 stream-json 紀錄確認這件事。同一個實驗資料夾、同一句需求跑兩次:

次數需求開頭session 初始化清單有沒有 review-animations實際載入的 skill
run5/review-animations有review-animations,並讀了 STANDARDS.md
run6拿掉斜線,其餘一字不改有apple-design(模型自己選的)
兩次的清單都列著 review-animations,所以不是沒裝好。沒有斜線時模型叫不到它,就改去用它叫得到、description 也對得上的 apple-design。把審查設成只能點名,我認為是合理的設計:嚴格的 Block 判定如果在寫功能途中自動跳出來,會很干擾。

⚙️ 怎麼安裝到 Claude Code?

README 給的是一次裝整個 repo,會進入互動選單:

npx skills@latest add emilkowalski/skills

只要這一支,加 --skill 指定名稱。我在 2026-10-21 用 npx skills@latest add --help 確認過,當天的 skills CLI 是 1.7.4 版,-s, --skill 參數存在:

npx skills@latest add emilkowalski/skills --skill review-animations

要指定只裝給 Claude Code、跳過確認,可以再加 --agent claude-code -y。我的實驗資料夾則是直接把 repo 裡的 skills/review-animations/ 整個複製到 .claude/skills/review-animations/,兩個檔案都要在,因為 SKILL.md 會在需要數值時去讀 STANDARDS.md。

裝完開一個新的 Claude Code session,輸入 / 看清單裡有沒有 review-animations。

🧪 實測:拿它審我部落格剛上線的動畫

apple-design 那篇最後,我照 apple-design 的規範替這個部落格加了一批互動細節,commit 07d7267,2026-10-21 部署。用 A skill 寫出來的東西,剛好拿 B skill 來審。

怎麼跑的

  • 開一個新的 git 資料夾,先放 07d7267 前一版的檔案當 baseline,再提交 07d7267 版的 global.css、BlogFilters.tsx、NavbarNeub.astro,最新一個 commit 是 3 個檔案、新增 141 行。
  • 把 skill 放進 .claude/skills/review-animations/。
  • 用 Claude Code 2.1.306(模型 Opus 5.5)跑一次,需求是:
/review-animations 請審查最新一個 commit(HEAD,git show HEAD 可看 diff)新增的動畫:src/styles/global.css、src/components/BlogFilters.tsx、src/components/NavbarNeub.astro。用繁體中文回答。

這次花了 125 秒、4 個回合、0.67 美元。stream-json 裡看得到它先讀了 .claude/skills/review-animations/STANDARDS.md,輸出也照規定的表格加 Block 格式。

review-animations 對 07d7267 的原始輸出:8 列 Before/After/Why 對照表,最後判定 Block

8 條意見,逐條驗證

光看它講得頭頭是道不夠,我用 Playwright 到正式站 yanchen.app 逐條量。下表的「判定」是我對照實測或程式碼後的結論:

#它指出的問題我怎麼驗判定
1global.css:65 減少動態模式改成 * { transition-duration: 150ms },但 transition-property 的初始值是 all,原本沒有過渡的元素全都會跑 150ms一般模式下 714 個元素裡有 64 個帶 transition;切到 reduce 後 714 個全部帶,body、p 都變成 all 0.15s真問題,已重現
2篩選卡片退場用 cubic-bezier(0.4, 0, 1, 1)(ease-in),而且退場卡片還佔著格子,grid 會先變長再塌回去點「AI 部署」:89ms 精選區立刻消失、125 個動畫開始跑;279ms 時 grid 高度從 19,470px 一次掉到 449px版面跳動是真問題,已重現;ease-in 符合它的標準,但是不是錯屬於設計取向
3篩選是高頻操作,進場應拿掉 8px 位移,只留淡入,改用 ease-out 強曲線依標準 2 的頻率表推論風格建議,不是 bug
4迴圈裡每張卡先 getComputedStyle 再寫入,讀寫交錯造成 layout thrash讀程式碼成立,我沒有量效能技術上成立,影響未實測
5手機選單收合用 ease-in 140ms程式碼確實是 cubic-bezier(0.4, 0, 1, 1)符合它的標準,同第 2 條屬於設計取向
6setTimeout(finishClose, 300) 沒存 id、沒清掉,收合、反向、再收合時第二次會被提早切掉正常收合從點擊到 open=false 是 169ms;照它描述的順序操作,第二次收合 51ms 就被切掉真問題,已重現
7全螢幕面板 transform-origin: top right 加 scale(0.96),左邊緣會橫移約 15px390px 寬的手機視窗,面板第一幀 left 是 16px、寬 374px,之後收到 1px數字正確;看起來歪不歪是主觀
8.lift 的 box-shadow 過渡每幀重繪這段是 07d7267 之前就有的,它也註明了成立但優先度低,未實測
8 條裡沒有一條是誤報。3 條我在正式站量到了,2 條讀程式碼成立,剩下 3 條是「它的標準這樣規定,但屬於設計選擇」。 在部落格列表點「AI 部署」分類後約 70ms 的畫面:不屬於該分類的卡片正在原地淡出、仍佔著格子,列表標題還顯示 121 posts

它漏掉的 3 個問題

同一批量測也找到它沒提、甚至判錯的地方:

  • 帶網址參數進站還是會跑動畫。BlogFilters.tsx 用 hasApplied 想讓「第一次套用篩選」不跑動畫,但從網址讀條件的 effect 是另外一輪。我用 /blog/?cat=工程師日常 進站,載入後約 889ms 一次跑了 124 個動畫。
  • 減少動態模式下封面圖仍會縮放。global.css 在 reduce 裡把 .cover-img 設成 transform: none,但卡片 hover 用的是 Tailwind 的 scale-*,那是獨立的 scale 屬性,transform: none 管不到。實測 reduce 下 hover,scale 仍是 1.03,配 0.15s 過渡。它在結論裡把這段列為「做得對的地方」,這一點判錯了。
  • 漢堡圖示比面板晚一步。X 形狀的樣式綁在 .mobile-menu[open] 上,收合期間 [open] 還在,所以面板 140ms 收完、open 變成 false 之後,圖示才開始 200ms 的變形,量到約 370ms 才回到三條線。

對照:沒點名時拿到什麼

run6 拿掉斜線、其他一字不改,模型自己載入了 apple-design,花 137 秒、0.80 美元,列了 7 個問題。它也抓到版面跳動、減少動態把旋轉放回來、計時器沒清,還多抓到上面那個漢堡圖示延遲。但它沒有 Block/Approve 判定,有一條是誤報:它說 viewport-fit=cover 不存在所以安全區域無效,其實那行寫在 src/layouts/RootLayout.astro,只是我沒複製進實驗資料夾,正式站的 viewport meta 裡有。它還把 hasApplied 誇成「首次載入不跑動畫」,同樣判錯。

這兩次放在一起看,我的結論是:review-animations 多給的是審查紀律,不是更好的眼力。兩次抓到的核心問題重疊不少;點名 review-animations 的那次多了曲線、讀寫交錯、起點這類照標準逐條掃出來的項目,還有一個不能含糊的判定。兩次都只讀程式碼,跟實際跑起來的落差,都要靠量測補。

🕳️ 限制與踩坑

  • Git Bash 會吃掉開頭的斜線。我在 Windows 的 Git Bash 跑 claude -p "/review-animations ...",第一次 skill 沒被載入,原因是 MSYS 把 /review-animations 當成路徑轉換掉了。命令前加 MSYS_NO_PATHCONV=1 才正常。從 stream-json 看有沒有讀 STANDARDS.md,是確認 skill 有生效最快的方法。
  • 只問 /review-animations 會只回一句話。SKILL.md 規定沒帶問題時只回準備好了,要把審查範圍直接寫在同一句。
  • 它只讀程式碼,不會跑頁面。這次漏掉的 3 個都要實際操作才看得到:網址參數、Tailwind 的獨立 scale 屬性、選單的時序。它給的 Block 理由可以信,但「沒提到」不等於沒問題。
  • 它的標準會跟你的設計取向衝突。「UI 一律不准 ease-in」是 Emil 的立場,退場要不要用 ease-in 是可以討論的設計決定。我會把這類意見當成「要回答得出理由」,不是一定照改。
  • 全域設定會影響結果。我的對照組會自動跑去用 apple-design,是因為我的 ~/.claude/skills/ 本來就裝了它。換一台機器、裝了不同的 skill,沒點名時的行為會不一樣。
  • 只有 2 次正式執行。不能說它每次都會給同樣的 8 條;同一份 diff 重跑,條目和措辭可能不同。

👥 適合誰、不適合誰?

適合:

  • 寫前端動畫、想在 merge 前多一道關卡的人。它的 Block 條件具體,可以直接當成 PR 檢查表。
  • 讓 AI 寫完動畫、想讓另一個 session 用固定標準審一次的流程。點名才觸發,正好放在「寫完、送審前」那一步。
  • 想學動畫細節的人。STANDARDS.md 的時間表、曲線和頻率表本身就是一份很好的參考,不跑 skill 也值得讀。
不適合:
  • 想審一般程式碼的人,它會拒絕。
  • 動畫風格本來就跟 Emil 不同的產品,例如刻意用彈性很大、時間較長的品牌動畫。它會一路擋,需要自己判斷哪些不照做。
  • 想要它直接幫你修好的人。它只給意見;要整批規劃修改,用 improve-animations;要查效能瓶頸,同 repo 有 animation-performance。

🔗 延伸資源

下一步建議:挑你專案裡最近一個加了動畫的 commit,用 /review-animations 請審查 HEAD 新增的動畫 跑一次,再把它判 Block 的理由逐條到瀏覽器裡開 DevTools 的 Animations 面板,把速度調到 25% 看一遍。它講對的地方,慢動作下會很明顯。
author
陳
陳彥彤

AI 工程師 · AI 顧問。Java 後端 8 年、AI 工程師 2 年。AI 內訓 · AI 導入顧問 · 前後端與雲端培訓。

support

覺得文章有用可以到 GitHub 給個 star,或是透過信箱聊聊 AI 內訓、AI 導入顧問或前後端 / 雲端培訓。

related

相關文章

[AI 工具] · 23min
improve-animations 實測:9 分鐘審完全站動畫,剛修的也被抓
improve-animations 是 Emil Kowalski 開源的 Claude Code skill,掃整個 repo 的動畫程式碼,只把修法寫成 plans/ 底下的自足計畫、不動原始碼。我拿剛修完動畫的部落格前端跑一次,約 9 分鐘、US$2.04 產出 8 條發現與 4 份計畫,挑 3 條到正式站量測全部成立,其中一條就是當天新加的 ease-in。
[AI 工具] · 21min
find-animation-opportunities 實測:抓到沒寫 CSS 的目錄箭頭
find-animation-opportunities 是 Emil Kowalski 收在 MIT 授權 emilkowalski/skills 裡的 Claude Code skill,用頻率、目的、速度、功能四題 Gate 篩出介面上該加與不該加動畫的地方,只出報告、不改程式碼。我拿部落格前端跑了兩次,點名那次抓到有 class 沒樣式的目錄箭頭,兩次對篩選動畫卻給出相反結論——箭頭與篩選動畫後來都修進正式站,附 diff 與 Playwright 實測。
[AI 工具] · 22min
emil-design-eng skill 實測:674 行規範,差異全在動態
emil-design-eng 是 Emil Kowalski 收在 MIT 授權 emilkowalski/skills 裡最長的一支 skill(674 行),把他對 easing、動畫時長、何時不該動畫與 UI 細節的判斷寫給 AI agent 看。我實測同一個下拉選單,點名後開啟 102ms 就接近不透明、關閉比開啟快,截圖卻幾乎一樣——而且不點名 3 次只觸發 1 次,載入一次約多 9.9k tokens。