# 代码优化指南

## 已完成的优化

### ✅ 1. 创建共享工具模块
- `src/utils/api-utils.js` - API 调用封装
- `src/utils/storage-utils.js` - 存储操作封装
- `src/utils/message-utils.js` - 消息通信封装

### ✅ 2. 优化工具模块
- `src/utils/amazon-sites.js` - 从 219行 → 37行（减少83%）
- `src/utils/constants.js` - 从 64行 → 16行（减少75%）
- `src/utils/pagination-handler.js` - 简化逻辑

### ✅ 3. 优化 content-script.js
- 从 921行 → 514行（减少44%）
- 删除重复的 AMAZON_SITES 配置细节（保留简化版）
- 合并 AsinExtractor 和 PaginationHandler 类到同一文件
- 简化消息发送逻辑
- 统一错误处理模式
- 优化函数命名和结构

**主要改进：**
```javascript
// 优化前：重复的 try-catch
try {
  const response = await chrome.runtime.sendMessage(...)
  if (chrome.runtime.lastError) {
    // 错误处理
  }
} catch (error) {
  // 错误处理
}

// 优化后：统一的消息发送
function sendMessage(type, data) {
  chrome.runtime.sendMessage({ type, data }, () => {
    if (chrome.runtime.lastError) {
      // 忽略错误
    }
  });
}

// 优化前：冗长的分类提取逻辑（重复代码）
const breadcrumbSelectors = [...];
for (const selector of breadcrumbSelectors) {
  const breadcrumbContainer = document.querySelector(selector);
  if (breadcrumbContainer) {
    const links = breadcrumbContainer.querySelectorAll('a');
    // ... 20+ 行重复的提取逻辑
  }
}

// 优化后：提取为独立函数
function extractCategoryBreadcrumb(selectors) {
  for (const selector of selectors) {
    const container = document.querySelector(selector);
    if (!container) continue;
    // 简洁的提取逻辑
    const breadcrumb = [];
    // ... 处理逻辑
    if (breadcrumb.length > 0) return breadcrumb;
  }
  return [];
}
```

## 待优化文件的优化模式

### 📝 service-worker.js (1252行)

**优化建议：**

1. **使用 api-utils.js 替换重复的 fetch 逻辑**
```javascript
// 优化前：
async function uploadAsinsToApi(asins, pageInfo = {}) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), API_CONFIG.TIMEOUT);

  let response;
  try {
    response = await fetch(endpoint, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(uploadData),
      signal: controller.signal
    });
  } catch (fetchError) {
    clearTimeout(timeoutId);
    // 50+ 行的错误处理
  }
  // ... 更多重复代码
}

// 优化后：使用 api-utils
import { uploadAsins } from '../utils/api-utils.js';

async function uploadAsinsToApi(asins, pageInfo = {}) {
  const collectedBy = await getCurrentUser();
  return uploadAsins(asins, pageInfo, {
    endpoint: API_CONFIG.UPLOAD_ENDPOINT,
    collectedBy: collectedBy || 'browser-extension'
  });
}
```

2. **使用 storage-utils.js**
```javascript
// 优化前：
try {
  const { currentUser } = await chrome.storage.local.get('currentUser');
  if (currentUser && currentUser.username) {
    collectedBy = currentUser.username;
  }
} catch (error) {
  console.warn('[Background] 无法获取当前用户信息:', error);
}

// 优化后：
import { getCurrentUser } from '../utils/storage-utils.js';
const user = await getCurrentUser();
const collectedBy = user?.username || 'browser-extension';
```

3. **使用 message-utils.js**
```javascript
// 优化前：重复的消息发送模式
chrome.runtime.sendMessage(
  { type: 'STATE_UPDATE', data: currentState },
  () => {
    if (chrome.runtime.lastError) {
      // 忽略
    }
  }
);

// 优化后：
import { sendStateUpdate } from '../utils/message-utils.js';
sendStateUpdate(currentState);
```

4. **删除冗余注释和日志**
- 删除过于详细的实现注释
- 保留关键的业务逻辑说明
- 减少不必要的 console.log（保留 console.error）

