[GitHub Global] Translate Vibe Coding 零基础教程/30 经验技巧/08 Vibe Coding 性能优化技巧.md to zh-TW
This commit is contained in:
committed by
GitHub
parent
eabe5a8b85
commit
30bab375fe
@@ -0,0 +1,519 @@
|
||||
# Vibe Coding 效能優化技巧
|
||||
|
||||
> 讓你的應用跑得更快
|
||||
|
||||
|
||||
|
||||
你好,我是魚皮。
|
||||
|
||||
在 Vibe Coding 中,你可能遇到過這樣的情況:用 AI 做出來的應用,功能都正常,但就是有點慢。比如頁面加載要等好幾秒、點擊按鈕半天沒反應、滾動列表卡卡的。不僅用戶體驗不好,自己用著也不爽。
|
||||
|
||||
這就是效能問題,AI 生成代碼的常見問題之一。因為 AI 更關注 “能不能跑”,而選擇性忽略 “跑得快不快”。在 Vibe Coding 中,我們追求的是快速實現功能,但不代表要犧牲效能。還好,效能優化同樣可以借助 AI 來完成。
|
||||
|
||||
下面,我就來教你如何在 Vibe Coding 中識別效能瓶頸,以及如何讓 AI 幫你優化效能。即使你不懂技術原理,也能讓應用跑得更快。
|
||||
|
||||
|
||||
|
||||
## 一、識別效能問題
|
||||
|
||||
優化之前,先要知道問題在哪裡。
|
||||
|
||||
首先要知道,效能不是一個抽象的概念,而是用戶的真實感受。用戶關心的是:頁面打開快不快?點擊按鈕響應快不快?滾動流暢不流暢?
|
||||
|
||||
如今,用戶對效能的要求越來越高。如果你的頁面加載超過 3 秒,用戶可能就會離開。如果點擊按鈕後沒有立即反饋,用戶會以為頁面卡住了。
|
||||
|
||||
所以,優化效能的第一步是站在用戶的角度,感受應用的速度。
|
||||
|
||||
|
||||
|
||||
### 使用效能測試工具
|
||||
|
||||
除了主觀感受,還要用工具來客觀測量。不用擔心,這些工具都很簡單,不需要編程基礎。
|
||||
|
||||
1)瀏覽器開發者工具
|
||||
|
||||
按 F12 打開開發者工具,切換到 Performance 效能標籤,點擊錄製按鈕,然後操作你的應用,最後停止錄製。你會看到一個詳細的效能報告,包括每個操作花了多少時間,哪些函數最慢,有沒有卡頓等。
|
||||
|
||||

|
||||
|
||||
如果你看不懂這些數據,沒關係,可以截圖給 AI,讓它幫你分析:
|
||||
|
||||
```markdown
|
||||
這是我的效能報告截圖,請幫我找出效能瓶頸在哪裡。
|
||||
```
|
||||
|
||||
|
||||
|
||||
2)Lighthouse
|
||||
|
||||
Chrome 自帶的效能測試工具。在開發者工具的 Lighthouse 標籤,點擊 "分析網站加載情況",它會給你的頁面打分,並提供優化建議。
|
||||
|
||||

