← back to Watches
performance-optimize.sh
223 lines
#!/bin/bash
###############################################################################
# OMEGA WATCHES - PERFORMANCE OPTIMIZATION SCRIPT
# Implements: WebP conversion, pre-compression, build optimization
###############################################################################
set -e
PROJECT_DIR="/root/Projects/watches"
DIST_DIR="$PROJECT_DIR/dist"
PUBLIC_DIR="$PROJECT_DIR/public"
echo "╔════════════════════════════════════════════════════════════════╗"
echo "║ OMEGA WATCHES - PERFORMANCE OPTIMIZATION ║"
echo "╚════════════════════════════════════════════════════════════════╝"
echo ""
# Step 1: Build optimized production bundle
echo "🔨 Step 1/6: Building optimized production bundle..."
cd "$PROJECT_DIR"
npm run build
echo ""
echo "📊 Bundle Analysis:"
du -sh "$DIST_DIR"
echo ""
find "$DIST_DIR" -type f -name "*.js" -exec du -h {} \; | sort -hr | head -10
# Step 2: Convert images to WebP (if any exist)
echo ""
echo "🖼️ Step 2/6: Converting images to WebP format..."
convert_to_webp() {
local dir=$1
if [ -d "$dir" ]; then
find "$dir" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) | while read img; do
webp_name="${img%.*}.webp"
if [ ! -f "$webp_name" ]; then
echo " Converting: $(basename $img) -> $(basename $webp_name)"
cwebp -q 85 "$img" -o "$webp_name" 2>/dev/null || echo " (skipped)"
fi
done
fi
}
convert_to_webp "$DIST_DIR/assets"
convert_to_webp "$PUBLIC_DIR/icons"
# Step 3: Pre-compress static assets with Brotli
echo ""
echo "🗜️ Step 3/6: Pre-compressing assets with Brotli..."
compress_files() {
local dir=$1
find "$dir" -type f \( -name "*.js" -o -name "*.css" -o -name "*.html" -o -name "*.json" -o -name "*.svg" \) | while read file; do
if [ ! -f "${file}.br" ]; then
echo " Brotli: $(basename $file)"
brotli -f -k -q 11 "$file"
fi
if [ ! -f "${file}.gz" ]; then
echo " Gzip: $(basename $file)"
gzip -f -k -9 "$file"
fi
done
}
compress_files "$DIST_DIR"
# Step 4: Generate performance manifest
echo ""
echo "📋 Step 4/6: Generating performance manifest..."
cat > "$DIST_DIR/performance-manifest.json" <<EOF
{
"optimized": true,
"timestamp": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")",
"optimizations": [
"Brotli compression (level 11)",
"Gzip compression (level 9)",
"WebP image conversion",
"Code splitting (4 chunks)",
"Tree shaking",
"Minification (Terser)",
"CSS minification",
"Asset versioning (cache-busting)",
"Pre-compressed static files"
],
"bundle_sizes": {
"total": "$(du -sh $DIST_DIR | cut -f1)",
"js": "$(find $DIST_DIR -name '*.js' -exec du -ch {} + | grep total | cut -f1)",
"css": "$(find $DIST_DIR -name '*.css' -exec du -ch {} + | grep total | cut -f1)",
"compressed": "$(find $DIST_DIR -name '*.br' -exec du -ch {} + | grep total | cut -f1)"
}
}
EOF
# Step 5: Create resource hints file
echo ""
echo "🔗 Step 5/6: Creating resource hints..."
cat > "$DIST_DIR/.htaccess" <<'EOF'
# Apache Performance Configuration
# Enable Brotli compression
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/xml text/css text/javascript application/javascript application/json
</IfModule>
# Enable Gzip compression
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/javascript application/json application/xml+rss
</IfModule>
# Serve pre-compressed files
<IfModule mod_rewrite.c>
RewriteEngine On
# Serve Brotli files if available
RewriteCond %{HTTP:Accept-Encoding} br
RewriteCond %{REQUEST_FILENAME}.br -f
RewriteRule ^(.*)$ $1.br [L]
# Serve Gzip files if available
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteCond %{REQUEST_FILENAME}.gz -f
RewriteRule ^(.*)$ $1.gz [L]
</IfModule>
# Cache control
<IfModule mod_expires.c>
ExpiresActive On
# HTML (no cache)
ExpiresByType text/html "access plus 0 seconds"
# CSS and JavaScript (1 year)
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
# Images (1 year)
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
# Fonts (1 year)
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType font/woff "access plus 1 year"
</IfModule>
# Security headers
<IfModule mod_headers.c>
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
# Set proper MIME types for compressed files
<FilesMatch "\.js\.br$">
Header set Content-Type "application/javascript"
Header set Content-Encoding "br"
</FilesMatch>
<FilesMatch "\.css\.br$">
Header set Content-Type "text/css"
Header set Content-Encoding "br"
</FilesMatch>
<FilesMatch "\.js\.gz$">
Header set Content-Type "application/javascript"
Header set Content-Encoding "gzip"
</FilesMatch>
<FilesMatch "\.css\.gz$">
Header set Content-Type "text/css"
Header set Content-Encoding "gzip"
</FilesMatch>
</IfModule>
EOF
# Step 6: Run Lighthouse audit
echo ""
echo "🔍 Step 6/6: Performance summary..."
BEFORE_SIZE=$(du -sb "$DIST_DIR" | cut -f1)
AFTER_SIZE=$(find "$DIST_DIR" -name "*.br" -exec du -b {} + | awk '{sum+=$1} END {print sum}')
COMPRESSION_RATIO=$(echo "scale=1; (1 - $AFTER_SIZE / $BEFORE_SIZE) * 100" | bc)
echo ""
echo "════════════════════════════════════════════════════════════════"
echo " OPTIMIZATION RESULTS "
echo "════════════════════════════════════════════════════════════════"
echo ""
echo "Bundle Size (uncompressed): $(numfmt --to=iec $BEFORE_SIZE)"
echo "Bundle Size (Brotli): $(numfmt --to=iec $AFTER_SIZE)"
echo "Compression Ratio: ${COMPRESSION_RATIO}%"
echo ""
echo "Files Optimized:"
echo " JavaScript files: $(find $DIST_DIR -name '*.js' | wc -l)"
echo " CSS files: $(find $DIST_DIR -name '*.css' | wc -l)"
echo " Brotli files: $(find $DIST_DIR -name '*.br' | wc -l)"
echo " Gzip files: $(find $DIST_DIR -name '*.gz' | wc -l)"
echo " WebP images: $(find $DIST_DIR -name '*.webp' 2>/dev/null | wc -l)"
echo ""
echo "Performance Features:"
echo " ✓ Code splitting (4 chunks)"
echo " ✓ Tree shaking enabled"
echo " ✓ Minification (Terser, 2 passes)"
echo " ✓ Brotli compression (level 11)"
echo " ✓ Gzip compression (level 9)"
echo " ✓ CSS minification"
echo " ✓ Asset versioning (cache-busting)"
echo " ✓ Pre-compressed files"
echo " ✓ WebP image support"
echo ""
echo "Next Steps:"
echo " 1. Restart server: pm2 restart omega-watches"
echo " 2. Test performance: ./lighthouse-test.sh"
echo " 3. Monitor: curl http://45.61.58.125:7600/api/metrics"
echo ""
echo "════════════════════════════════════════════════════════════════"