|
| 1 | +# Optimole JavaScript Modules |
| 2 | + |
| 3 | +This directory contains the modular JavaScript components for the Optimole image optimizer. |
| 4 | + |
| 5 | +## Module Structure |
| 6 | + |
| 7 | +### Core Modules |
| 8 | + |
| 9 | +#### `logger.js` |
| 10 | +- **Purpose**: Centralized logging functionality with debug mode support |
| 11 | +- **Exports**: `optmlLogger` object |
| 12 | +- **Key Features**: |
| 13 | + - Debug mode detection via URL params or localStorage |
| 14 | + - Structured logging with prefixes |
| 15 | + - Table logging support |
| 16 | + - Conditional logging based on debug state |
| 17 | + |
| 18 | +#### `storage.js` |
| 19 | +- **Purpose**: Session storage management for tracking processed pages |
| 20 | +- **Exports**: `optmlStorage` object |
| 21 | +- **Key Features**: |
| 22 | + - Generate unique storage keys for URL/device combinations |
| 23 | + - Check if page/device combinations have been processed |
| 24 | + - Mark combinations as processed with timestamps |
| 25 | + - Error handling for storage operations |
| 26 | + |
| 27 | +#### `device.js` |
| 28 | +- **Purpose**: Device type detection based on screen width |
| 29 | +- **Exports**: `optmlDevice` object |
| 30 | +- **Key Features**: |
| 31 | + - Mobile/desktop detection using 600px breakpoint |
| 32 | + - Device type constants (MOBILE: 1, DESKTOP: 2) |
| 33 | + - Helper methods for device type checking |
| 34 | + - PageSpeed Insights compatible detection logic |
| 35 | + |
| 36 | +#### `api.js` |
| 37 | +- **Purpose**: REST API communication with fallback mechanisms |
| 38 | +- **Exports**: `optmlApi` object |
| 39 | +- **Key Features**: |
| 40 | + - Primary sendBeacon API for reliable data transmission |
| 41 | + - Fetch API fallback for when sendBeacon fails |
| 42 | + - Automatic storage marking on successful sends |
| 43 | + - Error handling and logging |
| 44 | + |
| 45 | +#### `dom-utils.js` |
| 46 | +- **Purpose**: DOM manipulation and utility functions |
| 47 | +- **Exports**: `optmlDomUtils` object |
| 48 | +- **Key Features**: |
| 49 | + - Debounce utility for performance optimization |
| 50 | + - Unique CSS selector generation for elements |
| 51 | + - Background image detection and URL extraction |
| 52 | + - Page condition checking (viewport, visibility, load state) |
| 53 | + - Promise-based waiting utilities |
| 54 | + |
| 55 | +### Specialized Modules |
| 56 | + |
| 57 | +#### `background.js` |
| 58 | +- **Purpose**: Background image handling and lazy loading observation |
| 59 | +- **Exports**: `optmlBackground` object |
| 60 | +- **Key Features**: |
| 61 | + - Background image lazy loading detection |
| 62 | + - Mutation observer setup for class changes |
| 63 | + - URL extraction from background images |
| 64 | + - Selector processing and element observation |
| 65 | + |
| 66 | +#### `lcp.js` |
| 67 | +- **Purpose**: Largest Contentful Paint (LCP) element detection |
| 68 | +- **Exports**: `optmlLcp` object |
| 69 | +- **Key Features**: |
| 70 | + - Performance Observer integration |
| 71 | + - LCP element identification and processing |
| 72 | + - Support for both image and background image LCP elements |
| 73 | + - Timeout handling for LCP detection |
| 74 | + |
| 75 | +#### `image-detector.js` |
| 76 | +- **Purpose**: Image detection and dimension analysis |
| 77 | +- **Exports**: `optmlImageDetector` object |
| 78 | +- **Key Features**: |
| 79 | + - Missing dimension detection for images |
| 80 | + - Intersection Observer setup for above-fold detection |
| 81 | + - Optimole image observation (`data-opt-id` attributes) |
| 82 | + - Cleanup utilities for temporary attributes |
| 83 | + |
| 84 | +#### `srcset-detector.js` |
| 85 | +- **Purpose**: Srcset analysis and missing variation detection for eligible images |
| 86 | +- **Exports**: `optmlSrcsetDetector` object |
| 87 | +- **Key Features**: |
| 88 | + - Smart image detection with improved skip logic: |
| 89 | + - Includes images without `data-opt-src` (non-lazyload images) |
| 90 | + - Includes images with `data-opt-src` AND `data-opt-lazy-loaded` (completed lazyload) |
| 91 | + - Skips images with only `data-opt-src` (pending lazyload) |
| 92 | + - **Aspect ratio detection for cropping requirements**: |
| 93 | + - Compares natural vs. displayed aspect ratios to determine if cropping is needed |
| 94 | + - Uses intelligent thresholds: 5% tolerance, 15% significant difference, 10% ratio change |
| 95 | + - Prevents unnecessary cropping when aspect ratios match |
| 96 | + - Returns separate crop status data as `imageId: cropStatus` mapping |
| 97 | + - Calculates required srcset variations using comprehensive size ranges: |
| 98 | + - Mobile range: 200w-500w (50w steps) for dense mobile coverage |
| 99 | + - Tablet range: 500w-800w (100w steps) for tablet devices |
| 100 | + - Desktop range: 800w-1200w (200w steps) for desktop screens |
| 101 | + - High-res range: 1200w-1600w (200w steps) with strategic 2x DPR |
| 102 | + - Configurable generation settings: |
| 103 | + - `widthStepSize`: Step size for width variations (default: 100px) |
| 104 | + - `minSize`: Minimum image size to consider (default: 200px) |
| 105 | + - `maxVariations`: Maximum srcset variations per image (default: 8) |
| 106 | + - `sizeTolerance`: Tolerance for existing sizes (default: 50px) |
| 107 | + - Analyzes existing srcset attributes to identify missing sizes |
| 108 | + - **Ultra-compact API payload**: Sends only essential fields with short names (w, h, d, s, b) |
| 109 | + - **Separate crop status**: Returns crop requirements as `imageId: cropStatus` mapping instead of per-srcset flags |
| 110 | + - **Full logging**: Complete analysis data available in console logs for debugging |
| 111 | + - Smart selection from dense size grid for optimal responsive coverage |
| 112 | + |
| 113 | +#### `main.js` |
| 114 | +- **Purpose**: Main orchestrator coordinating all functionality |
| 115 | +- **Exports**: `optmlMain` object |
| 116 | +- **Key Features**: |
| 117 | + - Complete above-the-fold detection workflow |
| 118 | + - Module coordination and data aggregation |
| 119 | + - API data preparation and submission with separate crop status |
| 120 | + - Error handling and condition checking |
| 121 | + |
| 122 | +## Data Structure |
| 123 | + |
| 124 | +### API Payload Structure |
| 125 | +The main module sends data to the REST API with the following structure: |
| 126 | + |
| 127 | +```javascript |
| 128 | +{ |
| 129 | + d: deviceType, // Device type (1=mobile, 2=desktop) |
| 130 | + a: aboveTheFoldImages, // Array of above-fold image IDs |
| 131 | + b: backgroundSelectors, // Background image selectors |
| 132 | + u: url, // Page URL |
| 133 | + t: timestamp, // Request timestamp |
| 134 | + h: hmac, // Security hash |
| 135 | + l: lcpData, // LCP (Largest Contentful Paint) data |
| 136 | + m: missingDimensions, // Missing dimension data |
| 137 | + s: srcsetData, // Srcset variations data |
| 138 | + c: cropStatusData // Crop status mapping (imageId -> boolean) |
| 139 | +} |
| 140 | +``` |
| 141 | + |
| 142 | +### Srcset Data Structure |
| 143 | +Individual srcset entries contain: |
| 144 | +```javascript |
| 145 | +{ |
| 146 | + w: width, // Image width |
| 147 | + h: height, // Image height |
| 148 | + d: dpr, // Device pixel ratio |
| 149 | + s: descriptor, // Srcset descriptor (e.g., "300w") |
| 150 | + b: breakpoint // CSS breakpoint |
| 151 | +} |
| 152 | +``` |
| 153 | + |
| 154 | +### Crop Status Data Structure |
| 155 | +Crop requirements are stored separately: |
| 156 | +```javascript |
| 157 | +{ |
| 158 | + 882936320: true, // Image ID -> requires cropping |
| 159 | + 123456789: false // Image ID -> no cropping needed |
| 160 | +} |
| 161 | +``` |
| 162 | + |
0 commit comments