|
||||
|
||||
重點關注這幾個指標:
|
||||
|
||||
- LCP(Largest Contentful Paint):最大內容繪製時間,應該在 2.5 秒內
|
||||
- FID(First Input Delay):首次輸入延遲,應該在 100 毫秒內
|
||||
- CLS(Cumulative Layout Shift):累積佈局偏移,應該小於 0.1
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
3)其他在線工具
|
||||
|
||||
還可以用 PageSpeed Insights、GTmetrix 等在線工具測試你的網站,它們會從真實用戶的角度測試效能。
|
||||
|
||||
|
||||
|
||||
### 找到效能瓶頸
|
||||
|
||||
測試後,你會發現一些慢的地方。不要急著優化所有問題,先找到最嚴重的瓶頸。
|
||||
|
||||
一般來說,AI 生成的代碼效能瓶頸在這幾個地方:
|
||||
|
||||
- JavaScript 文件太大,加載慢
|
||||
- API 請求太慢,或者請求太多
|
||||
- 渲染邏輯複雜,導致頁面卡頓
|
||||
- 數據庫查詢慢,或者查詢太多
|
||||
- 引用的資源太大,沒有壓縮和優化
|
||||
|
||||
找到瓶頸後,優先優化影響最大的那個。你可以直接把測試結果和代碼一起發給 AI,讓它幫你定位問題:
|
||||
|
||||
```markdown
|
||||
我的應用加載很慢,這是效能測試結果【貼測試結果】,這是相關代碼【貼代碼】,請幫我找出問題並給出優化方案。
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## 二、常見效能瓶頸
|
||||
|
||||
基於我的經驗,這裡總結了一些 AI 生成代碼時容易出現的效能瓶頸。了解這些問題,能幫你更好地引導 AI 生成高效能的代碼。
|
||||
|
||||
|
||||
|
||||
### 不必要的重新渲染
|
||||
|
||||
在前端開發框架(比如 React)中,組件會因為各種原因重新渲染。如果渲染太頻繁,頁面就會卡。
|
||||
|
||||
AI 生成的代碼可能會忽略這個問題,因為它更關注功能實現。常見的原因是:父組件更新時,所有子組件都會重新渲染,即使它們的數據沒變。每次渲染都創建新的函數或對象,導致子組件認為數據變了。狀態更新太頻繁,比如在輸入框的每次輸入都觸發複雜計算。
|
||||
|
||||
如何讓 AI 幫你優化?
|
||||
|
||||
你可以這樣告訴 AI:
|
||||
|
||||
```markdown
|
||||
這個組件渲染太頻繁,頁面很卡。請幫我優化,使用 React.memo、useMemo 和 useCallback 來減少不必要的渲染。
|
||||
```
|
||||
|
||||
即使你不懂這些技術名詞,直接跟 AI 說 “這個頁面很卡”,AI 也會幫你做好優化。
|
||||
|
||||
|
||||
|
||||
### 大量數據的渲染
|
||||
|
||||
如果要渲染一個很長的列表,比如 1000 條數據,AI 可能會直接把所有數據一次性渲染出來,導致頁面很慢。
|
||||
|
||||
如何讓 AI 幫你優化?
|
||||
|
||||
告訴 AI 你的具體需求:
|
||||
|
||||
```markdown
|
||||
我有一個 1000 條數據的列表,全部渲染太慢了。請幫我實現虛擬滾動,只渲染可見的部分。
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
```markdown
|
||||
請幫我實現分頁功能,一次只顯示 20 條數據。
|
||||
```
|
||||
|
||||
AI 會給你完整的實現方案,包括相關的庫推薦(比如 react-window)和代碼示例。
|
||||
|
||||
|
||||
|
||||
### 圖片未優化
|
||||
|
||||
圖片一般是頁面最大的資源。AI 在生成代碼時,往往會直接使用原始圖片,不會主動優化。
|
||||
|
||||
你可以讓 AI 幫你實現圖片優化:
|
||||
|
||||
```markdown
|
||||
請幫我實現圖片懶加載功能,只有圖片進入視口時才加載
|
||||
```
|
||||
|
||||
或者:
|
||||
|
||||
```markdown
|
||||
請幫我把圖片改成 WebP 格式,並添加壓縮處理
|
||||
```
|
||||
|
||||
對於圖片壓縮,你可以使用在線工具(比如 [TinyPNG](https://tinypng.com/)),或者讓 AI 幫你寫個程序,來實現自動化的圖片處理流程。
|
||||
|
||||
|
||||
|
||||
### 同步的 API 請求
|
||||
|
||||
AI 生成完整的前後端代碼時,一般會按照最直觀的方式實現,也就是前端一個請求接一個請求調用後端。這樣一來,請求總時間就是所有請求時間的總和,會比較慢。
|
||||
|
||||
比如下面這段代碼:
|
||||
|
||||
```typescript
|
||||
// AI 最初可能生成的:串行請求(慢)
|
||||
const user = await fetchUser();
|
||||
const posts = await fetchPosts();
|
||||
const comments = await fetchComments();
|
||||
// 總時間 = t1 + t2 + t3
|
||||
```
|
||||
|
||||
如果你發現了這個問題,可以告訴 AI:
|
||||
|
||||
```markdown
|
||||
這幾個 API 請求是獨立的,請幫我改成並行請求,減少總等待時間。
|
||||
```
|
||||
|
||||
AI 會幫你改成這樣:
|
||||
|
||||
```typescript
|
||||
// 優化後:並行請求(快)
|
||||
const [user, posts, comments] = await Promise.all([
|
||||
fetchUser(),
|
||||
fetchPosts(),
|
||||
fetchComments()
|
||||
]);
|
||||
// 總時間 = max(t1, t2, t3)
|
||||
```
|
||||
|
||||
就是這樣一個小優化,說不定能讓頁面的加載速度提升 2 ~ 3 倍。
|
||||
|
||||
|
||||
|
||||
### 缺少緩存
|
||||
|
||||
緩存就像是把常用的東西放在手邊,下次用的時候不用再去遠處拿。比如你第一次查詢用戶信息需要 1 秒,如果把結果緩存起來,下次再查詢同一個用戶,0.01 秒就能拿到結果。
|
||||
|
||||

|
||||
|
||||
AI 生成的代碼一般不會主動添加緩存機制,導致每次都要重新獲取相同的數據,浪費時間。
|
||||
|
||||
你可以這樣告訴 AI:
|
||||
|
||||
```markdown
|
||||
這個數據每次都要重新獲取,太慢了。請幫我添加緩存,把數據緩存 5 分鐘。
|
||||
```
|
||||
|
||||
或者
|
||||
|
||||
```markdown
|
||||
請幫我實現一個簡單的內存緩存,避免重複請求相同的數據。
|
||||
```
|
||||
|
||||
AI 會根據你的場景選擇合適的緩存方案,比如瀏覽器緩存、內存緩存或者 CDN。
|
||||
|
||||
|
||||
|
||||
## 三、前端效能優化
|
||||
|
||||
前端效能直接影響用戶體驗,我們重點講一下。這部分內容對於有編程基礎的朋友會更有幫助,如果你是零基礎,可以把這些優化需求直接告訴 AI,讓它幫你實現。
|
||||
|
||||
|
||||
|
||||
|
||||
### 代碼分割
|
||||
|
||||
AI 生成的代碼可能會把所有功能打包成一個大文件,用戶打開頁面時要下載整個文件,很慢。
|
||||
|
||||
你可以告訴 AI:
|
||||
|
||||
```markdown
|
||||
我的 JavaScript 文件太大了,請幫我實現代碼分割,把管理面板的代碼獨立出來,只有用戶訪問時才加載。
|
||||
```
|
||||
|
||||
AI 會幫你改成這樣:
|
||||
|
||||
```typescript
|
||||
// AI 最初可能生成的:一次性導入
|
||||
import AdminPanel from './AdminPanel';
|
||||
|
||||
// 優化後:懶加載
|
||||
const AdminPanel = lazy(() => import('./AdminPanel'));
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<Suspense fallback={<Loading />}>
|
||||
<AdminPanel />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
這樣,只有用戶訪問管理面板時,才會加載相關代碼,首頁加載速度可能提升 50% 以上。
|
||||
|
||||
|
||||
|
||||
### 優化渲染效能
|
||||
|
||||
如果 AI 生成的代碼使用了 React 框架,那麼 “渲染” 可能會成為瓶頸。
|
||||
|
||||
優化方法包括:
|
||||
|
||||
1)使用 `React.memo` 避免不必要的渲染。比如一個展示用戶信息的組件,如果用戶信息沒變,就不需要重新渲染:
|
||||
|
||||
```typescript
|
||||
const UserCard = React.memo(({ user }) => {
|
||||
return (
|
||||
<div>
|
||||
<h2>{user.name}</h2>
|
||||
<p>{user.email}</p>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
2)使用 `useMemo` 緩存計算結果。如果有複雜的計算,不要每次渲染都重新計算:
|
||||
|
||||
```typescript
|
||||
function TodoList({ todos }) {
|
||||
// 不好:每次渲染都重新計算
|
||||
const completedCount = todos.filter(t => t.completed).length;
|
||||
|
||||
// 好:只在 todos 變化時重新計算
|
||||
const completedCount = useMemo(
|
||||
() => todos.filter(t => t.completed).length,
|
||||
[todos]
|
||||
);
|
||||
|
||||
return <div>已完成:{completedCount}</div>;
|
||||
}
|
||||
```
|
||||
|
||||
3)使用 `useCallback` 緩存函數。避免每次渲染都創建新函數:
|
||||
|
||||
```typescript
|
||||
function TodoList({ todos, onDelete }) {
|
||||
// 不好:每次渲染都創建新函數
|
||||
const handleDelete = (id) => {
|
||||
onDelete(id);
|
||||
};
|
||||
|
||||
// 好:緩存函數
|
||||
const handleDelete = useCallback((id) => {
|
||||
onDelete(id);
|
||||
}, [onDelete]);
|
||||
|
||||
return <div>{/* ... */}</div>;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 優化資源加載
|
||||
|
||||
減少首次加載的資源大小和數量。
|
||||
|
||||
1)壓縮資源:使用 Gzip 或 Brotli 壓縮 JavaScript、CSS 等文本文件。現代的構建工具(如 Vite、Next.js)一般會自動做這個。
|
||||
|
||||
2)Tree Shaking:移除未使用的代碼。確保你的構建工具開啟了 Tree Shaking,只打包實際用到的代碼。
|
||||
|
||||
3)預加載關鍵資源:對於首屏需要的資源,可以預加載:
|
||||
|
||||
```html
|
||||
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
|
||||
```
|
||||
|
||||
4)延遲加載非關鍵資源:對於不是立即需要的資源,可以延遲加載:
|
||||
|
||||
```html
|
||||
<script src="/analytics.js" defer></script>
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 優化 CSS
|
||||
|
||||
CSS 也會影響效能,這是比較容易被忽略的點。
|
||||
|
||||
1)避免複雜的選擇器:複雜的 CSS 選擇器會讓瀏覽器花更多時間匹配元素。盡量用簡單的類名。
|
||||
|
||||
2)減少重排和重繪:修改 DOM 會觸發重排(reflow)和重繪(repaint),很消耗效能。盡量批量修改 DOM,而不是一個一個改。
|
||||
|
||||
3)使用 CSS 動畫而不是 JavaScript:CSS 動畫由瀏覽器優化,比 JavaScript 動畫更流暢。
|
||||
|
||||
💡 如果你想要更進一步學習前端效能優化,可以看 [魚皮的前端效能優化實戰視頻教程](https://www.bilibili.com/video/BV1Wi33zmEAn/)。
|
||||
|
||||
|
||||
|
||||
## 四、後端效能優化
|
||||
|
||||
後端效能決定了 API 的響應速度。同樣,這些優化都可以通過 AI 來實現,你只需要描述清楚需求就好。
|
||||
|
||||
|
||||
|
||||
|
||||
### 數據庫查詢優化
|
||||
|
||||
數據庫查詢往往是後端最慢的部分。AI 生成的數據庫查詢代碼通常比較簡單直接,可能會有效能問題。
|
||||
|
||||
如何讓 AI 幫你優化呢?提供幾個思路:
|
||||
|
||||
1)讓 AI 添加索引
|
||||
|
||||
```markdown
|
||||
用戶表的 email 字段查詢很慢,請幫我添加索引。
|
||||
```
|
||||
|
||||
AI 會給你具體的 SQL 語句或 ORM 配置。
|
||||
|
||||
|
||||
|
||||
2)避免 N+1 查詢
|
||||
|
||||
這是 AI 生成代碼時最容易出現的效能陷阱。比如你要獲取 10 篇文章和它們的作者信息,AI 可能會生成這樣的代碼:
|
||||
|
||||
```typescript
|
||||
// AI 可能生成的:N+1 查詢(慢)
|
||||
const posts = await db.posts.findMany(); // 1 次查詢
|
||||
for (const post of posts) {
|
||||
post.author = await db.users.findOne({ id: post.authorId }); // N 次查詢
|
||||
}
|
||||
// 10 篇文章 = 11 次查詢
|
||||
```
|
||||
|
||||
你可以告訴 AI:這段代碼查詢太多次了,請優化成一次查詢。
|
||||
|
||||
AI 會幫你改成:
|
||||
|
||||
```typescript
|
||||
// 優化後:一次查詢(快)
|
||||
const posts = await db.posts.findMany({
|
||||
include: { author: true }
|
||||
});
|
||||
// 10 篇文章 = 1 次查詢
|
||||
```
|
||||
|
||||
這個優化能讓接口響應速度提升 10 倍以上。
|
||||
|
||||
|
||||
|
||||
3)只查詢需要的字段
|
||||
|
||||
告訴 AI:
|
||||
|
||||
```markdown
|
||||
請只查詢需要的字段,不要用 SELECT *,減少數據傳輸量。
|
||||
```
|
||||
|
||||
AI 會幫你優化查詢語句。
|
||||
|
||||
|
||||
|
||||
### 使用緩存
|
||||
|
||||
使用緩存能大大提高響應速度。
|
||||
|
||||
1)內存緩存:把常用的數據緩存在內存裡,比如用戶信息、配置數據等。可以用 Redis 內存存儲或者簡單的 Map。
|
||||
|
||||
2)HTTP 緩存:設置合適的 Cache-Control 響應頭(HTTP 頭是服務器告訴瀏覽器如何處理資源的指令),讓瀏覽器緩存靜態資源
|
||||
|
||||
```typescript
|
||||
// 靜態資源:緩存一年
|
||||
res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
|
||||
|
||||
// API 數據:緩存 5 分鐘
|
||||
res.setHeader('Cache-Control', 'public, max-age=300');
|
||||
```
|
||||
|
||||
3)CDN 緩存:CDN(內容分發網絡)就像在全國各地開了很多倉庫,用戶訪問時從最近的倉庫拿資源,比從總部拿要快得多。使用 CDN 來緩存和加速靜態資源的分發,能大幅提升全球用戶的訪問速度。
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
### 異步處理
|
||||
|
||||
不要讓用戶等待耗時的操作。
|
||||
|
||||
舉個例子,用戶上傳了一張圖片,需要生成縮略圖。不要讓用戶等待生成完成,而是:
|
||||
|
||||
1. 立即返回成功響應
|
||||
2. 在後台異步生成縮略圖
|
||||
3. 生成完成後更新數據庫
|
||||
|
||||
這樣用戶體驗會好很多。
|
||||
|
||||
|
||||
|
||||
|
||||
### API 設計優化
|
||||
|
||||
好的 API 設計也能提高效能。
|
||||
|
||||
1)批量操作:如果要刪除多個項目,不要發送多個請求,而是一次性發送:
|
||||
|
||||
```typescript
|
||||
// 不好:多次請求
|
||||
for (const id of ids) {
|
||||
await deleteItem(id);
|
||||
}
|
||||
|
||||
// 好:批量請求
|
||||
await deleteItems(ids);
|
||||
```
|
||||
|
||||
2)分頁和游標:大量數據不要一次性返回,而是使用分頁或游標分批返回。
|
||||
|
||||
分頁就像翻書,一頁一頁看;游標就像書籤,記住你看到哪裡了,下次從那裡繼續。你可以通過 [這篇文章](https://www.codefather.cn/post/1823563686797688834) 進一步了解游標機制。
|
||||
|
||||
3)GraphQL:GraphQL 是一種查詢語言,讓客戶端可以精確地指定需要哪些數據,而不是服務器返回一堆用不到的數據。就像點菜時可以自己選配菜,而不是只能點套餐。
|
||||
|
||||
|
||||
|
||||
|
||||
## 五、Vibe Coding 效能優化實戰
|
||||
|
||||
讓我用幾個真實的案例,展示如何在 Vibe Coding 中通過 AI 來優化效能。這些案例都是我在實際項目中遇到的問題。
|
||||
|
||||
|
||||
|
||||
### 案例一、慢速列表
|
||||
|
||||
問題:我用 AI 做了一個文章列表頁面,加載 100 篇文章時很慢,頁面卡頓。
|
||||
|
||||
我的做法:
|
||||
|
||||
1)先用 Performance 工具測試,發現渲染 100 個文章卡片組件花了 2 秒
|
||||
|
||||
2)截圖測試結果,連同代碼一起發給 AI:
|
||||
|
||||
```markdown
|
||||
這個列表頁面很卡,這是效能測試結果【截圖】,這是代碼【代碼】,請幫我優化。
|
||||
```
|
||||
|
||||
3)AI 給出了優化方案:使用虛擬滾動、React.memo、圖片懶加載
|
||||
|
||||
4)我讓 AI 直接實現這些優化:
|
||||
|
||||
```markdown
|
||||
請幫我實現虛擬滾動,使用 react-window 庫。
|
||||
```
|
||||
|
||||
5)測試優化效果,確認沒問題
|
||||
|
||||
最後,頁面加載時間從 3 秒降到 0.5 秒,滾動變得流暢,整個優化過程不到 10 分鐘。
|
||||
|
||||
|
||||
|
||||
### 案例二、慢速搜索
|
||||
|
||||
問題:我用 AI 實現了搜索功能,但搜索很慢,用戶每輸入一個字符,都要等半秒才能看到結果。
|
||||
|
||||
我的做法:
|
||||
|
||||
1)通過瀏覽器的開發者工具觀察發現,每次輸入都觸發了 API 請求
|
||||
|
||||
2)我告訴 AI:
|
||||
|
||||
```markdown
|
||||
搜索太慢了,每次輸入都發請求。請幫
|
||||
Reference in New Issue
Block a user