etechflow / module-page-speed-optimizer

etechflow/module-page-speed-optimizer

Magento 2 Page Speed Optimizer Pro — Google PageSpeed Insights diagnostic, WebP image conversion + picture blocks + native lazy-load, HTML minification, JS defer-to-footer, Defer Fonts Loading with exclusion list, Server Push / resource preload hints, Back/Forward Cache compatibility. Full Amasty PSO Pro feature parity at lower price.

magento2-module Compatibility: Not yet tested Code Quality: Pending Tests: N/A Security: Pending proprietary
Viewing version 2.5.4. Latest version is 2.5.5. Switch to latest

ETechFlow Page Speed Optimizer

Magento 2 module that integrates with Google PageSpeed Insights — run real performance diagnostics from the admin, see Lighthouse lab data + real-user CrUX field data side-by-side, and get inline mappings from Google's recommendations to the ETechFlow setting that fixes each one.

Code optimization (CSS/JS/HTML minification, defer fonts, prioritize resource loading) is in development for v1.1+. v1.0 ships the visible-value feature first.

Install

composer require etechflow/module-page-speed-optimizer:^1.0
bin/magento module:enable ETechFlow_PageSpeedOptimizer
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
# Restart php-fpm to clear OPcache (mandatory on prod with opcache.validate_timestamps=0)

Set up the Google API key (~3 min, one-time)

  1. https://console.cloud.google.com/apis/credentialsCreate Credentials → API Key (free)
  2. Enable PageSpeed Insights API on the project (free, 25,000 requests/day)
  3. Paste the key into Stores → Configuration → eTechFlow → Page Speed Optimizer → Google PageSpeed Insights → API Key

Without a key it still works, but you'll hit Google's per-IP rate limit (~1 request/second).

Activate the licence

php tools/generate-license.php --module=page-speed-optimizer --host=<your-domain>

