本文目录导读:

Git 钩子脚本可以从多个维度检查代码性能问题,以下是针对不同场景的完整实现方案:
基础性能检查脚本结构
pre-commit 钩子示例(检查提交前代码)
#!/bin/bash
# .git/hooks/pre-commit
echo "🔍 开始性能检查..."
# 设置严格模式
set -e
# 定义性能违规函数
performance_violations=0
check_performance() {
local file="$1"
# 根据不同文件类型检查
case "$file" in
*.py)
check_python_performance "$file"
;;
*.js|*.ts)
check_javascript_performance "$file"
;;
*.java)
check_java_performance "$file"
;;
*.sql)
check_sql_performance "$file"
;;
esac
}
特定语言性能检查函数
Python 性能检查
check_python_performance() {
local file="$1"
# 检查循环中不必要的计算
if grep -n "for.*in range\|while.*:" "$file" | grep -q "len("; then
echo "⚠️ $file: 循环中可能重复计算 len(),建议缓存"
((performance_violations++))
fi
# 检查重复的数据库查询
if grep -n "\.query\|\.filter\|\.get(" "$file" | grep -q "for\|while"; then
echo "⚠️ $file: 循环中存在数据库查询,考虑批量操作"
((performance_violations++))
fi
# 检查大量字符串拼接
if grep -n "+=.*str\|+=.*'" "$file" | head -5 | grep -q "for\|while"; then
echo "⚠️ $file: 循环中使用字符串拼接,建议使用 join()"
((performance_violations++))
fi
# 检查未使用的导入
local unused_imports=$(grep "^import\|^from" "$file" | while read line; do
local module=$(echo "$line" | awk '{print $2}')
if ! grep -q "$module" <(grep -v "^import\|^from" "$file"); then
echo "$module"
fi
done)
if [ -n "$unused_imports" ]; then
echo "⚠️ $file: 可能未使用的导入: $unused_imports"
((performance_violations++))
fi
}
JavaScript/TypeScript 性能检查
check_javascript_performance() {
local file="$1"
# 检查不必要的 DOM 操作
if grep -n "\.innerHTML\s*=" "$file" | grep -q "for\|while\|forEach"; then
echo "⚠️ $file: 循环中频繁操作 innerHTML,建议使用 DocumentFragment"
((performance_violations++))
fi
# 检查闭包中的大对象
if grep -n "return function\|=> {" "$file" | head -10 | while read line; do
if echo "$line" | grep -q "large\|big\|heavy"; then
echo "⚠️ $file: 闭包中可能包含大对象,注意内存泄漏"
((performance_violations++))
fi
done
# 检查防抖/节流使用
if grep -n "\.addEventListener\|onclick\|onscroll\|onresize" "$file" | grep -v "debounce\|throttle"; then
echo "⚠️ $file: 高频事件未使用防抖/节流"
((performance_violations++))
fi
# 检查 import 大小(需要 webpack 配置)
if command -v node &> /dev/null; then
node -e "
const fs = require('fs');
const content = fs.readFileSync('$file', 'utf8');
const imports = content.match(/import\s+.*from\s+['\"]([^'\"]+)['\"]/g);
if (imports) {
imports.forEach(imp => {
if (imp.includes('lodash') || imp.includes('moment')) {
console.log('⚠️ 考虑使用 lodash 按需引入或 moment 替代方案');
}
});
}
"
fi
}
Java 性能检查
check_java_performance() {
local file="$1"
# 检查 StringBuilder 使用
if grep -n "String\s\+\w\+\s*=" "$file" | grep -q "for\|while"; then
echo "⚠️ $file: 循环中使用字符串拼接,建议使用 StringBuilder"
((performance_violations++))
fi
# 检查大对象序列化
if grep -n "implements Serializable\|@Serial" "$file" | grep -q "List\|Map\|Set"; then
echo "⚠️ $file: 大集合类实现 Serializable,注意性能影响"
((performance_violations++))
fi
# 检查线程安全
if grep -n "synchronized\|Lock\|Atomic" "$file" | grep -q "get\|set\|add\|remove"; then
# 这里的逻辑可能需要调整
true
fi
# 检查深拷贝
if grep -n "clone()\|new.*(.*old\|deepCopy\|deepClone" "$file"; then
echo "⚠️ $file: 使用深拷贝,注意性能开销"
((performance_violations++))
fi
}
SQL 性能检查
check_sql_performance() {
local file="$1"
# 检查 SELECT *
if grep -n "SELECT\s+\*" "$file"; then
echo "⚠️ $file: 使用 SELECT *,建议明确指定列"
((performance_violations++))
fi
# 检查缺少索引的 JOIN
if grep -n "JOIN\|LEFT JOIN\|RIGHT JOIN" "$file" | grep -v "INDEX\|index"; then
echo "⚠️ $file: JOIN 操作可能缺少索引"
((performance_violations++))
fi
# 检查 LIKE 前导通配符
if grep -n "LIKE\s+'%" "$file"; then
echo "⚠️ $file: LIKE 前导通配符将导致全表扫描"
((performance_violations++))
fi
# 检查 OR 条件(可能导致索引失效)
if grep -n "OR" "$file"; then
echo "⚠️ $file: 使用 OR 条件可能导致索引失效"
((performance_violations++))
fi
}
通用性能检查
大文件检查
check_file_size() {
local file="$1"
local max_size=500000 # 500KB
if [ -f "$file" ]; then
local size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
if [ "$size" -gt "$max_size" ]; then
echo "⚠️ 文件过大 ($(echo "scale=2; $size/1024/1024" | bc) MB): $file"
((performance_violations++))
fi
fi
}
依赖检查(package.json)
check_dependencies() {
if [ -f "package.json" ]; then
local heavy_packages=("lodash" "moment" "jquery" "bootstrap")
for package in "${heavy_packages[@]}"; do
if grep -q "\"$package\"" "package.json"; then
echo "⚠️ package.json 包含重依赖: $package"
((performance_violations++))
fi
done
fi
}
完整的 pre-commit 钩子
#!/bin/bash
# .git/hooks/pre-commit
echo "🔍 开始性能检查..."
performance_violations=0
# 获取暂存的文件
staged_files=$(git diff --cached --name-only --diff-filter=ACM)
if [ -z "$staged_files" ]; then
echo "✅ 没有需要检查的文件"
exit 0
fi
echo "检查以下文件:"
echo "$staged_files"
echo ""
# 逐个检查文件
for file in $staged_files; do
# 跳过非代码文件
[[ "$file" =~ \.(md|txt|json|yml|yaml)$ ]] && continue
echo "检查: $file"
# 文件大小检查
check_file_size "$file"
# 语言特定检查
check_performance "$file"
echo ""
done
# 依赖检查
check_dependencies
# 输出结果
if [ "$performance_violations" -gt 0 ]; then
echo "❌ 发现 $performance_violations 个潜在性能问题"
echo "请修复后重新提交,或使用 git commit --no-verify 跳过检查"
exit 1
else
echo "✅ 性能检查通过"
exit 0
fi
性能检查工具集成
集成 ESLint 性能规则
# .eslintrc.json 配置
{
"rules": {
"no-unused-vars": "error",
"no-console": "warn",
"no-await-in-loop": "warn",
"require-atomic-updates": "warn"
}
}
集成 Python Pylint 性能检查
# .pylintrc 配置
[MESSAGES CONTROL]
enable=performance
disable=C,R,W
# 在钩子中调用
if [ "$file" == *.py ]; then
pylint --load-plugins=pylint.extensions.bad_builtin "$file" 2>/dev/null || true
fi
性能检查报告生成
generate_performance_report() {
local report_file="performance_report_$(date +%Y%m%d_%H%M%S).md"
cat > "$report_file" << EOF
# 性能检查报告
生成时间: $(date)
提交者: $(git config user.name)
分支: $(git branch --show-current)
## 发现的问题
EOF
# 追加检查结果
for violation in "${violations[@]}"; do
echo "- $violation" >> "$report_file"
done
echo "报告已生成: $report_file"
}
使用建议
- 性能阈值设置:根据项目实际需求调整阈值
- 忽略列表:创建
.performanceignore文件跳过特定检查 - 增量检查:只检查新修改的代码,避免全量检查
- 并行执行:对于大型项目,考虑并行执行检查
- 持续优化:定期更新检查规则,适应项目演变
将这个脚本保存为 .git/hooks/pre-commit 并赋予执行权限:
chmod +x .git/hooks/pre-commit
这种方式的性能检查可以有效预防常见的性能问题,但建议配合专业的性能分析工具使用,以获得更全面的性能保障。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播