manage-your-printer/utils/optimize_frontend.py
2025-06-04 10:03:22 +02:00

216 lines
6.6 KiB
Python

#!/usr/bin/env python3
"""
Frontend Optimization Script for MYP Platform
Optimizes JavaScript and CSS files for better performance
"""
import os
import gzip
import shutil
import hashlib
from pathlib import Path
def minify_file(content, file_type='js'):
"""Basic minification - removes comments and extra whitespace"""
if file_type == 'js':
# Remove single-line comments
lines = content.split('\n')
cleaned_lines = []
for line in lines:
# Skip lines that are only comments
stripped = line.strip()
if stripped.startswith('//'):
continue
# Remove inline comments
if '//' in line:
line = line.split('//')[0].rstrip()
cleaned_lines.append(line)
content = '\n'.join(cleaned_lines)
# Remove multi-line comments
import re
content = re.sub(r'/\*[\s\S]*?\*/', '', content)
# Remove extra whitespace
content = re.sub(r'\s+', ' ', content)
content = re.sub(r'\s*([{}();,:])\s*', r'\1', content)
elif file_type == 'css':
# Remove CSS comments
import re
content = re.sub(r'/\*[\s\S]*?\*/', '', content)
# Remove extra whitespace
content = re.sub(r'\s+', ' ', content)
content = re.sub(r'\s*([{}:;,])\s*', r'\1', content)
return content.strip()
def compress_file(file_path, force=False):
"""Compress file with gzip"""
gz_path = file_path + '.gz'
# Skip if already compressed and not forcing
if os.path.exists(gz_path) and not force:
return False
with open(file_path, 'rb') as f_in:
with gzip.open(gz_path, 'wb', compresslevel=9) as f_out:
shutil.copyfileobj(f_in, f_out)
return True
def optimize_js_files(js_dir):
"""Optimize JavaScript files"""
js_path = Path(js_dir)
optimized_count = 0
for js_file in js_path.glob('*.js'):
# Skip already minified files
if js_file.name.endswith('.min.js'):
continue
min_file = js_file.with_suffix('.min.js')
# Skip if minified version already exists
if min_file.exists():
continue
print(f"Optimizing {js_file.name}...")
# Read and minify
content = js_file.read_text(encoding='utf-8')
minified = minify_file(content, 'js')
# Write minified version
min_file.write_text(minified, encoding='utf-8')
# Compress both versions
compress_file(str(js_file))
compress_file(str(min_file))
optimized_count += 1
return optimized_count
def optimize_css_files(css_dir):
"""Optimize CSS files"""
css_path = Path(css_dir)
optimized_count = 0
for css_file in css_path.glob('*.css'):
# Skip already minified files
if css_file.name.endswith('.min.css'):
continue
min_file = css_file.with_suffix('.min.css')
# Skip if minified version already exists
if min_file.exists():
continue
print(f"Optimizing {css_file.name}...")
# Read and minify
content = css_file.read_text(encoding='utf-8')
minified = minify_file(content, 'css')
# Write minified version
min_file.write_text(minified, encoding='utf-8')
# Compress both versions
compress_file(str(css_file))
compress_file(str(min_file))
optimized_count += 1
return optimized_count
def create_bundle_js(js_dir):
"""Create bundled JavaScript file with core utilities"""
js_path = Path(js_dir)
# Core files to bundle in order
core_files = [
'core-utilities.js',
'dark-mode.js',
'user-dropdown.js'
]
bundle_content = []
for file_name in core_files:
file_path = js_path / file_name
if file_path.exists():
content = file_path.read_text(encoding='utf-8')
bundle_content.append(f"/* === {file_name} === */\n{content}\n")
if bundle_content:
bundle_path = js_path / 'core-bundle.min.js'
bundled = '\n'.join(bundle_content)
minified = minify_file(bundled, 'js')
bundle_path.write_text(minified, encoding='utf-8')
compress_file(str(bundle_path))
print(f"Created core bundle: {bundle_path.name}")
def main():
"""Main optimization function"""
base_dir = Path(__file__).parent.parent
static_dir = base_dir / 'static'
js_dir = static_dir / 'js'
css_dir = static_dir / 'css'
print("Starting frontend optimization...")
# Optimize JavaScript
js_count = optimize_js_files(js_dir)
print(f"Optimized {js_count} JavaScript files")
# Optimize CSS
css_count = optimize_css_files(css_dir)
print(f"Optimized {css_count} CSS files")
# Create JavaScript bundle
create_bundle_js(js_dir)
# Compress performance-optimized.css if not already done
perf_css = css_dir / 'performance-optimized.css'
if perf_css.exists():
compress_file(str(perf_css), force=True)
# Create minified version
min_perf_css = css_dir / 'performance-optimized.min.css'
if not min_perf_css.exists():
content = perf_css.read_text(encoding='utf-8')
minified = minify_file(content, 'css')
min_perf_css.write_text(minified, encoding='utf-8')
compress_file(str(min_perf_css))
# Compress core-utilities files
core_js = js_dir / 'core-utilities.js'
core_css = css_dir / 'core-utilities.css'
if core_js.exists():
compress_file(str(core_js), force=True)
# Create minified version
min_core_js = js_dir / 'core-utilities.min.js'
if not min_core_js.exists():
content = core_js.read_text(encoding='utf-8')
minified = minify_file(content, 'js')
min_core_js.write_text(minified, encoding='utf-8')
compress_file(str(min_core_js))
if core_css.exists():
compress_file(str(core_css), force=True)
# Create minified version
min_core_css = css_dir / 'core-utilities.min.css'
if not min_core_css.exists():
content = core_css.read_text(encoding='utf-8')
minified = minify_file(content, 'css')
min_core_css.write_text(minified, encoding='utf-8')
compress_file(str(min_core_css))
print("\nOptimization complete!")
print("Remember to update templates to use minified versions in production.")
if __name__ == "__main__":
main()