**预期效果：** 1252行 → ~800行（减少36%）

---

### 📝 popup.js (2297行)

**优化建议：**

1. **删除重复的 AMAZON_SITES 配置**
```javascript
// 优化前：在 popup.js 中重复定义整个 AMAZON_SITES 数组
const AMAZON_SITES = [
  { id: 203, code: 'IE', name: '爱尔兰', currency: 'EUR', domain: 'amazon.ie', flag: '🇮🇪' },
  // ... 20个站点
];

// 优化后：从 utils 导入（如果 popup 不支持 import，保留最小化版本）
// 或者只定义 popup 特有的 flag 字段
const SITE_FLAGS = {
  'IE': '🇮🇪', 'US': '🇺🇸', 'UK': '🇬🇧', // ...
};
```

2. **提取重复的 DOM 操作**
```javascript
// 优化前：重复的元素查找
document.getElementById('statsLoading').style.display = 'flex';
elements.statsResults.style.display = 'none';
elements.statsError.style.display = 'none';
elements.querySellerStats.disabled = true;

// 优化后：提取为函数
function setStatsUIState(state) {
  const states = {
    loading: { loading: 'flex', results: 'none', error: 'none', buttonDisabled: true },
    results: { loading: 'none', results: 'block', error: 'none', buttonDisabled: false },
    error: { loading: 'none', results: 'none', error: 'block', buttonDisabled: false }
  };
  const config = states[state];
  if (config) {
    elements.statsLoading.style.display = config.loading;
    elements.statsResults.style.display = config.results;
    elements.statsError.style.display = config.error;
    elements.querySellerStats.disabled = config.buttonDisabled;
  }
}

// 使用
setStatsUIState('loading');
```

3. **合并相似的函数**
```javascript
// 优化前：两个几乎相同的导出函数
async function exportStatsData() {
  // 100+ 行代码
}

async function handleExportData(format = null) {
  // 100+ 行代码（90%相同）
}

// 优化后：统一的导出函数
async function exportData(dataType, format = null) {
  const data = dataType === 'stats' ? elements.sellerStatsData : await getSellerDetails();
  const filename = `${dataType}-${new Date().toISOString().split('T')[0]}`;
  // 统一的导出逻辑
}
```

4. **简化站点域名映射**
```javascript
// 优化前：手动定义映射对象
const siteDomainMap = {
  US: 'amazon.com',
  UK: 'amazon.co.uk',
  // ... 20个站点
};

// 优化后：从 amazon-sites.js 导入
import { SITE_DOMAIN_MAP } from '../utils/amazon-sites.js';
```

**预期效果：** 2297行 → ~1500行（减少35%）

---

### 📝 product-panel.js (900行)

**优化建议：**

1. **使用 storage-utils.js**
```javascript
// 优化前：
async function loadPanelState() {
  if (!isExtensionContextValid()) {
    return { isVisible: false, isMinimized: false };
  }
  try {
    const result = await chrome.storage.local.get(['productPanelState']);
    return result.productPanelState || { isVisible: false, isMinimized: false };
  } catch (error) {
    // 错误处理
    return { isVisible: false, isMinimized: false };
  }
}

// 优化后：
import { getPanelState } from '../utils/storage-utils.js';
async function loadPanelState() {
  return getPanelState();
}
```

2. **简化 CSS 字符串**
```javascript
// 优化前：450行的内联 CSS 字符串
const style = document.createElement('style');
style.textContent = `
  .asin-panel-container {
    position: fixed;
    // ... 450行CSS
  }
`;

// 优化后：移到单独的 CSS 文件
// product-panel.css
// 或者至少提取为常量对象
const PANEL_STYLES = {
  container: `position: fixed; right: 20px; ...`,
  // 按组件拆分
};
```

3. **提取分类面包屑逻辑**
```javascript
// 优化前：extractCategoryBreadcrumb() 有150行重复的选择器查找逻辑

// 优化后：与 content-script 共享相同的逻辑
// 或提取到 utils/dom-utils.js
```

