#!/usr/bin/env nu # HTML optimization utilities # Minify HTML content export def minify_html [html_content: string, config: record] { let minified = ($html_content # Remove HTML comments (but keep IE conditionals) | str replace -ar '' '' # Remove unnecessary whitespace between tags | str replace -ar '>\s+<' '><' # Remove extra whitespace in text content (preserve single spaces) | str replace -ar '\s+' ' ' # Remove whitespace around block elements | str replace -ar '\s*<(div|section|article|header|footer|main|nav)\s*' '<$1' | str replace -ar '\s*\s*' '' # Remove optional closing tags (basic list) | str replace -ar '\s*
  • ' '
  • ' | str replace -ar '

    \s*

    ' '

    ' # Remove unnecessary quotes around attributes (safe cases) | str replace -ar '=([a-zA-Z0-9-_]+)(\s|>)' '=$1$2' # Trim | str trim ) $minified } # Inline critical CSS into HTML export def inline_critical_css [html_content: string, critical_css: string] { # Find the head section and inject critical CSS let css_style = $"" let updated_html = ($html_content | str replace '' $"($css_style)\n" ) $updated_html } # Add async CSS loading export def add_async_css [html_content: string, css_file: string] { let async_css = $' ' let updated_html = ($html_content | str replace '' $"($async_css)\n" ) $updated_html } # Inline small SVGs export def inline_small_svgs [html_content: string, svg_dir: string, max_size: int] { # Find SVG references and inline if small enough let svg_refs = ($html_content | parse -r ']+src="([^"]+\.svg)"[^>]*>') mut updated_html = $html_content for svg_ref in $svg_refs { let svg_path = $svg_ref.capture0 let full_path = $"($svg_dir)/($svg_path)" if ($full_path | path exists) { let svg_content = (open $full_path) if ($svg_content | str length) <= $max_size { # Inline the SVG by replacing the img tag let img_pattern = $']+src="($svg_path)"[^>]*>' $updated_html = ($updated_html | str replace -r $img_pattern $svg_content) } } } $updated_html } # Optimize meta tags export def optimize_meta_tags [html_content: string] { # Add performance and SEO meta tags let performance_meta = ' ' let updated_html = ($html_content | str replace '' $' ($performance_meta)' ) $updated_html } # Add preconnect links for external resources export def add_preconnect_links [html_content: string] { let preconnect_links = ' ' let updated_html = ($html_content | str replace '' $' ($preconnect_links)' ) $updated_html } # Remove unnecessary attributes export def remove_unnecessary_attributes [html_content: string] { let cleaned = ($html_content # Remove type="text/css" (default for style tags) | str replace -ar '\s+type="text/css"' '' # Remove type="text/javascript" (default for script tags in HTML5) | str replace -ar '\s+type="text/javascript"' '' # Remove method="get" (default for forms) | str replace -ar '\s+method="get"' '' ) $cleaned } # Optimize images (basic attributes) export def optimize_img_attributes [html_content: string] { # Add loading="lazy" to images below the fold # Add loading="lazy" to images that don't already have it mut optimized = $html_content # Find img tags that don't have loading attribute let img_without_loading = ($html_content | parse -r ']*loading=)[^>]*>') for img_tag in $img_without_loading { let original_tag = $img_tag.capture0 let lazy_tag = ($original_tag | str replace '' } # Analyze HTML for optimization opportunities export def analyze_html [html_content: string] { let size = ($html_content | str length) let lines = ($html_content | lines | length) let tags = ($html_content | str replace -ar '<[^>]+>' '' | str length) let tag_count = (($size - $tags) / 10) # Rough estimate let external_resources = { css_files: ($html_content | str replace -ar ']+rel="stylesheet"[^>]*>' '' | str length), js_files: ($html_content | str replace -ar ']+src[^>]*>' '' | str length), images: ($html_content | str replace -ar ']+>' '' | str length) } { size_bytes: $size, lines: $lines, estimated_tags: $tag_count, external_css: (($size - $external_resources.css_files) > 0), external_js: (($size - $external_resources.js_files) > 0), images: (($size - $external_resources.images) > 0), minification_potential: (($size * 0.3) | math round) } } # Validate HTML structure (basic) export def validate_html_structure [html_content: string] { let has_doctype = (($html_content | str starts-with "") let has_body = ($html_content | str contains "") { valid_structure: ($has_doctype and $has_html_tag and $has_head and $has_body and $has_title), has_doctype: $has_doctype, has_html_tag: $has_html_tag, has_head: $has_head, has_body: $has_body, has_title: $has_title } } # Extract critical above-the-fold content export def extract_critical_html [html_content: string] { # Extract content likely to be above the fold let critical_selectors = [ ".header", ".main-title", ".title", ".ocean-tech-bg", ".top-logo", ".provisioning-logo" ] # This is a simplified approach - extract elements with critical classes let critical_elements = ($critical_selectors | each { |selector| let class_name = ($selector | str replace '.' '') $html_content | parse -r $'<[^>]*class="[^"]*($class_name)[^"]*"[^>]*>.*?]+>' } | flatten) # Return the original content for now (simplified) $html_content } # Generate HTML performance hints export def generate_performance_hints [html_content: string] { mut hints = [] # Check for common performance issues if ($html_content | str contains 'style=') { $hints = ($hints | append "Consider moving inline styles to CSS files") } if ($html_content | str contains '