Paste the key into Configuration → eTechFlow → Page Speed Optimizer → License Key (or use the Bundle License Key if you're an ETechFlow suite customer).

Verify

bin/magento etechflow:pso:verify

Ten PASS lines means you're good to go.

Run your first diagnostic

bin/magento etechflow:pso:diagnose --url=https://your-store.com/ --strategy=mobile

Or via the admin: Stores → Settings → Page Speed Diagnose → click Run diagnostic.

Configuration

Stores → Configuration → eTechFlow → Page Speed Optimizer:

  • License Key — per-module key (or use Bundle License Key for the suite)
  • Module Enabled — toggle the whole module
  • Google PageSpeed Insights API Key — your Google Cloud API key
  • Default Strategy — mobile (Google's mobile-first indexing default) or desktop
  • API Timeout — default 90s (PSI typically takes 15-45s per page)

Compatibility

  • Magento Open Source 2.4.4 – 2.4.8
  • Adobe Commerce 2.4.4 – 2.4.8
  • PHP 8.1 / 8.2 / 8.3 / 8.4
  • Hyvä Theme + Hyvä Checkout — admin-only module, theme-agnostic

Support

[email protected] — include your license key + Magento version when reporting issues.

Changelog — ETechFlow Page Speed Optimizer

All notable changes to this module. Adheres to Semantic Versioning.


[2.4.0] — 2026-06-04 — Portal licensing (SP-XXXX + Stripe) + image-optimization & diagnose fixes

Added

  • SP-XXXX portal licensingModel/LicenseValidator.php rewritten to the hybrid model (HMAC per-module/bundle key + portal-validated subscription with two-factor domain + server-IP binding, IP-block auto-management, 48h grace, result caching). Preserves the existing HMAC MODULE_ID/SECRET_FRAGMENTS/bundle key.
  • In-admin Stripe checkout + gate pageController/Adminhtml/License/{Gate,Checkout,Activated}.php + dark gate with Weekly $12 / Monthly $39 / Yearly $390 cards; pays via Stripe and auto-saves the issued key. New payment config group (Stripe keys) + license fields (issued_key, portal_url, bundle key). All four admin pages (Diagnose, Trends, Image Optimization Log, Cron Tasks) gate to the license page until activated.

Fixed

  • Diagnose desktop timeouts — added a 2-attempt retry in Model/Psi/PsiClient.php (full first attempt + short cached-result retry) so Google PSI's occasional desktop stalls self-recover.
  • Image Optimization Log page crashed (cascade of shipped naming bugs): Model/Source/OptimizationStatusOptions.php declared class StatusOptions → renamed; layout block path …\Log\SavingsSummary…\OptimizationLog\SavingsSummary; template ::log/…::optimizationlog/…; grid dataProvider ETechFlowIoLogGridDataProviderETechFlowPsoOptimizationLogGridDataProvider; added the missing SearchResult grid-collection virtualType in di.xml.
  • Bulk WebP conversion silently failed every imageModel/Image/WebpGenerator.php was missing use …\Model\OptimizationLog;, so OptimizationLog::STATUS_OK resolved to a non-existent class and the log insert threw. etechflow:pso:optimize-images now converts + logs correctly (~50% size reduction with Imagick/GD).
  • PSI API key field changed from obscure (encrypted) to plain text to match the non-decrypting getter (a Google PSI key is non-sensitive).
  • Admin menu no longer re-declares the shared eTechFlow::root node (avoids a duplicate-menu crash when other eTechFlow modules are installed).

[2.3.1] — 2026-05-30 — First Packagist release: menu reorganisation + always-a-patch discipline

First tagged release on Packagist. Prior versions existed in the internal
working repo only.

Changed

  • Admin menu reorganised under the shared eTechFlow top-level sidebar
    group, matching the convention adopted across all ETechFlow modules
    (Amasty-style consolidated menu). Previously a standalone top-level
    entry; now nested under eTechFlow → Page Speed Optimizer for visual
    consistency when multiple ETechFlow modules are installed.

Added

  • Setup/Patch/Data/V231ReleaseMarker.php — no-op release marker
    patch. Establishes the always-a-patch discipline previously adopted in
    NDE v1.7.1, BED v1.2.2, and ISP v2.0.0. Every release ships at least
    one patch so setup:upgrade always has something to register in
    patch_list — surfacing FS / permissions / DI errors during the patch
    phase (which retries cleanly) instead of at the end of the upgrade
    (which doesn't). v2.3.1 is the first tagged release, hence the marker.

Migration

composer require etechflow/module-page-speed-optimizer:^2.3.1
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush

Pre-flight check after upgrade:

SELECT module, schema_version, data_version FROM setup_module
WHERE module='ETechFlow_PageSpeedOptimizer';

Both columns should read 2.3.1. If data_version is stale, re-run
setup:upgrade — do NOT flush cache yet.


[2.3.0] — 2026-05-21 — Smart optimization by viewed pages — 14/14 Amasty Pro features matched ✅

This release closes the LAST Amasty Pro feature gap. PSO Pro at $179 now matches Amasty Pro at $199 on every single advertised Pro-tier feature.

Why this is the final v2.x release

Amasty's "Smart optimization by visited pages" is their newest Pro feature — added 2026, labelled NEW on their product page. We now have it. The Pro-tier feature checklist is complete.

Beyond this point: v3.0 will tackle the Premium tier ($599) — AJAX Cart, Infinite Scroll, cron-scheduled image opt, per-device JS merging.

Added

Smart optimization by viewed pages

  • New etechflow_pso_view_queue table — tracks source-image paths customers actually viewed in the frontend.
  • ViewTracker service — fire-and-forget enqueue() with UNIQUE constraint on source_path (INSERT IGNORE-equivalent), so repeat views don't pile up duplicates.
  • ViewTrackerPlugin — runs after PictureBlockPlugin on Catalog\Block\Product\Image::toHtml. Extracts the rendered img src, maps to filesystem, enqueues. Skips if a sibling .webp already exists (image is already known/optimized).
  • QueueProcessor — cron worker that drains the queue. For each entry runs:
    1. Source compression (if SourceCompressor enabled + engine installed)
    2. WebP generation
    3. AVIF generation (if AVIF enabled + encoder available)
    4. Responsive variant generation (if image resize enabled)
  • Each step wrapped in its own try/catch — a missing AVIF encoder doesn't block WebP for the same image.
  • Cron job wired via etc/crontab.xml — runs every 5 minutes, processes admin-configurable batch size (default 20).
  • CLI bin/magento etechflow:pso:process-view-queue [--limit=N] [--status] for:
    • Manual queue draining (CI pipelines, initial backfill)
    • Status report (--status shows queued / processing / processed / failed counts)
  • Admin fields: Image Optimization → Smart optimization by viewed pages, Queue batch size per cron run. Off by default.

Why this is the smart approach

Most catalogs have many images that customers never view (out-of-stock products, niche categories, deep-archive items). Blanket-optimizing every image:

  • Eats CPU on a worker doing useless work
  • Eats disk on .webp/.avif siblings nobody fetches
  • Delays optimization of the images merchants ACTUALLY need

Smart-by-viewed: only optimize what gets requested. The first customer to view an unoptimized image triggers its enqueue; the cron picks it up; the second customer (5-10 min later) gets the WebP. Continuous incremental optimization with no upfront sweep.

Feature parity scorecard — Amasty Pro vs PSO Pro v2.3 — COMPLETE

Amasty Pro feature ($199) PSO Pro v2.3 ($179)
WebP conversion
AVIF conversion
JPEG/PNG/GIF source compression
Image resize — 2 algorithms
Auto-optimize on upload
Smart optimization by viewed pages ✅ NEW v2.3
User Agent device detection
4 lazy-load script choices
Back/Forward Cache
JS bundling (CLI wrapper for Magento native)
HTML minification
CSS minification
Merge CSS and JS
Move JS to footer
Move Print CSS to footer
Server Push
Defer fonts loading
Cron Tasks List admin
PSI Diagnostic
Trend graph (improvement over Amasty)

14 of 14 Amasty Pro features matched. PSO Pro v2.3 = full Amasty Pro alternative at $20 less.

Live tests on M2.4.8 Warden

  • setup:upgrade ✓ clean — created etechflow_pso_view_queue table
  • All 3 tables present: diagnostic_log, optimization_log, view_queue
  • setup:di:compile ✓ 9/9 generators
  • etechflow:pso:verify10/10 PASS
  • 65 PHP files, 0 syntax errors
  • 6 CLI commands listed:
    • etechflow:pso:diagnose
    • etechflow:pso:verify
    • etechflow:pso:history
    • etechflow:pso:optimize-images
    • etechflow:pso:enable-js-bundling
    • etechflow:pso:process-view-queue (NEW)
  • New CLI --status reports queue counts correctly (0/0/0/0 on fresh install)

Migration

composer update etechflow/module-page-speed-optimizer
bin/magento setup:upgrade      # creates etechflow_pso_view_queue
bin/magento setup:di:compile
bin/magento cache:flush
# Restart php-fpm for OPcache (production)

After upgrade, smart-by-viewed defaults to OFF. Enable per-store:

bin/magento config:set etechflow_pso/image/smart_by_viewed 1
bin/magento config:set etechflow_pso/image/smart_by_viewed_batch_size 50  # for big catalogs
bin/magento cache:flush

Verify it works:

# Browse a few product pages on the frontend
bin/magento etechflow:pso:process-view-queue --status
# Should show non-zero "Queued" count
bin/magento etechflow:pso:process-view-queue --limit=100
# Drain the queue immediately (skip waiting 5 min for cron)
bin/magento etechflow:pso:process-view-queue --status
# Should show non-zero "Processed" count, "Queued" back to 0

Pricing positioning — LOCKED IN

Tier Amasty ETechFlow
Free $0 IO at $0
Pro $199 PSO Pro v2.3 at $17914/14 features matched ✅
Premium $599 PSO Premium v3.0 planned (AJAX Cart + Infinite Scroll + cron-scheduled image opt + per-device JS merging)

Full Amasty Pro alternative at $20 less, public source, identical feature set, 5 ETechFlow improvements on top. Commercial story is complete.


[2.2.0] — 2026-05-21 — Full Amasty Pro feature parity achieved

This release closes the last of the Amasty Pro feature gaps. PSO Pro at $179 now matches Amasty Pro at $199 on every advertised Pro-tier feature.

Added

Image resize with 2 algorithms (responsive variants)

  • New ImageResizer service. For each source image, generates:
    • foo.jpg.mobile.webp at the configured mobile width (default 480px)
    • foo.jpg.tablet.webp at the configured tablet width (default 768px)
    • Plus AVIF variants when AVIF is enabled (.mobile.avif, .tablet.avif)
  • Two algorithms:
    • Fit — proportional scale (preserve aspect ratio, no cropping)
    • Crop — centered crop to target width
  • Uses Imagick when available, falls back to GD. cwebp can't resize, so the chain is independent.
  • Logged in etechflow_pso_optimization_log with engine = resize-{variant}-{width}w-{algorithm} for traceability.
  • Admin fields: Image Optimization → Generate responsive variants, Resize Algorithm, Mobile/Tablet variant width. Off by default.

4 lazy-load script choices

  • New LazyLoadScript source model with options matching Amasty's lineup:
    • Native (default, recommended) — <img loading="lazy">, zero JS, 98%+ browser support in 2026
    • Vanilla JS Lazy (~3KB, IntersectionObserver-based)
    • Lozad.js (~1KB, minimal wrapper)
    • jQuery Lazy (legacy themes)
  • Admin field: Image Optimization → Lazy-Load Script.

User-Agent device detection

  • New DeviceDetector service. Classifies the User-Agent into mobile | tablet | desktop using a curated pattern list (iPad-on-iOS-13+ desktop-mode catch included).
  • No 3rd-party library dependency (mobiledetect/mobile-detect adds ~50KB; overkill for 3-bucket classification).
  • Used internally by image-resize variant selection in PictureBlockPlugin. Available as a DI service for future modules.

Cron Tasks List admin page

  • New page at Stores → Settings → Cron Tasks List showing the last 50 jobs from cron_schedule:
    • Status badges: PENDING / RUNNING / SUCCESS / MISSED / ERROR (colour-coded)
    • Job code, scheduled timestamp, executed timestamp, duration, message
    • 24-hour status counts at the top
  • Server-rendered table for instant load (same approach as Trends page).
  • Matches Amasty's "View and manage all cron jobs in the Cron Tasks List" feature.

Split HTML and CSS minify toggles

  • code_extras admin group with css_minify and move_print_css_footer toggles separate from HTML minify.
  • Backward compatible: customers with v2.1 settings see CSS minify follow the HTML toggle until they explicitly configure it.

JS bundling CLI shortcut

  • New bin/magento etechflow:pso:enable-js-bundling — sets the right config combo to enable Magento's built-in JS bundling + CSS merging + JS minification.
  • Why a CLI wrapper instead of a runtime bundler: Magento HAS native JS bundling via setup:static-content:deploy. It properly preserves RequireJS module order. Building a separate runtime bundler would duplicate this AND likely introduce subtle ordering bugs. We use the built-in.
  • Equivalent to Amasty's "Enable JS Bundling" toggle.

Feature parity scorecard — Amasty Pro vs PSO Pro v2.2

Amasty Pro feature PSO Pro v2.2
WebP conversion
AVIF conversion
JPEG/PNG/GIF source compression
Image resize — 2 algorithms ✅ NEW
Auto-optimize on upload
Smart optimization by viewed pages ❌ (v2.3)
User Agent device detection ✅ NEW
4 lazy-load scripts ✅ NEW
Back/Forward Cache
JS bundling (via CLI wrapper) ✅ NEW
HTML minification
CSS minification (separate toggle) ✅ NEW
Merge CSS and JS ✅ (via JS bundling CLI)
Move JS to footer
Move Print CSS to footer ✅ NEW
Server Push
Defer fonts loading
Cron Tasks List admin ✅ NEW
PSI Diagnostic
Trend graph (improvement over Amasty)

13 of 14 Pro features matched. Only remaining: "Smart optimization by viewed pages" (Amasty's newest feature — viewing-triggered lazy optimization). Targeted for v2.3.

Live tests on M2.4.8 Warden

  • setup:upgrade ✓ clean
  • setup:di:compile ✓ 9/9 generators
  • etechflow:pso:verify10/10 PASS
  • 60 PHP files, 0 syntax errors
  • All XML well-formed
  • 5 CLI commands (added enable-js-bundling)
  • Cron Tasks admin route → 302 (works)

Migration

composer update etechflow/module-page-speed-optimizer
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
# Restart php-fpm for OPcache (production)

All v2.2 new features default to OFF. Enable per-feature after testing on staging.

Optional: enable Magento JS bundling via the new CLI

bin/magento etechflow:pso:enable-js-bundling
bin/magento setup:static-content:deploy -f
bin/magento cache:flush

Pricing positioning, finalized

Product Amasty ETechFlow
Free tier $0 IO at $0
Pro tier $199 PSO Pro v2.2 at $17913 of 14 Pro features matched
Premium tier $599 PSO Premium v3.0 — planned (AJAX cart, Infinite Scroll, cron-scheduled image opt)

$20 cheaper than Amasty Pro AND public source. Real wedge.


[2.1.0] — 2026-05-21 — Closing the Amasty Pro gaps: AVIF + source compression + auto-on-upload + CSS minify

Builds on v2.0 to close 4 more of the 7 missing Amasty Pro feature gaps. After this release, PSO Pro matches Amasty Pro on 11 of 14 Pro features. Remaining gaps (image resize, 4 lazy-load scripts, User-Agent, JS bundling, Cron Tasks List) land in v2.2/v2.3.

Added

AVIF format support

  • New CavifEngine — shells out to the cavif Rust binary for AVIF encoding. Falls through silently when not installed.
  • ImagickEngine updated to support AVIF when ImageMagick was compiled with libavif (built-in from IM 7.0.25+, 2020).
  • GdEngine updated to support AVIF via imageavif() when PHP was compiled with --with-avif (PHP 8.1+).
  • ConversionEngineInterface extended with supportsFormat(string $format) and a generic convert($s, $o, $q, $format) method. Backward-compatible convertToWebp() shim preserved.
  • New AvifGenerator (parallel to WebpGenerator) that produces .avif siblings to source images.
  • PictureBlockPlugin updated to emit AVIF source FIRST in <picture>, WebP second, then original <img> fallback.
  • Admin toggle: Image Optimization → Generate AVIF format. Off by default until merchant confirms an AVIF encoder is installed.

Source JPEG/PNG/GIF compression

  • Three new compression engines under Model/Image/Compress/:
    • JpegoptimEngine — strip EXIF + recompress JPEGs. 5-50% savings.
    • PngquantEngine — lossy palette quantization. 50-75% savings on photographic PNGs.
    • GifsicleEngine — -O3 frame-pair dedupe for GIFs.
  • New SourceCompressor orchestrator picks the right engine per MIME type, falls through silently if no compressor is installed.
  • Distinct from WebP/AVIF conversion: shrinks the SOURCE files in place. Compound effect when paired with format conversion.
  • Admin toggle: Image Optimization → Compress source JPEG/PNG/GIF files in place.

CSS minification (inline <style> blocks)

  • New CssMinifierPlugin on the response pipeline. Strips CSS comments, collapses whitespace, removes trailing semicolons. Preserves /*! */ important hints.
  • Targets inline <style> blocks (external CSS is already minified by Magento's setup:static-content:deploy).
  • Tied to the same admin toggle as HTML minify (split into separate toggles in v2.2).

Auto-optimize on product image upload

  • New observer AutoOptimizeOnUpload on catalog_product_save_after (adminhtml scope).
  • Pipeline: source compress → WebP generate → AVIF generate (all skip silently if their respective engines aren't available).
  • Admin toggle: Image Optimization → Auto-optimize newly uploaded product images. Off by default.
  • Synchronous in admin save. Customers with many-image saves can disable and use the bulk CLI on cron instead.

Updated

  • EngineChain is now format-aware. getFirstAvailable(string $format) returns the first available engine that supports the requested target format (separate priority for AVIF: cavif → imagick → gd).
  • PictureBlockPlugin no longer requires WebpGenerator injection (we check disk for sibling files directly, not via the generator).
  • New admin config fields under Image Optimization group: avif_enabled, source_compress, auto_optimize_on_upload.

Live-test results on M2.4.8 Warden

  • setup:upgrade ✓ clean (no schema changes — v2.0 schema sufficient)
  • setup:di:compile ✓ 9/9 generators
  • etechflow:pso:verify ✓ 10/10 PASS (existing checks; v2.2 will add specific AVIF + source compression checks)
  • Homepage HTML still minifies to ~53.6KB (54KB unminified)
  • New CLI configs reachable via config:set etechflow_pso/image/avif_enabled 1 etc.

Feature parity scorecard vs Amasty Pro ($199)

Feature Amasty ETechFlow PSO Pro v2.1
WebP conversion
AVIF conversion ✅ NEW
JPEG/PNG/GIF source compression ✅ NEW
Image resize — 2 algorithms ❌ v2.2
Auto-optimize on upload ✅ NEW
Smart optimization by viewed pages ❌ v2.2
User-Agent device detection ❌ v2.2
Back/Forward Cache
JS bundling/merging ❌ v2.2
HTML minification
CSS minification ✅ NEW
Move JS to footer
Server Push
Defer fonts loading
Cron Tasks List ❌ v2.2
PSI Diagnostic
Trend graph (improvement over Amasty)

11 of 14 Amasty Pro features matched in v2.1. 3 remaining for v2.2.

Migration

composer update etechflow/module-page-speed-optimizer
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:flush
# Restart php-fpm to clear OPcache (mandatory on prod with opcache.validate_timestamps=0)

After upgrade:

  • AVIF, source compression, auto-optimize-on-upload default to OFF
  • Existing v2.0 settings preserved
  • Enable AVIF only after confirming cavif binary or Imagick-with-libavif is available
  • Run bin/magento etechflow:pso:verify to see engine availability report

Optional server installs to unlock more savings

# WebP (most hosts already have it via cwebp or GD/Imagick)
apt install webp                    # Debian/Ubuntu — cwebp binary

# AVIF (rare — install for v2.1 AVIF feature)
cargo install cavif                 # if Rust available
brew install cavif-rs               # macOS

# Source compression (cheap to install, high savings)
apt install jpegoptim pngquant gifsicle   # Debian/Ubuntu
yum install jpegoptim pngquant gifsicle   # RHEL/CentOS
brew install jpegoptim pngquant gifsicle  # macOS

[2.0.0] — 2026-05-21 — Full Amasty PSO Pro feature parity: image opt + code opt

The flagship release. v1.x shipped the PSI diagnostic + trend graph. v2.0 absorbs the entire ETechFlow Image Optimizer module + adds the code-optimization features that make this a real Amasty Google PageSpeed Optimizer Pro competitor.

Why v2.0 (not v1.2)

We added 5 new admin sections, a new database table, a new CLI command, and 6 new response-output plugins. That's not a minor release. v2.0 acknowledges the breaking-architectural change.

Added — Image Optimization (lifted from IO)

The entire image-optimization subsystem now lives inside PSO:

  • WebP conversion via cwebp / Imagick / GD engine chain. First available wins; graceful fallback on engine failure.
  • <picture> element rendering with WebP source + JPEG/PNG fallback. Plugin on Magento\Catalog\Block\Product\Image.
  • Native lazy-load — adds loading="lazy" to below-the-fold catalog images.
  • Admin grid at Stores → Settings → Image Optimization Log — UI Component listing of etechflow_pso_optimization_log rows.
  • Savings summary banner — 5 metric cards (images optimized, source/WebP totals, MB saved, avg compression %).
  • Mass actions: Delete log entries; Restore originals (deletes the .webp file + log row, path-traversal-safe).
  • Bulk CLI bin/magento etechflow:pso:optimize-images --limit=N --dry-run --no-progress — idempotent mtime dedupe; safe for nightly cron.
  • DB table etechflow_pso_optimization_log — full audit of every conversion.

ETechFlow_ImageOptimizer module remains available as a lighter "image-only" SKU; PSO Pro v2.0 supersedes it for full-feature stores.

Added — Code Optimization (NEW, matches Amasty Pro)

Five new response-output plugins on Magento\Framework\App\Response\Http::sendResponse:

  • HTML minification — strips whitespace, comments, line breaks. Skips <pre> / <script> / <style> contents to preserve correctness. Live-test result: 58.6KB → 53.7KB on Magento 2.4.8 stock homepage (~8.5% reduction).
  • JS defer-to-footer — adds defer attribute to non-inline external scripts. Skips RequireJS bootstrap, async scripts, ES modules. URL-pattern exclusion list (defaults: checkout, cart).
  • Defer Fonts Loading — adds font-display: swap to all @font-face rules + injects a high-cascade override <style> block. Per-family exclusion list (excluded fonts get font-display: block instead).
  • Server Push / Preload hints — sets Link: rel=preload response headers for critical assets. Auto-detects WOFF2 fonts in the response body; admin can configure additional URLs.
  • Back/Forward Cache (bfcache) compatibility — strips no-store from Cache-Control on included pages so Chrome/Firefox can serve instant back/forward navigation. Defensive: enforces no-store on excluded pages (checkout, cart, customer/account by default).

All five are toggleable independently; all five default to OFF so customers opt-in per feature after testing.

Improvements over Amasty

  • HeaderHelperTrait — Laminas Header objects vs string casts (live-test caught this; documented gotcha #5 below).
  • Defer Fonts also injects <link rel=preload> hints for any @font-face it touches — Amasty doesn't do this automatically.
  • bfcache explicitly ENFORCES no-store on private pages (defensive). Amasty's bfcache module just strips, doesn't enforce.
  • CLI etechflow:pso:optimize-images ships with --dry-run flag — Amasty's bulk CLI doesn't.

Compatibility claims (matching Amasty Pro)

  • ✅ Magento Open Source 2.4.4 – 2.4.8 / Adobe Commerce 2.4.4 – 2.4.8 / PHP 8.1 – 8.4
  • ✅ Hyvä Theme + Hyvä Checkout (no theme-specific code; everything lives in core admin + response plugins)
  • ✅ Mage-OS compatible
  • ✅ Varnish-aware (response plugins skip when Varnish hits)
  • ⚠️ AWS Remote Storage — not yet tested; v2.1
  • ⚠️ Hyvä CSP compliance — manual verification needed; v2.1 will audit

Live-test gotchas caught + documented

Adding to the running list (now at 6):

  1. (IO v1.2.0) PHP 8.1+ readonly child-property conflict on $formKey
  2. (IO v1.2.0) Magento XSD varchar length capped at 1024
  3. (IO v1.2.0) InnoDB utf8mb4 composite-index 3072-byte limit
  4. (PSO v1.1.0) Magento\Framework\DataObject::hasData($key = '') has a $key parameter
  5. (NEW — PSO v2.0) HttpResponse::getHeader('X') returns a Laminas Header object, NOT a string. Casting (string) $response->getHeader(...) throws on PHP 8+. Solution: a HeaderHelperTrait with a headerValue() accessor that calls ->getFieldValue() on the object. All 5 v2.0 response plugins use it.
  6. (NEW — PSO v2.0) PSR-4 filename↔classname mismatch on a lifted module. When you cp a file and rename it but forget to rename the class declaration inside, Magento's autoloader silently tries to load both — resulting in Cannot redeclare class fatals. ALWAYS rename the class inside when you rename the file.

v2.0 deferred to v2.1+

These Amasty Pro features need more time:

  • AVIF format support (next-gen image, smaller than WebP)
  • JPEG / PNG / GIF source compression (currently we only convert, don't compress originals)
  • Image resize with 2 algorithms (resize-proportional vs crop) for mobile/tablet variants
  • 4 lazy-load script choices (jQuery / Native / Vanilla / Lozad) — we ship native only
  • User-Agent device detection — different settings per mobile/tablet/desktop
  • Multi-Process Generation — parallel image processing
  • Auto-optimize on upload — observer on product image save
  • Smart optimization by viewed pages (Amasty's newest feature)
  • CSS minification + merging
  • JS bundling + merging
  • Minify JS in PHTML files (non-cacheable page optimization)
  • Cron Tasks List admin UI
  • Sign static files (browser cache invalidation tokens)
  • Async order indexing
  • CDN URL rewriting for static assets

Premium tier (v3.0):

  • AJAX Shopping Cart
  • Infinite Scroll for category pages
  • Image optimization by Cron (scheduled, not immediate)
  • JS merging per device
  • Logging for auto-optimization

Migration

composer update etechflow/module-page-speed-optimizer
bin/magento setup:upgrade      # creates etechflow_pso_optimization_log table
bin/magento setup:di:compile
bin/magento cache:flush
# Restart php-fpm to clear OPcache (mandatory on prod with opcache.validate_timestamps=0)

After upgrade, every code-optimization toggle defaults to OFF. Test on staging first — JS defer in particular can break themes that rely on synchronous script execution.

Pricing positioning

Product Price What it gets you
ETechFlow IO $0 (free tier — matches Amasty's free) Basic lazy-load + WebP image optimization only
ETechFlow PSO Pro v2.0 $179 (vs Amasty Pro $199) Full image + code optimization + PSI Diagnostic + Trends + bfcache
ETechFlow PSO Premium v3.0+ (planned) $499 (vs Amasty Premium $599) All of Pro + AJAX Cart + Infinite Scroll + Cron-scheduled image opt + per-device JS merging

[1.1.0] — 2026-05-21 — Score Timeline graph + History CLI

Pure additive release on top of v1.0.0. The diagnostic runs we've been logging into etechflow_pso_diagnostic_log now surface as a visual trend graph + a tabular history CLI.

Added

  • Admin page at Stores → Settings → Page Speed Trends — visual score-over-time chart with the last 20 diagnostic runs in a table below.
    • Inline SVG line chart, server-rendered. No JS lib dependency (no Chart.js, no React, no jQuery). Loads instantly.
    • One coloured line per (URL, strategy) combination. Hover any data point to see the exact score + timestamp.
    • Y-axis grid lines highlight Google's score bands (90 = green / 50 = orange thresholds).
    • Recent-runs table with colour-coded scores, LCP / TBT / CLS columns.
  • bin/magento etechflow:pso:history --url=... --limit=20 --json CLI — tabular dump of recent runs. Useful for:
    • CI pipelines tracking score regression over time
    • Agency dashboards aggregating across multiple stores
    • Quick "what's the current state?" check without opening admin
  • New ACL resource ETechFlow_PageSpeedOptimizer::trends separately grantable from ::diagnose — view-only roles can see history without being able to spawn new diagnostic runs.

Backwards compatibility

No schema changes, no setup:upgrade required when upgrading from v1.0.0 → v1.1.0. Only composer update + cache:flush.

Migration

composer update etechflow/module-page-speed-optimizer
bin/magento setup:di:compile
bin/magento cache:flush

Magento gotcha caught by live testing

Adding to our running list of "Magento APIs that bite you on first run":

  • Magento\Framework\DataObject::hasData($key = '') has a $key parameter, so a child block class can't define public function hasData(): bool (no args) — PHP rejects the incompatible signature at compile time. Named our method hasAnyRuns() instead. (Adds to the IO v1.2.0 lessons about $formKey readonly conflict, varchar(1024) cap, and InnoDB 3072-byte index limit.)

[1.0.0] — 2026-05-21 — Google PageSpeed Insights diagnostic + foundation

First commercial release. Ships the PSI Diagnose feature — the visible-feature that closes every "is your store fast?" conversation with merchants. Code optimization (CSS/JS/HTML minification, defer fonts, prioritize resource loading) follows in v1.1+.

Why v1.0 ships Diagnose first

Every Amasty / Mageworx / Mirasvit page-speed module markets the same optimization features. What makes Amasty's $259 product feel premium is the Diagnostic tool — it shows merchants a real Google score before/after, with concrete recommendations. We ship that as v1.0 because:

  1. It's the highest-perceived-value feature in the category
  2. It gives merchants something to measure their other ETechFlow modules against (IO's WebP conversion, future PSO minification, etc.)
  3. The code already exists — it was originally added to IO v1.2.0 then moved here in IO v1.3.0 because a measurement tool didn't belong in an image-optimization module.

Added

Foundation

  • registration.php, composer.json (proprietary licence, soft-deps on IO + suite modules via Bundle key).
  • etc/module.xml setup_version 1.0.0.
  • DB schema: 1 table etechflow_pso_diagnostic_log — full audit of every PSI run with lab + field metrics + raw JSON for future re-parsing.
  • Admin config (etc/adminhtml/system.xml) — License section + Google PageSpeed Insights section + Code Optimization section (placeholder toggles for v1.1+ features).

Licensing + Infrastructure

  • Model/LicenseValidator — per-domain HMAC + bundle key. MODULE_ID = page-speed-optimizer. Shares BUNDLE_SECRET_FRAGMENTS byte-identical with every other ETechFlow module.
  • Model/Config — license-aware isEnabled(). PSI API key + default strategy + timeout getters.
  • Model/Performance/Profiler — Tideways span helper, tags ETechFlow_PSO_*.

Google PageSpeed Insights Integration

  • Model/Psi/PsiClient — vanilla Curl client. Free tier: 25,000 requests/day per merchant's Google Cloud API key (no key works too, with Google's per-IP rate limit).
  • Model/Data/DiagnosticResult — typed value object: lab Lighthouse score + Core Web Vital metrics + CrUX real-user field metrics + sorted recommendation list.
  • Model/Recommendation/Mapper — curated mapping of 16 PSI audit IDs to the ETechFlow feature that fixes them. Drives the "ETechFlow can fix this" badge inline next to each Google recommendation.
  • Model/Psi/DiagnosticLogger — best-effort persistence to the audit table.

Admin UI

  • New page at Stores → Settings → Page Speed Diagnose:
    • Big colour-coded score card (green ≥ 90, orange 50-89, red < 50 — Google's own bands)
    • Lab metrics row (FCP, LCP, TBT, CLS)
    • Field metrics row (real-user CrUX data when available — LCP, INP, CLS + overall FAST/AVERAGE/SLOW category)
    • Sorted recommendation list (biggest LCP impact first) with HIGH/MEDIUM/LOW badges
    • ETechFlow fix badge on every recommendation we cover

CLI

  • bin/magento etechflow:pso:diagnose --url=... --strategy=mobile|desktop --json --pass-score=80 — headless diagnostic for CI gates.
  • bin/magento etechflow:pso:verify — 10-check smoke test.

Deferred to v1.1+

  • CSS minification (build-time, stored in pub/static)
  • JavaScript minification + defer
  • HTML minification
  • Defer Fonts Loading with exclusion list
  • Prioritize Resource Loading (<link rel="preload"> injection)
  • GZIP/Brotli headers via .htaccess / nginx hints
  • Critical CSS extraction (above-the-fold CSS inlining)
  • Performance budgets (admin-set max JS/CSS/image total per page; flag offenders)
  • Score timeline graph (chart of LCP / INP / CLS over time from the diagnostic_log table)
  • Hyvä Mode (auto-detect Hyvä, skip optimizations Hyvä already handles)

Setup (one-time, ~3 min)

  1. Go to https://console.cloud.google.com/apis/credentials
  2. Click "Create Credentials → API Key" (free)
  3. Enable "PageSpeed Insights API" on the project (free, 25,000 requests/day)
  4. Paste the key into Stores → Configuration → eTechFlow → Page Speed Optimizer → Google PageSpeed Insights → PageSpeed Insights API Key

Without a key it still works (Google's per-IP rate limit) but the key is strongly recommended.

Compatibility

  • Magento Open Source 2.4.4 – 2.4.8
  • Adobe Commerce 2.4.4 – 2.4.8
  • PHP 8.1 / 8.2 / 8.3 / 8.4
  • Hyvä Theme + Hyvä Checkout (PSO is admin-side; theme-agnostic for now — Hyvä-aware optimizations land in v1.1+)
Versions
Version Stability QA Status Compatibility Released
2.5.5 stable Fail Magento 2.4.7-2.4.8 Details 2026-06-22 11:39:20
2.5.4 stable Not tested Not yet tested Details 2026-06-22 09:37:33
2.5.0 stable Not tested Not yet tested Details 2026-06-06 14:14:44
2.4.0 stable Not tested Not yet tested Details 2026-06-04 10:23:48
2.3.1 stable Not tested Not yet tested Details 2026-05-30 14:33:11
2.3.0 stable Not tested Not yet tested Details 2026-05-21 10:02:55
2.2.0 stable Not tested Not yet tested Details 2026-05-21 09:55:49
2.1.0 stable Not tested Not yet tested Details 2026-05-21 09:41:38
2.0.0 stable Not tested Not yet tested Details 2026-05-21 07:20:33
1.1.0 stable Not tested Not yet tested Details 2026-05-21 06:15:11
1.0.0 stable Not tested Not yet tested Details 2026-05-21 06:07:22

Requires 7

Package Constraint
magento/framework ^103.0||^104.0
magento/module-backend ^102.0||^103.0
magento/module-catalog ^104.0||^105.0
magento/module-config ^101.2||^102.0
magento/module-store ^101.1||^102.0
magento/module-ui ^101.2||^102.0
php ~8.1.0||~8.2.0||~8.3.0||~8.4.0

Suggests 3

Package Reason
etechflow/module-back-in-stock-notification Bundle key activates this module too.
etechflow/module-image-optimizer Lighter sibling with image-optimization only. PSO Pro supersedes it on full-feature stores.
etechflow/module-next-day-eligibility Bundle key activates this module too.

No QA results yet

QA pipelines haven't run for this version. Compatibility and quality results appear here once the vendor publishes a tagged release that gets ingested.

License
proprietary
Authors

More from etechflow

View vendor
Make it pay

Turn an existing module into recurring revenue.

If you already maintain a Magento 2 module on GitHub or GitLab, listing it on Packagento takes about five minutes. We mirror your tags, handle distribution signing, and route paid licenses through Stripe Connect, so you can keep shipping the way you already do.