feat(docs): add NavGrid/NavCard components and restructure stage pages
- Add NavGrid.vue and NavCard.vue components for better navigation layout - Restructure stage-0 index pages across languages into intro.md with new navigation components - Remove old stage-0 index.md files and update stage-3 pages similarly - Add new dependencies 'claude' and 'codex' to package.json - Improve code formatting in multiple Vue components for better readability - Update documentation content and structure for better user experience
This commit is contained in:
@@ -7,11 +7,13 @@
|
||||
**性能就是用户体验。**
|
||||
|
||||
一个页面加载多慢,用户就会流失?研究数据表明:
|
||||
|
||||
- **3 秒法则**:页面加载超过 3 秒,53% 的用户会离开
|
||||
- **0.1 秒延迟**:亚马逊发现页面延迟 0.1 秒,销售额下降 1%
|
||||
- **移动端更敏感**:移动用户对性能的容忍度更低
|
||||
|
||||
性能优化不只是"让页面变快",而是:
|
||||
|
||||
- **提升转化率**:更快的加载 = 更多的订单/注册
|
||||
- **改善 SEO**:搜索引擎优先索引加载快的页面
|
||||
- **降低成本**:优化的资源 = 更少的带宽和服务器成本
|
||||
@@ -27,11 +29,13 @@ Google 定义了三个核心性能指标,所有网页都应该达标:
|
||||
### 0.2 性能预算 (Performance Budget)
|
||||
|
||||
**性能预算**是为项目设定的性能限制,比如:
|
||||
|
||||
- JavaScript 文件不超过 200KB
|
||||
- 首屏加载时间不超过 2 秒
|
||||
- 总资源大小不超过 1MB
|
||||
|
||||
**为什么需要预算?**
|
||||
|
||||
- 防止项目膨胀:随着功能增加,性能很容易恶化
|
||||
- 团队协作规范:新功能上线前必须通过性能检查
|
||||
- 持续优化动力:每次迭代都有改进目标
|
||||
@@ -47,17 +51,20 @@ Google 定义了三个核心性能指标,所有网页都应该达标:
|
||||
浏览器自带的开发者工具,功能强大:
|
||||
|
||||
**Performance 面板**:
|
||||
|
||||
- 录制页面运行过程
|
||||
- 查看 FPS(帧率)、CPU 使用率
|
||||
- 分析 JavaScript 执行时间
|
||||
- 找出长任务(Long Tasks,超过 50ms 的 JS 任务)
|
||||
|
||||
**Lighthouse 面板**:
|
||||
|
||||
- 一键生成性能报告
|
||||
- 包含性能、可访问性、最佳实践、SEO 等评分
|
||||
- 给出具体优化建议
|
||||
|
||||
**Network 面板**:
|
||||
|
||||
- 查看所有资源加载时间
|
||||
- 分析瀑布图(Waterfall)
|
||||
- 找出加载慢的资源
|
||||
@@ -65,6 +72,7 @@ Google 定义了三个核心性能指标,所有网页都应该达标:
|
||||
### 1.2 WebPageTest
|
||||
|
||||
在线性能测试工具([webpagetest.org](https://webpagetest.org)):
|
||||
|
||||
- 多地点测试(全球各地)
|
||||
- 真实浏览器测试(Chrome、Firefox、Safari)
|
||||
- 丰富的测试报告和视频
|
||||
@@ -73,6 +81,7 @@ Google 定义了三个核心性能指标,所有网页都应该达标:
|
||||
### 1.3 PageSpeed Insights
|
||||
|
||||
Google 官方工具([pagespeed.web.dev](https://pagespeed.web.dev)):
|
||||
|
||||
- 基于 Core Web Vitals 评分
|
||||
- 区分移动端和桌面端
|
||||
- 提供字段数据(真实用户数据)和实验室数据
|
||||
@@ -96,6 +105,7 @@ Brotli: 120 KB (压缩率 76%)
|
||||
```
|
||||
|
||||
**开启方法**(Nginx 配置):
|
||||
|
||||
```nginx
|
||||
gzip on;
|
||||
gzip_types text/css application/javascript;
|
||||
@@ -117,6 +127,7 @@ brotli_types text/plain text/css application/javascript;
|
||||
**解决方案**:按路由或功能分割代码,用户只下载当前页面需要的代码
|
||||
|
||||
**示例**(Vite + Vue Router):
|
||||
|
||||
```javascript
|
||||
// 懒加载路由组件
|
||||
const Home = () => import('./views/Home.vue')
|
||||
@@ -129,6 +140,7 @@ const routes = [
|
||||
```
|
||||
|
||||
**效果**:
|
||||
|
||||
- 首页只加载 100KB(而不是 500KB)
|
||||
- 用户访问 /about 时才加载额外代码
|
||||
- 整体首屏时间减少 60%
|
||||
@@ -138,6 +150,7 @@ const routes = [
|
||||
**Tree Shaking**:移除未使用的代码
|
||||
|
||||
**示例**:
|
||||
|
||||
```javascript
|
||||
// 整个 lodash 库:70 KB
|
||||
import _ from 'lodash'
|
||||
@@ -147,6 +160,7 @@ import debounce from 'lodash/debounce'
|
||||
```
|
||||
|
||||
**Tree Shaking 原理**:
|
||||
|
||||
- ES Module 的 `import/export` 是静态结构
|
||||
- 打包工具(Webpack、Vite)可以分析哪些代码被使用
|
||||
- 未使用的代码在打包时被删除
|
||||
@@ -157,19 +171,20 @@ import debounce from 'lodash/debounce'
|
||||
|
||||
```html
|
||||
<!-- 预加载关键 CSS -->
|
||||
<link rel="preload" href="critical.css" as="style">
|
||||
<link rel="preload" href="critical.css" as="style" />
|
||||
|
||||
<!-- 预加载字体 -->
|
||||
<link rel="preload" href="font.woff2" as="font" crossorigin>
|
||||
<link rel="preload" href="font.woff2" as="font" crossorigin />
|
||||
|
||||
<!-- DNS 预解析 -->
|
||||
<link rel="dns-prefetch" href="https://api.example.com">
|
||||
<link rel="dns-prefetch" href="https://api.example.com" />
|
||||
|
||||
<!-- 预连接 -->
|
||||
<link rel="preconnect" href="https://cdn.example.com">
|
||||
<link rel="preconnect" href="https://cdn.example.com" />
|
||||
```
|
||||
|
||||
**优先级**:
|
||||
|
||||
- `preload`:立即下载(但可能抢占关键资源)
|
||||
- `prefetch`:空闲时下载(适合下一页资源)
|
||||
- `preconnect`:提前建立 TCP 连接
|
||||
@@ -179,16 +194,19 @@ import debounce from 'lodash/debounce'
|
||||
**CDN(Content Delivery Network)**:内容分发网络
|
||||
|
||||
**工作原理**:
|
||||
|
||||
- 把静态资源部署到全球各地的服务器
|
||||
- 用户从最近的服务器下载资源
|
||||
- 减少网络传输延迟
|
||||
|
||||
**使用建议**:
|
||||
|
||||
- 图片、字体、CSS、JS 等静态资源放 CDN
|
||||
- 使用公共 CDN(如 unpkg、jsDelivr)加载第三方库
|
||||
- 大型网站使用自建 CDN 或商业 CDN(如 Cloudflare)
|
||||
|
||||
**效果**:
|
||||
|
||||
- 国内用户加载速度提升 50%-80%
|
||||
- 海外用户体验显著改善
|
||||
|
||||
@@ -216,6 +234,7 @@ import debounce from 'lodash/debounce'
|
||||
**减少 DOM 操作**:DOM 操作很慢,批量处理
|
||||
|
||||
**示例**(低效):
|
||||
|
||||
```javascript
|
||||
// 每次循环都触发重排
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
@@ -224,6 +243,7 @@ for (let i = 0; i < 1000; i++) {
|
||||
```
|
||||
|
||||
**优化**:
|
||||
|
||||
```javascript
|
||||
// 使用文档片段,只触发一次重排
|
||||
const fragment = document.createDocumentFragment()
|
||||
@@ -236,33 +256,41 @@ document.body.appendChild(fragment)
|
||||
```
|
||||
|
||||
**使用虚拟 DOM**:
|
||||
|
||||
- Vue、React 使用虚拟 DOM 减少真实 DOM 操作
|
||||
- 批量更新,减少重排次数
|
||||
|
||||
### 3.3 CSS 优化
|
||||
|
||||
**减少 CSS 大小**:
|
||||
|
||||
- 移除未使用的 CSS(使用 PurgeCSS)
|
||||
- 压缩 CSS(移除空格、注释)
|
||||
|
||||
**优化 CSS 选择器**:
|
||||
|
||||
```css
|
||||
/* 慢:从右向左匹配 */
|
||||
.container div ul li a { }
|
||||
.container div ul li a {
|
||||
}
|
||||
|
||||
/* 快:使用类选择器 */
|
||||
.link { }
|
||||
.link {
|
||||
}
|
||||
```
|
||||
|
||||
**关键 CSS 内联**:
|
||||
|
||||
- 把首屏需要的 CSS 内联到 HTML
|
||||
- 减少渲染阻塞
|
||||
|
||||
```html
|
||||
<style>
|
||||
/* 首屏关键 CSS */
|
||||
.header { }
|
||||
.hero { }
|
||||
.header {
|
||||
}
|
||||
.hero {
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
@@ -271,17 +299,20 @@ document.body.appendChild(fragment)
|
||||
<ReflowRepaintDemo />
|
||||
|
||||
**触发重排的操作**:
|
||||
|
||||
- 改变元素大小、位置
|
||||
- 添加/删除 DOM 元素
|
||||
- 改变字体大小
|
||||
- 改变窗口大小
|
||||
|
||||
**触发重绘的操作**:
|
||||
|
||||
- 改变颜色
|
||||
- 改变背景
|
||||
- 改变边框样式
|
||||
|
||||
**优化建议**:
|
||||
|
||||
- 批量修改样式(使用 class)
|
||||
- 使用 `transform` 和 `opacity`(触发合成)
|
||||
- 避免逐帧修改样式(使用 requestAnimationFrame)
|
||||
@@ -289,6 +320,7 @@ document.body.appendChild(fragment)
|
||||
### 3.5 合成层 (Compositing)
|
||||
|
||||
**使用 `will-change` 提示浏览器**:
|
||||
|
||||
```css
|
||||
.animated-element {
|
||||
will-change: transform, opacity;
|
||||
@@ -296,6 +328,7 @@ document.body.appendChild(fragment)
|
||||
```
|
||||
|
||||
**使用 GPU 加速**:
|
||||
|
||||
```css
|
||||
.gpu-accelerated {
|
||||
transform: translateZ(0);
|
||||
@@ -309,6 +342,7 @@ document.body.appendChild(fragment)
|
||||
### 3.6 虚拟列表 (Virtual List)
|
||||
|
||||
当需要展示成千上万条数据时(如长列表、聊天记录),如果直接渲染所有 DOM 节点,会导致:
|
||||
|
||||
- **DOM 节点过多**:占用大量内存
|
||||
- **渲染缓慢**:样式计算和布局耗时增加
|
||||
- **滚动卡顿**:浏览器无法维持 60fps
|
||||
@@ -318,6 +352,7 @@ document.body.appendChild(fragment)
|
||||
<VirtualScrollingDemo />
|
||||
|
||||
**核心原理**:
|
||||
|
||||
1. 计算可视区域能容纳多少个元素。
|
||||
2. 监听滚动事件,根据 `scrollTop` 计算当前应该渲染数据的 `startIndex` 和 `endIndex`。
|
||||
3. 使用 `padding-top` 或 `transform` 将渲染的内容定位到正确位置。
|
||||
@@ -331,16 +366,19 @@ JavaScript 是页面的"肌肉",优化它让页面更流畅。
|
||||
### 4.1 代码压缩 (Minification)
|
||||
|
||||
**移除不必要的字符**:
|
||||
|
||||
- 空格、换行、注释
|
||||
- 缩短变量名
|
||||
- 移除无用代码
|
||||
|
||||
**工具**:
|
||||
|
||||
- **Terser**:JavaScript 压缩工具
|
||||
- **ESBuild**:极快的打包工具
|
||||
- **Vite**:开发环境使用 ESBuild,生产环境使用 Rollup
|
||||
|
||||
**示例**:
|
||||
|
||||
```javascript
|
||||
// 原始代码
|
||||
function calculateTotal(price, quantity) {
|
||||
@@ -348,7 +386,9 @@ function calculateTotal(price, quantity) {
|
||||
}
|
||||
|
||||
// 压缩后
|
||||
function calculateTotal(a,b){return a*b}
|
||||
function calculateTotal(a, b) {
|
||||
return a * b
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 防抖与节流
|
||||
@@ -382,11 +422,13 @@ window.addEventListener('scroll', throttledScroll)
|
||||
**Web Workers**:在后台线程运行 JavaScript,不阻塞主线程
|
||||
|
||||
**使用场景**:
|
||||
|
||||
- 大数据计算
|
||||
- 图片/视频处理
|
||||
- 复杂算法
|
||||
|
||||
**示例**:
|
||||
|
||||
```javascript
|
||||
// 主线程
|
||||
const worker = new Worker('calculator.js')
|
||||
@@ -409,18 +451,20 @@ self.onmessage = (e) => {
|
||||
**问题**:长任务会阻塞主线程,导致页面卡顿
|
||||
|
||||
**解决方案**:
|
||||
|
||||
- **时间切片**:把大任务拆成小任务
|
||||
- **使用 requestIdleCallback**:在浏览器空闲时执行
|
||||
- **Web Workers**:移到后台线程
|
||||
|
||||
**示例**(时间切片):
|
||||
|
||||
```javascript
|
||||
async function processLargeArray(items) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
processItem(items[i])
|
||||
// 每 100 个项目暂停一次,让浏览器处理其他任务
|
||||
if (i % 100 === 0) {
|
||||
await new Promise(resolve => setTimeout(resolve, 0))
|
||||
await new Promise((resolve) => setTimeout(resolve, 0))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -438,21 +482,22 @@ async function processLargeArray(items) {
|
||||
|
||||
**格式对比**:
|
||||
|
||||
| 格式 | 大小 | 质量 | 浏览器支持 | 适用场景 |
|
||||
|------|------|------|-----------|----------|
|
||||
| JPEG | 小 | 好 | 所有 | 照片 |
|
||||
| PNG | 大 | 最好 | 所有 | 透明图片、图标 |
|
||||
| WebP | 很小 | 好 | 现代浏览器 | 大部分场景 |
|
||||
| AVIF | 最小 | 很好 | 最新浏览器 | 追求极致性能 |
|
||||
| 格式 | 大小 | 质量 | 浏览器支持 | 适用场景 |
|
||||
| ---- | ---- | ---- | ---------- | -------------- |
|
||||
| JPEG | 小 | 好 | 所有 | 照片 |
|
||||
| PNG | 大 | 最好 | 所有 | 透明图片、图标 |
|
||||
| WebP | 很小 | 好 | 现代浏览器 | 大部分场景 |
|
||||
| AVIF | 最小 | 很好 | 最新浏览器 | 追求极致性能 |
|
||||
|
||||
**建议**:
|
||||
|
||||
- 优先使用 WebP
|
||||
- 提供降级方案(JPEG/PNG)
|
||||
|
||||
```html
|
||||
<picture>
|
||||
<source srcset="image.webp" type="image/webp">
|
||||
<img src="image.jpg" alt="描述">
|
||||
<source srcset="image.webp" type="image/webp" />
|
||||
<img src="image.jpg" alt="描述" />
|
||||
</picture>
|
||||
```
|
||||
|
||||
@@ -463,17 +508,14 @@ async function processLargeArray(items) {
|
||||
```html
|
||||
<img
|
||||
src="image-800.jpg"
|
||||
srcset="
|
||||
image-400.jpg 400w,
|
||||
image-800.jpg 800w,
|
||||
image-1200.jpg 1200w
|
||||
"
|
||||
srcset="image-400.jpg 400w, image-800.jpg 800w, image-1200.jpg 1200w"
|
||||
sizes="(max-width: 600px) 400px, 800px"
|
||||
alt="响应式图片"
|
||||
>
|
||||
/>
|
||||
```
|
||||
|
||||
**解释**:
|
||||
|
||||
- `srcset`:定义不同尺寸的图片
|
||||
- `sizes`:告诉浏览器图片在不同屏幕上的显示尺寸
|
||||
- 浏览器自动选择最合适的图片
|
||||
@@ -485,14 +527,16 @@ async function processLargeArray(items) {
|
||||
**图片懒加载**:只有当图片进入视口时才加载
|
||||
|
||||
**方法 1:使用 `loading` 属性**:
|
||||
|
||||
```html
|
||||
<img src="image.jpg" loading="lazy" alt="懒加载图片">
|
||||
<img src="image.jpg" loading="lazy" alt="懒加载图片" />
|
||||
```
|
||||
|
||||
**方法 2:使用 Intersection Observer**:
|
||||
|
||||
```javascript
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
const img = entry.target
|
||||
img.src = img.dataset.src
|
||||
@@ -501,7 +545,7 @@ const observer = new IntersectionObserver((entries) => {
|
||||
})
|
||||
})
|
||||
|
||||
document.querySelectorAll('img[data-src]').forEach(img => {
|
||||
document.querySelectorAll('img[data-src]').forEach((img) => {
|
||||
observer.observe(img)
|
||||
})
|
||||
```
|
||||
@@ -509,14 +553,16 @@ document.querySelectorAll('img[data-src]').forEach(img => {
|
||||
### 5.4 压缩与裁剪
|
||||
|
||||
**使用工具压缩图片**:
|
||||
|
||||
- **ImageOptim**(Mac)
|
||||
- **TinyPNG**(在线)
|
||||
- **Squoosh**(Google 开源)
|
||||
|
||||
**使用 CDN 实时裁剪**:
|
||||
|
||||
```html
|
||||
<!-- 使用 CDN 裁剪为 800x600 -->
|
||||
<img src="https://cdn.example.com/image.jpg?w=800&h=600&q=80">
|
||||
<img src="https://cdn.example.com/image.jpg?w=800&h=600&q=80" />
|
||||
```
|
||||
|
||||
---
|
||||
@@ -528,6 +574,7 @@ document.querySelectorAll('img[data-src]').forEach(img => {
|
||||
### 6.1 Web Font 优化
|
||||
|
||||
**问题**:使用 Web Font 时,浏览器可能:
|
||||
|
||||
- **FOUT**(Flash of Unstyled Text):先显示系统字体,然后切换到 Web Font
|
||||
- **FOIT**(Flash of Invisible Text):文字隐藏,等 Web Font 加载完才显示
|
||||
|
||||
@@ -542,6 +589,7 @@ document.querySelectorAll('img[data-src]').forEach(img => {
|
||||
```
|
||||
|
||||
**`font-display` 值**:
|
||||
|
||||
- `auto`:浏览器默认
|
||||
- `swap`:立即显示文本,Web Font 加载后替换(推荐)
|
||||
- `fallback`:短时间隐藏,超时后显示系统字体
|
||||
@@ -550,20 +598,24 @@ document.querySelectorAll('img[data-src]').forEach(img => {
|
||||
### 6.3 字体子集化
|
||||
|
||||
**只包含用到的字符**:
|
||||
|
||||
- 中文字体很大(几 MB),但通常只用几百个字
|
||||
- 使用工具提取子集
|
||||
|
||||
**工具**:
|
||||
|
||||
- **Fontmin**(中文字体子集化)
|
||||
- **glyphhanger**(提取页面实际使用的字符)
|
||||
|
||||
**示例**:
|
||||
|
||||
```bash
|
||||
# 只提取常用的 500 个汉字
|
||||
fontmin input.ttf output/ --text='常用的五百个汉字...'
|
||||
```
|
||||
|
||||
**结果**:
|
||||
|
||||
- 原始字体:5 MB
|
||||
- 子集化后:200 KB
|
||||
- 减少 96%
|
||||
@@ -577,6 +629,7 @@ fontmin input.ttf output/ --text='常用的五百个汉字...'
|
||||
### 7.1 HTTP 缓存
|
||||
|
||||
**强缓存(Strong Cache)**:
|
||||
|
||||
```nginx
|
||||
# 静态资源缓存 1 年
|
||||
location ~* \.(jpg|png|css|js)$ {
|
||||
@@ -586,6 +639,7 @@ location ~* \.(jpg|png|css|js)$ {
|
||||
```
|
||||
|
||||
**协商缓存(Conditional Cache)**:
|
||||
|
||||
```nginx
|
||||
# 使用 ETag
|
||||
location / {
|
||||
@@ -594,6 +648,7 @@ location / {
|
||||
```
|
||||
|
||||
**最佳实践**:
|
||||
|
||||
- 带哈希的文件名(如 `app.abc123.js`):永久缓存
|
||||
- 不带哈希的文件:协商缓存
|
||||
|
||||
@@ -602,11 +657,13 @@ location / {
|
||||
**Service Worker**:在浏览器后台运行的脚本,可以拦截网络请求
|
||||
|
||||
**核心能力**:
|
||||
|
||||
- 离线访问
|
||||
- 资源缓存
|
||||
- 后台同步
|
||||
|
||||
**示例**(使用 Workbox):
|
||||
|
||||
```javascript
|
||||
// 注册 Service Worker
|
||||
if ('serviceWorker' in navigator) {
|
||||
@@ -621,9 +678,9 @@ workbox.routing.registerRoute(
|
||||
plugins: [
|
||||
new workbox.expiration.ExpirationPlugin({
|
||||
maxEntries: 60,
|
||||
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 天
|
||||
}),
|
||||
],
|
||||
maxAgeSeconds: 30 * 24 * 60 * 60 // 30 天
|
||||
})
|
||||
]
|
||||
})
|
||||
)
|
||||
```
|
||||
@@ -631,6 +688,7 @@ workbox.routing.registerRoute(
|
||||
### 7.3 LocalStorage / IndexedDB
|
||||
|
||||
**LocalStorage**:存储简单数据(5-10 MB)
|
||||
|
||||
```javascript
|
||||
// 缓存 API 数据
|
||||
localStorage.setItem('cache_key', JSON.stringify(data))
|
||||
@@ -638,6 +696,7 @@ const cached = JSON.parse(localStorage.getItem('cache_key'))
|
||||
```
|
||||
|
||||
**IndexedDB**:存储大量结构化数据
|
||||
|
||||
```javascript
|
||||
// 存储离线数据
|
||||
const db = await openDB('mydb', 1, {
|
||||
@@ -659,11 +718,13 @@ await db.put('posts', postData, 'post-1')
|
||||
**RUM**:收集真实用户的性能数据
|
||||
|
||||
**工具**:
|
||||
|
||||
- **Google Analytics**:免费,基础数据
|
||||
- **Cloudflare Web Analytics**:免费,注重隐私
|
||||
- **SpeedCurve**:付费,专业级
|
||||
|
||||
**关键指标**:
|
||||
|
||||
- 首屏时间(FCP、LCP)
|
||||
- 交互时间(TTI)
|
||||
- 转化率与性能的关系
|
||||
@@ -673,6 +734,7 @@ await db.put('posts', postData, 'post-1')
|
||||
**合成监控**:用模拟用户定期测试
|
||||
|
||||
**工具**:
|
||||
|
||||
- **Lighthouse CI**:每次提交代码自动测试
|
||||
- **WebPageTest**:定期测试关键页面
|
||||
- **Pingdom**:简单易用的监控服务
|
||||
@@ -690,8 +752,8 @@ export default defineConfig({
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
'vendor': ['vue', 'vue-router'],
|
||||
'ui': ['element-plus']
|
||||
vendor: ['vue', 'vue-router'],
|
||||
ui: ['element-plus']
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -700,6 +762,7 @@ export default defineConfig({
|
||||
```
|
||||
|
||||
**使用 Lighthouse CI 检查预算**:
|
||||
|
||||
```json
|
||||
// lighthouserc.json
|
||||
{
|
||||
@@ -724,12 +787,14 @@ export default defineConfig({
|
||||
**问题**:一个电商商品页加载需要 8 秒
|
||||
|
||||
**诊断**:
|
||||
|
||||
- 图片总和:3 MB
|
||||
- JavaScript:1.2 MB
|
||||
- CSS:400 KB
|
||||
- 45 个资源请求
|
||||
|
||||
**优化措施**:
|
||||
|
||||
1. 压缩图片 → 减少 60%(1.2 MB)
|
||||
2. 使用 WebP → 再减少 30%(800 KB)
|
||||
3. 图片懒加载 → 首屏只加载 3 张图
|
||||
@@ -737,6 +802,7 @@ export default defineConfig({
|
||||
5. 启用 Gzip → CSS 减少到 150 KB
|
||||
|
||||
**结果**:
|
||||
|
||||
- 首屏时间:8 秒 → 1.8 秒(减少 77%)
|
||||
- Lighthouse 性能评分:35 → 92
|
||||
|
||||
@@ -745,6 +811,7 @@ export default defineConfig({
|
||||
**问题**:单页应用(SPA)首次加载慢
|
||||
|
||||
**优化策略**:
|
||||
|
||||
1. **路由懒加载**:每个路由单独打包
|
||||
2. **组件懒加载**:非首屏组件延迟加载
|
||||
3. **虚拟列表**:长列表只渲染可见部分
|
||||
@@ -752,23 +819,27 @@ export default defineConfig({
|
||||
5. **SSR(服务端渲染)**:首屏由服务器渲染
|
||||
|
||||
**技术选型**:
|
||||
|
||||
- 使用 **Vite**(快速构建)
|
||||
- 使用 **Vue 3**(更好的性能)
|
||||
- 使用 **Pinia**(轻量状态管理)
|
||||
- 使用 **Vant**(按需引入的 UI 组件库)
|
||||
|
||||
**结果**:
|
||||
|
||||
- 首屏加载时间:4.5 秒 → 1.2 秒
|
||||
- Time to Interactive:6 秒 → 1.8 秒
|
||||
|
||||
### 9.3 案例 3:移动端性能优化
|
||||
|
||||
**移动端特殊挑战**:
|
||||
|
||||
- CPU 性能弱
|
||||
- 网络慢
|
||||
- 内存有限
|
||||
|
||||
**优化措施**:
|
||||
|
||||
1. **减少动画**:使用 CSS 动画代替 JS 动画
|
||||
2. **触摸优化**:避免 `click` 延迟,使用 `touchstart`
|
||||
3. **减少重排**:使用 `transform` 代替 `top/left`
|
||||
@@ -776,6 +847,7 @@ export default defineConfig({
|
||||
5. **PWA**:支持离线访问,提供类原生体验
|
||||
|
||||
**结果**:
|
||||
|
||||
- 移动端评分:45 → 95
|
||||
- 用户留存率提升:+30%
|
||||
|
||||
@@ -786,6 +858,7 @@ export default defineConfig({
|
||||
### 10.1 性能优化清单
|
||||
|
||||
**加载优化**:
|
||||
|
||||
- ✅ 启用 Gzip/Brotli 压缩
|
||||
- ✅ 使用 CDN 加速静态资源
|
||||
- ✅ 实施代码分割和懒加载
|
||||
@@ -793,23 +866,27 @@ export default defineConfig({
|
||||
- ✅ 使用 WebP/AVIF 格式
|
||||
|
||||
**渲染优化**:
|
||||
|
||||
- ✅ 减少重排和重绘
|
||||
- ✅ 使用 CSS 动画(transform、opacity)
|
||||
- ✅ 优化关键渲染路径
|
||||
- ✅ 内联关键 CSS
|
||||
|
||||
**JavaScript 优化**:
|
||||
|
||||
- ✅ 压缩和 Tree Shaking
|
||||
- ✅ 避免长任务(时间切片)
|
||||
- ✅ 使用 Web Workers
|
||||
- ✅ 防抖和节流
|
||||
|
||||
**缓存优化**:
|
||||
|
||||
- ✅ 配置 HTTP 缓存
|
||||
- ✅ 使用 Service Worker
|
||||
- ✅ 合理使用 LocalStorage
|
||||
|
||||
**监控优化**:
|
||||
|
||||
- ✅ 设置性能预算
|
||||
- ✅ 使用 RUM 和合成监控
|
||||
- ✅ 定期审计性能
|
||||
@@ -833,15 +910,18 @@ export default defineConfig({
|
||||
### 10.4 学习资源
|
||||
|
||||
**工具**:
|
||||
|
||||
- [Lighthouse](https://developers.google.com/web/tools/lighthouse)
|
||||
- [WebPageTest](https://www.webpagetest.org)
|
||||
- [PageSpeed Insights](https://pagespeed.web.dev)
|
||||
|
||||
**文档**:
|
||||
|
||||
- [Web.dev Performance](https://web.dev/performance/)
|
||||
- [MDN Performance](https://developer.mozilla.org/en-US/docs/Web/Performance)
|
||||
|
||||
**书籍**:
|
||||
|
||||
- 《高性能网站建设指南》
|
||||
- 《高性能网站建设进阶指南》
|
||||
- 《Web 性能权威指南》
|
||||
|
||||
Reference in New Issue
Block a user