Git钩子脚本如何检查加载时间

wen 实用脚本 1

本文目录导读:

Git钩子脚本如何检查加载时间

  1. 方案一:使用Node.js脚本进行服务端渲染测试
  2. 方案二:使用Puppeteer进行实际加载测试
  3. 方案三:集成性能测试工具
  4. 方案四:简单的文件级别检查
  5. 最佳实践建议

在Git钩子中直接检查页面加载时间比较困难,因为Git钩子运行在服务端或本地,无法直接访问浏览器环境,您可以通过以下几种方案实现类似的功能:

使用Node.js脚本进行服务端渲染测试

pre-commit钩子示例

#!/bin/bash
# .git/hooks/pre-commit
# 获取即将提交的文件列表
FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(html|js|css)$')
if [ -n "$FILES" ]; then
    echo "🔍 检查提交文件性能..."
    # 使用Node.js进行初步性能检查
    node -e "
    const fs = require('fs');
    const files = process.argv[1].split('\n').filter(Boolean);
    files.forEach(file => {
        if (fs.existsSync(file)) {
            const content = fs.readFileSync(file, 'utf-8');
            // 检查常见性能问题
            const performanceIssues = [];
            // 检查大文件
            const size = Buffer.byteLength(content, 'utf-8');
            if (size > 50000) {
                performanceIssues.push('文件过大: ' + (size/1024).toFixed(2) + 'KB');
            }
            // 检查图片大小
            const imgMatches = content.match(/<img[^>]+>/gi) || [];
            imgMatches.forEach(img => {
                if (img.includes('base64')) {
                    const base64Match = img.match(/base64,([^\"']+)/);
                    if (base64Match && base64Match[1].length > 100000) {
                        performanceIssues.push('发现大Base64图片');
                    }
                }
            });
            // 检查JavaScript
            if (file.endsWith('.js')) {
                // 检查同步请求
                if (content.includes('XMLHttpRequest') && !content.includes('async')) {
                    performanceIssues.push('存在同步AJAX请求');
                }
                // 检查大循环
                const forMatches = content.match(/for\s*\([^)]+\)/g);
                if (forMatches && forMatches.length > 10) {
                    performanceIssues.push('存在过多循环');
                }
            }
            if (performanceIssues.length > 0) {
                console.log('⚠️  ' + file + ':');
                performanceIssues.forEach(issue => console.log('   - ' + issue));
            }
        }
    });
    " "$FILES"
fi

使用Puppeteer进行实际加载测试

安装依赖

npm install puppeteer --save-dev

post-merge钩子示例

// .git/hooks/post-merge
#!/usr/bin/env node
const puppeteer = require('puppeteer');
async function checkLoadTime(url) {
    const browser = await puppeteer.launch({ headless: true });
    const page = await browser.newPage();
    // 收集性能指标
    await page.goto(url, { waitUntil: 'networkidle0' });
    const performance = await page.evaluate(() => {
        const perfData = performance.getEntriesByType('navigation')[0];
        const resources = performance.getEntriesByType('resource');
        return {
            // 核心Web指标
            FCP: performance.getEntriesByName('first-contentful-paint')[0]?.startTime,
            LCP: new Promise((resolve) => {
                new PerformanceObserver((list) => {
                    const entries = list.getEntries();
                    resolve(entries[entries.length - 1].startTime);
                }).observe({ type: 'largest-contentful-paint', buffered: true });
            }),
            // 加载时间
            domContentLoaded: perfData.domContentLoadedEventEnd,
            loadComplete: perfData.loadEventEnd,
            // 资源分析
            totalResources: resources.length,
            totalSize: resources.reduce((acc, res) => acc + (res.transferSize || 0), 0),
            // 慢资源
            slowResources: resources
                .filter(res => res.duration > 5000)
                .map(res => ({
                    name: res.name,
                    duration: res.duration,
                    size: res.transferSize
                }))
        };
    });
    console.log('📊 加载性能报告:');
    console.log(`   FCP: ${performance.FCP?.toFixed(0)}ms`);
    console.log(`   总资源数: ${performance.totalResources}`);
    console.log(`   总大小: ${(performance.totalSize / 1024).toFixed(2)}KB`);
    if (performance.slowResources.length > 0) {
        console.log('⚠️  慢资源警告:');
        performance.slowResources.forEach(res => {
            console.log(`   - ${res.name}: ${res.duration.toFixed(0)}ms`);
        });
    }
    await browser.close();
}
// 监控本地开发服务器
checkLoadTime('http://localhost:3000').catch(console.error);

集成性能测试工具

使用Lighthouse脚本

// .git/hooks/pre-push
#!/usr/bin/env node
const { execSync } = require('child_process');
async function runLighthouseCheck() {
    try {
        console.log('🏃 运行Lighthouse性能测试...');
        // 确保本地服务器运行
        execSync('npx http-server ./dist -p 8080 -c-1 --silent &', { 
            shell: true, 
            timeout: 3000 
        });
        // 运行Lighthouse
        execSync('npx lighthouse http://localhost:8080 --chrome-flags="--headless" --output=json --output-path=./lighthouse-report.json', {
            timeout: 30000
        });
        // 读取报告
        const report = require('./lighthouse-report.json');
        const performanceScore = report.categories.performance.score * 100;
        console.log(`📊 性能评分: ${performanceScore}`);
        if (performanceScore < 80) {
            console.log('❌ 性能评分低于80分,请优化后重试');
            process.exit(1);
        }
        console.log('✅ 性能检查通过');
    } catch (error) {
        console.error('❌ 性能测试失败:', error.message);
        process.exit(1);
    }
}
runLighthouseCheck();

简单的文件级别检查

适合快速部署的轻量方案

#!/bin/bash
# .git/hooks/pre-commit
# 定义阈值
MAX_JS_SIZE=500000  # 500KB
MAX_CSS_SIZE=100000 # 100KB
MAX_HTML_SIZE=50000 # 50KB
# 检查即将提交的文件
echo "🔍 检查文件大小限制..."
git diff --cached --name-only | while read file; do
    if [ -f "$file" ]; then
        size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
        case "$file" in
            *.js)
                if [ $size -gt $MAX_JS_SIZE ]; then
                    echo "⚠️  $file 过大 ($((size/1024))KB)"
                fi
                ;;
            *.css)
                if [ $size -gt $MAX_CSS_SIZE ]; then
                    echo "⚠️  $file 过大 ($((size/1024))KB)"
                fi
                ;;
            *.html)
                if [ $size -gt $MAX_HTML_SIZE ]; then
                    echo "⚠️  $file 过大 ($((size/1024))KB)"
                fi
                ;;
        esac
    fi