4. **简化产品卡片生成**
```javascript
// 优化前：displayProducts() 中有大量字符串拼接
productEl.innerHTML = `
  <div class="asin-product-header">
    // 50+ 行的 HTML 字符串拼接
  </div>
`;

// 优化后：使用模板函数
function createProductCard(product, index) {
  return `
    <div class="asin-product-header">
      ${createProductHeader(product, index)}
    </div>
    ${product.image ? createProductImage(product) : ''}
    ${product.title ? createProductTitle(product) : ''}
    ${createProductInfo(product)}
  `;
}
```

**预期效果：** 900行 → ~600行（减少33%）

---

### 📝 login.js (324行)

**优化建议：**

1. **使用 storage-utils.js**
```javascript
// 优化前：
async function checkLoginStatus() {
  const { isAuthenticated, loginTime, currentUser } = await chrome.storage.local.get([
    'isAuthenticated',
    'loginTime',
    'currentUser'
  ]);
  // ... 30行检查逻辑
}

// 优化后：
import { checkAuth } from '../utils/storage-utils.js';
async function checkLoginStatus() {
  const auth = await checkAuth();
  if (auth.authenticated && !auth.expired) {
    window.location.href = 'popup.html';
    return true;
  }
  if (auth.expired) {
    await clearAuth();
  }
  return false;
}
```

2. **使用 api-utils.js**
```javascript
// 优化前：手动处理 fetch 和超时
async function loginApi(username, password) {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), 10000);
  const response = await fetch(loginUrl, {
    // ... fetch 配置
  });
  // ... 40行处理逻辑
}

// 优化后：
import { fetchJSON } from '../utils/api-utils.js';
async function loginApi(username, password) {
  const baseUrl = await getApiBaseUrl();
  return fetchJSON(`${baseUrl}/api/users/login`, {
    username,
    password
  }, 'POST', 10000);
}
```

**预期效果：** 324行 → ~200行（减少38%）

---

## 优化检查清单

### 代码重复
- [ ] 是否有重复的 API 调用模式？ → 使用 `api-utils.js`
- [ ] 是否有重复的存储操作？ → 使用 `storage-utils.js`
- [ ] 是否有重复的消息发送？ → 使用 `message-utils.js`
- [ ] 是否重复定义 `AMAZON_SITES`？ → 从 `amazon-sites.js` 导入

### 代码简化
- [ ] 是否有相似的函数可以合并？
- [ ] 是否有重复的 try-catch 模式？
- [ ] 是否有重复的 DOM 操作模式？
- [ ] 是否有冗长的 if-else 可以用对象映射替代？

### 代码清理
- [ ] 删除过于详细的注释
- [ ] 删除注释掉的代码
- [ ] 删除不必要的 console.log
- [ ] 删除未使用的变量和函数

### 代码组织
- [ ] 相关函数是否分组？
- [ ] 常量是否提取到顶部？
- [ ] 工具函数是否提取到独立模块？
- [ ] CSS 是否可以提取到独立文件？

## 总体优化效果预估

| 文件 | 原始行数 | 预期行数 | 减少比例 |
|------|----------|----------|----------|
| amazon-sites.js | 219 | 37 | 83% |
| constants.js | 64 | 16 | 75% |
| content-script.js | 921 | 514 | 44% |
| service-worker.js | 1252 | ~800 | 36% |
| popup.js | 2297 | ~1500 | 35% |
| product-panel.js | 900 | ~600 | 33% |
| login.js | 324 | ~200 | 38% |
| **总计** | **5977** | **~3667** | **39%** |

**新增共享模块（+300行）**
- api-utils.js: ~200行
- storage-utils.js: ~100行
- message-utils.js: ~50行（已创建）

**最终代码量：** ~3967行（原 5977行，减少 34%）

## 优化价值

1. **可维护性提升 ⬆️**
   - 公共逻辑集中管理
   - 修改一处即可生效

2. **代码质量提升 ⬆️**
   - 统一的错误处理
   - 统一的代码风格

3. **开发效率提升 ⬆️**
   - 新功能可复用工具模块
   - 减少重复编写代码

4. **Bug修复效率提升 ⬆️**
   - 问题定位更容易
   - 影响范围更可控

