Performance - v1.0.0
Performance Changelog
All notable changes to the artisanpack-ui/performance package are documented
in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Unreleased
1.0.0 - 2026-07-04
Initial public release of the ArtisanPack UI Performance package. Every
feature ships opt-in via config/artisanpack/performance.php so an install
adds zero overhead until a feature is toggled on.
Added
Core infrastructure
PerformanceServiceProvider— registers configuration, migrations, event listeners, Blade directives, Livewire components, middleware aliases, the admin route file, and every console command; publishes the package's four publish tags (artisanpack-performance-config,artisanpack-performance-js,performance-views,performance-css).perf:installArtisan command — publishes the package configuration, optionally publishes views / JavaScript / stylesheet, runs migrations, validates PHP and Laravel versions plus storage writability, clears configuration and view caches, and prints the dashboard gate stub with next-step guidance. Idempotent; skips migrations already run and only overwrites existing published files with--force. Flags:--config,--views,--js,--css,--migrations,--skip-migrate,--skip-checks,--force, and standard--no-interaction.Performancefacade + container singleton for programmatic access to every service.- Global helper functions autoloaded via Composer for the common request-lifecycle operations (feature toggles, cache reads, hint registration, RUM ingestion).
- Event system — package emits
PerformanceMetricRecorded,CacheHit,CacheMissed,SlowQueryDetected,N1QueryDetected,ImageOptimized, andRecommendationGeneratedevents so applications can subscribe without patching the package. - Database migrations for performance metrics, slow queries, cache entries, and optimized images tables.
Image optimization
- WebP and AVIF conversion pipeline with quality controls per format and per source image.
- Responsive image generation (
ResponsiveImageGenerator) with configurable breakpoints,srcset/sizesoutput, and per-breakpoint cropping rules. - Lazy loading with placeholder generation — low-quality image placeholders
(LQIP), dominant-color placeholders via
DominantColorExtractor, and configurable intersection-observer thresholds. fetchpriorityhint support on above-the-fold imagery.- Queued image processing so uploads never block the request thread.
perf:generate-webpArtisan command for bulk conversion of the media library.
JavaScript & CSS
- Script loading strategies —
AsyncStrategy,DeferStrategy,ModuleStrategy,InlineStrategy, andConditionalStrategy, all routed throughScriptManager. - Critical CSS extraction (
CriticalCssExtractor) with per-route caching, above-the-fold selectors, and inline injection in the document head. - Resource hints (
preload,prefetch,preconnect,dns-prefetch) with auto-detected hints for critical assets and a manual registration API for developer-supplied hints. - Blade directives and view components for hint registration and script strategy selection.
perf:critical-cssArtisan command for regenerating critical CSS across the site.
Speculative loading
- Speculation Rules API support with configurable eagerness levels and
URL pattern matching (
UrlPatternMatcher). <x-perf-prefetch>component for per-link prefetch/prerender opt-in.- Embed optimizer for YouTube / Vimeo / Twitter embeds — replaces heavy iframes with click-to-load placeholders.
Caching
- Full-page caching with configurable exclude routes, exclude closures, query-string handling, and vary-by keys.
- Fragment caching keyed by tags with TTL and cache-warming support.
- Cache warming CLI command (
perf:warm-cache) that pre-fetches configured URLs or Livewire component states on a schedule. - Automatic invalidation via
CacheInvalidator— wire model events or application events to a cache-tag map to clear related fragments on writes. CacheStrategyManager— selects between page cache, fragment cache, and model-level caching based on the request context.CachingEloquentBuilder— opt-in Eloquent macro that transparently caches query results with automatic tag invalidation.perf:purge-cacheArtisan command with--type=page|fragment|alland--pattern/--tagtargeting.
Database optimization
- N+1 query detection (
N1Detector) that logs offending relations and suggests eager-load fixes. - Slow query logging (
SlowQueryLogger) with configurable threshold and aggregation. - Index suggestions (
IndexSuggester) based on observed slow queries. perf:suggest-indexesArtisan command for offline analysis of the slow query log.QueryAnalyzerfor grouping slow queries by normalized SQL fingerprint.
Server-side
- HTML minification middleware (
MinifyHtml/perf.minify) — runs HTML responses throughHtmlMinifier, skipping streamed / binary responses, non-2xx status codes, non-HTML content types, and routes matched byhtml_minification.exclude_routes. UpdatesContent-Lengthwhen the original response declared one. - HTTP/2 Early Hints middleware (
EarlyHints/perf.early-hints) — emits an HTTP 103 interim response with preload / preconnect Link headers before the controller runs, and mirrors the same hints into the final response so 103-unaware intermediaries (older caches, simple reverse proxies) still see the metadata. Hints merge config-suppliedmanual_hintswith auto-detected entries fromResourceHintInjector; both sources are deduplicated by(rel, href, as). SAPI emission usesheader()+flush()(orfastcgi_finish_requestunder FPM) and is swappable for tests. OutputBuffer(ArtisanPackUI\Performance\Output\OutputBuffer) — instance-scoped wrapper around PHP's output-buffering primitives with nestedstart()/end(), exception-safecapture(), and a transformer pipeline used by downstream response mutators. Registered as a container singleton with an Octane request-received reset hook so a leaked open buffer can't carry across requests.
Performance monitoring
- Core Web Vitals RUM collector — LCP, FID, CLS, INP, and TTFB posted to the ingest endpoint as they resolve.
@perfMonitorBlade directive andSupport\MonitorDirectiveshelper — bootstraps the Core Web Vitals RUM collector by emitting an inline configuration script (endpoint, sample rate, CSRF token, route/page context) followed by a deferred<script type="module">tag pointing at the publishedweb-vitals.js. Accepts per-call overrides (endpoint,sampleRate,extra,src) for per-page customization. Renders nothing whenmonitoring.enabledormonitoring.collect_web_vitalsis off so opted-out environments don't ship dead JavaScript.resources/js/web-vitals.jsCore Web Vitals collector — ESM module that imports theweb-vitalsnpm package and posts metrics to the configured endpoint as they resolve. Session-level sampling, connection / device-type capture,sendBeacon-first transport with afetch({ keepalive: true })fallback, and CSRF token forwarding viaX-CSRF-TOKEN. Published underresources/js/vendor/artisanpack-performance/via theartisanpack-performance-jspublish tag.- Livewire performance dashboard — overview, per-page metrics, cache manager, query analyzer, and recommendations panel.
RecommendationEngine— scans aggregated metrics for LCP hotspots, N+1 offenders, oversized assets, and cache-miss patterns.MetricsAggregator— rolls raw metric events into 24h, 7d, 30d, and 90d buckets, dispatched by theperf:aggregate-metricsscheduled command.
Admin JSON API
- New endpoints under
POST/GET /api/performance/admin/*back the React/Vue components (Livewire dashboards previously kept state on the server and could not be consumed from a bundler-based front-end). All endpoints run throughAdminApiController::authorizeAdmin(), which resolves the ability name fromartisanpack.performance.dashboard.gateand falls back toview-performance-dashboardwhen the config is blanked out — a missing or empty config cannot inadvertently expose the endpoints.GET /admin/dashboard(DashboardAdminApiController) — overview + pages + cache summary payload keyed by the requested range (24h|7d|30d|90d).GET /admin/chart(ChartAdminApiController) — chart payload matching the shape the bundledmetrics-chart.jsrenders; acceptsmetrics,range,show_threshold,type.GET /admin/cache+POST /admin/cache/actions(CacheAdminApiController) — page and fragment cache snapshot plus mutating actions (flush,warm,invalidate-key,invalidate-tag).GET /admin/queries+GET /admin/queries/export(QueriesAdminApiController) — grouped slow-query rows withIndexSuggesterhints; CSV export uses a formula-injection sanitizer.GET /admin/recommendations+POST /admin/recommendations/actions(RecommendationsAdminApiController) — recommendation list withapply/dismiss/resetactions. Dismissals share theartisanpack.performance.dismissed_recommendationssession key with the Livewire panel so users see a consistent state across both surfaces.
- Metrics ingest endpoint (
POST /api/performance/metrics) — accepts Core Web Vitals payloads from the browser collector, validates them againstmonitoring.sample_rate, and dispatchesPerformanceMetricRecordedfor downstream storage.
React + Vue companion components
- Shared vanilla client at
resources/js/performance.ts— typedPerformanceClientwith methods for the dashboard, chart, cache, queries, recommendations, and metrics-ingest endpoints. Auto-resolves the CSRF token from a<meta name="csrf-token">tag; consumers can override the base URL and fetch implementation. - React entry:
@artisanpack-ui/performance/react. Components:LazyImage,ResponsiveImage,PerfEmbed,PerfPrefetch,SpeculativeRules,PerformanceDashboard,MetricsChart,CacheManager,QueryAnalyzer,RecommendationsPanel. Hook:usePerformance— thin wrapper that returns the shared client's methods and a smalluseAsyncPayloadhelper for load-on-mount patterns. - Vue entry:
@artisanpack-ui/performance/vue. Same component set as.vueSFCs plus ausePerformancecomposable that mirrors the React hook's API.LazyImage,PerfEmbed, andSpeculativeRulesuse<Teleport>/head-portal patterns where applicable so the injected<script>/<link>elements land in<head>. package.jsonat the package root declares@artisanpack-ui/performancewith optional peer dependencies onreact,react-dom, andvue. Sub-path exports (./react,./vue,./web-vitals,./metrics-chart,./speculative-rules) so hosts pull in only what they need.tsconfig.jsonmirrors the privacy package's setup (ES2022, bundler resolution,jsx: preserve,.vuein the include list).
Documentation
docs/tree with feature guides for image optimization, caching, database optimization, speculative loading, monitoring, and the admin API.examples/directory with runnable snippets covering the quick-start path, image optimization, JavaScript / CSS optimization, caching, database, monitoring, and existing-app integration.CHANGELOG.mdfollowing Keep a Changelog format.README.md,CONTRIBUTING.md, and inline PHPDoc on every public class and method.
Changed
illuminate/supportconstraint now allows^13.0alongside the existing^10.0|^11.0|^12.0range. Laravel 13 requires PHP 8.3+; the PHP floor for users staying on older Laravel versions is unchanged.
Security
- Admin JSON API endpoints fall back to the
view-performance-dashboardability when the configured gate name is blank so a mis-published config cannot inadvertently expose the endpoints. - Slow-query CSV export sanitizes formula-injection payloads
(
=,+,-,@, tab, carriage return) in every cell before writing. - Metrics ingest endpoint validates payload shape and rejects unknown metric names so a compromised browser cannot poison the aggregated metrics store.
Migration notes
- Fresh install: run
php artisan perf:install --no-interactionaftercomposer require artisanpack-ui/performance. Every feature is off by default; enable only what you need inconfig/artisanpack/performance.php. - Define the
view-performance-dashboardgate (or your configured gate name) inAuthServiceProvider::boot()before the dashboard route is reachable. - Add
@perfMonitorto your main layout to start collecting Core Web Vitals data. - Publish and rebuild the JavaScript bundle when integrating the
React / Vue components:
php artisan vendor:publish --tag=artisanpack-performance-jsfollowed by your normalnpm run build.