done
# 检查图片文件
echo "🔍 检查图片优化..."
git diff --cached --name-only -- '*.png' '*.jpg' '*.jpeg' '*.gif' '*.webp' | while read file; do
    if [ -f "$file" ]; then
        size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
        if [ $size -gt 100000 ]; then  # 100KB
            echo "⚠️  图片文件过大: $file ($((size/1024))KB)"
        fi
    fi
done

最佳实践建议

  1. 选择合适的钩子类型

    • pre-commit:执行快速检查,适合文件大小限制
    • post-commit:执行耗时操作,如详细性能分析
    • pre-push:执行完整性能测试
  2. 配置CI/CD集成

    # .github/workflows/performance.yml
    name: Performance Check
    on: [pull_request]
    jobs:
    performance:
     runs-on: ubuntu-latest
     steps:
       - uses: actions/checkout@v2
       - name: Test load time
         run: |
           npm install
           npm run build
           npx lighthouse https://your-site.com --output=json
  3. 自定义阈值

    // 在项目根目录创建 .perfconfig.js
    module.exports = {
     thresholds: {
         fcp: 2000,    // First Contentful Paint < 2s
         lcp: 2500,    // Largest Contentful Paint < 2.5s
         tti: 3000,    // Time to Interactive < 3s
         fileSize: {
             js: 300000,     // 300KB
             css: 100000,    // 100KB
             images: 200000  // 200KB
         }
     }
    };

这些方案可以根据您的具体需求选择合适的实现,对于生产环境,建议结合多种方案进行全面检查。

抱歉,评论功能暂时关闭!