Performance - v1.0.0
View Customization
The performance package ships every user-facing view as an overridable template. This guide is the reference for the three levers you have — publishing the templates for direct edits, tweaking component props and slots without touching templates, and layering CSS custom properties on top of the base stylesheet.
Publishing Views
Publish the Blade templates when you want to fork the markup itself (different class names, different DOM structure, additional wrapper elements):
php artisan vendor:publish --tag=performance-views
Templates land at resources/views/vendor/artisanpack-ui/performance/
and Laravel prefers the published copy over the package copy at render
time. Directory layout under that root:
components/
├── critical-css.blade.php
├── lazy-image.blade.php
├── perf-embed.blade.php
├── perf-prefetch.blade.php
├── perf-script.blade.php
├── resource-hints.blade.php
├── responsive-image.blade.php
└── speculative-rules.blade.php
livewire/
├── cache-manager.blade.php
├── metrics-chart.blade.php
├── performance-dashboard.blade.php
├── query-analyzer.blade.php
└── recommendations-panel.blade.php
You can also publish the base CSS and the JS bundle if you want to fork those:
php artisan vendor:publish --tag=performance-css
php artisan vendor:publish --tag=artisanpack-performance-js
- CSS publishes to
resources/css/vendor/artisanpack-ui/performance.css - JS publishes to
resources/js/vendor/artisanpack-performance/
Republishing overwrites your local edits, so keep them under source control and re-publish deliberately.
Blade Component Props
Every prop below is optional. Attributes not listed pass through to the outer element via the component's attribute bag.
<x-perf-lazy-image />
| Prop | Type | Default | Description |
|---|---|---|---|
src |
string |
— | Image source URL (required). |
alt |
string |
'' |
Alt text. Falls back to an empty string; supply one for accessibility. |
width |
?int |
null |
Rendered width. Sets width and CSS aspect-ratio when height is also present. |
height |
?int |
null |
Rendered height. |
lazy |
bool |
true |
Emit loading="lazy" and set up the intersection-observer placeholder. |
placeholder |
?string |
null |
Placeholder URL (dominant color, SQIP, blur-hash, etc.). |
dominantColor |
?string |
null |
Optional hex color used as a background before the image paints. |
blurSrc |
?string |
null |
Blur-up thumbnail source. |
fetchpriority |
?string |
null |
high / low / auto. |
threshold |
?string |
null |
Intersection-observer root margin (e.g. 200px). |
sizes |
?string |
null |
sizes attribute. |
srcset |
?string |
null |
Explicit srcset. When absent, <x-perf-responsive-image> is a better fit. |
class |
?string |
null |
Extra classes merged into the wrapper. |
<x-perf-responsive-image />
| Prop | Type | Default | Description |
|---|---|---|---|
src |
string |
— | Base image source (required). |
sizes |
?array |
null |
Width breakpoints to generate. Defaults to the package's configured sizes. |
sizesAttr |
?string |
null |
Explicit sizes attribute (overrides the derived one). |
width |
?int |
null |
Rendered width. |
height |
?int |
null |
Rendered height. |
lazy |
bool |
true |
Enable lazy loading. |
placeholder |
?string |
null |
Placeholder URL. |
dominantColor |
?string |
null |
Placeholder color. |
fetchpriority |
?string |
null |
high / low / auto. |
formats |
?array |
null |
Modern formats to emit (['webp', 'avif']). |
class |
?string |
null |
Extra classes. |
<x-perf-script />
| Prop | Type | Default | Description |
|---|---|---|---|
src |
string |
— | Script URL (required). |
strategy |
?string |
config default | defer, async, module, inline, or conditional. |
priority |
?int |
null |
Sort key for the script queue. |
name |
?string |
null |
Handle emitted as data-script-name. |
loadOn |
?string|array |
null |
Conditional triggers (visible, idle, click, mouseover, network:4g). Passing this implicitly switches strategy to conditional. |
target |
?string |
null |
Selector for viewport / interaction triggers. |
Any additional HTML attributes (integrity, crossorigin, nonce,
type for non-conditional strategies, custom data-*) pass through
unchanged.
<x-perf-conditional-script />
Identical prop surface to <x-perf-script /> except strategy is
forced to conditional and loadOn defaults to visible.
<x-perf-embed />
| Prop | Type | Default | Description |
|---|---|---|---|
provider |
string |
— | youtube, vimeo, twitter (or x). |
id |
string |
— | Provider-specific ID. |
title |
?string |
provider default | Accessible label for the facade / iframe. |
lazy |
bool |
true |
Emit a facade that swaps in the provider iframe on click. |
showFacade |
bool |
true |
When lazy is true, whether to render a thumbnail/play button. |
thumbnail |
?string |
provider CDN | Override the facade thumbnail. |
params |
array |
[] |
Provider params (['start' => 30, 'autoplay' => true]). |
width |
?int |
null |
Rendered width. |
height |
?int |
null |
Rendered height. |
class |
?string |
null |
Extra classes. |
<x-perf-prefetch />
| Prop | Type | Default | Description |
|---|---|---|---|
urls |
array|string |
— | One or more URLs / route names. |
as |
?string |
null |
Optional resource type (script, style, image). |
crossorigin |
?string |
null |
Cross-origin mode. |
<x-perf-speculative-rules />
| Prop | Type | Default | Description |
|---|---|---|---|
prefetch |
?array |
null |
Prefetch rules override. |
prerender |
?array |
null |
Prerender rules override. |
Both keys accept the raw
Speculation Rules API
urls/where shape. Omitting them makes the component emit the rules
built from artisanpack.performance.speculative_loading config.
<x-perf-resource-hints />
| Prop | Type | Default | Description |
|---|---|---|---|
hints |
?array |
null |
Inline descriptors (['rel' => 'preconnect', 'href' => 'https://cdn.example']). Omitting reads from the injector singleton. |
only |
?array|string |
null |
Filter — only render hints whose rel matches. |
<x-perf-critical-css />
| Prop | Type | Default | Description |
|---|---|---|---|
route |
?string |
current route | Explicit route name to look up in the cache. |
Livewire Component Props and Slots
The dashboard components use the same public prop convention as Laravel
components — set them via <livewire:perf-performance-dashboard :label="…" />
or Livewire::mount(PerformanceDashboard::class, ['labels' => [...]]).
<livewire:perf-performance-dashboard />
| Prop | Type | Default | Description |
|---|---|---|---|
class |
string |
'' |
Extra classes on the outer wrapper. |
cardClasses |
string |
'' |
Extra classes for the header container. |
dateRange |
string |
'7d' |
Initial date range (24h, 7d, 30d, 90d). |
activeTab |
string |
'overview' |
Initial tab. |
labels |
array |
[] |
Label overrides. Keyed by canonical label name; unmatched keys are ignored. |
Available slots (via <x-slot:name>):
| Slot | Description |
|---|---|
header |
Rendered above the toolbar, inside a .performance-dashboard__header block. |
beforeMetrics |
Rendered above the metric cards. |
afterRecommendations |
Rendered below the recommendations block. |
footer |
Rendered at the very bottom of the dashboard. |
<livewire:perf-cache-manager />
| Prop | Type | Default | Description |
|---|---|---|---|
labels |
array |
[] |
Override individual button/label strings — supported keys: purge, warm, flush, invalidate. |
<livewire:perf-query-analyzer />
| Prop | Type | Default | Description |
|---|---|---|---|
labels |
array |
[] |
Override the exported CSV / table labels. |
dateRange |
?string |
config default | Same shape as the dashboard's range. |
<livewire:perf-metrics-chart /> and <livewire:perf-recommendations-panel />
Both accept a labels prop for the same purpose. See each component's
class docblock for the specific label keys.
CSS Variables
The base stylesheet lives at resources/css/performance.css and defines
every visual token as a CSS custom property. Override values by setting
them at any wrapping scope:
:root {
--perf-color-good: #22c55e;
--perf-color-poor: #ef4444;
--perf-radius: 0.75rem;
--perf-font-family: "InterVariable", sans-serif;
}
Reference
| Variable | Default | What it controls |
|---|---|---|
--perf-color-surface |
#ffffff |
Panel backgrounds |
--perf-color-surface-alt |
#f8fafc |
Recommendation card background |
--perf-color-border |
#e2e8f0 |
Table row / card borders |
--perf-color-text |
#0f172a |
Body text |
--perf-color-muted |
#64748b |
Secondary text |
--perf-color-good |
#16a34a |
Passing Core Web Vitals badge |
--perf-color-needs-improvement |
#f59e0b |
Warning badge |
--perf-color-poor |
#dc2626 |
Failing badge |
--perf-color-unknown |
#94a3b8 |
Missing-data badge |
--perf-color-priority-high |
#dc2626 |
High-priority recommendation border |
--perf-color-priority-medium |
#f59e0b |
Medium-priority recommendation border |
--perf-color-priority-low |
#0284c7 |
Low-priority recommendation border |
--perf-color-button-bg |
#0f172a |
Button background |
--perf-color-button-text |
#ffffff |
Button text |
--perf-font-family |
system-ui, … |
Font stack |
--perf-font-size-base |
0.9375rem |
Body font size |
--perf-font-size-heading |
1.25rem |
Heading font size |
--perf-space-xs |
0.25rem |
Space scale (extra-small) |
--perf-space-sm |
0.5rem |
Space scale (small) |
--perf-space-md |
1rem |
Space scale (medium) |
--perf-space-lg |
1.5rem |
Space scale (large) |
--perf-radius |
0.5rem |
Card / panel border radius |
--perf-shadow |
subtle shadow | Card / panel shadow |
Dark Mode
Two entry points cover both auto and manual theming:
/* System-driven — no code changes required. */
@media (prefers-color-scheme: dark) {
:root { --perf-color-surface: #0f172a; /* … */ }
}
/* Manual toggle — add or remove `perf-theme-dark` on <html> or any wrapper. */
.perf-theme-dark { --perf-color-surface: #0f172a; /* … */ }
The bundled stylesheet already includes dark-mode variables for both entry points. Overwrite them the same way you overwrite the light-mode values.
Component Extension
For deeper changes than props allow, extend the component class.
Custom perf-script variant
<?php
namespace App\View\Components\Performance;
use ArtisanPackUI\Performance\JavaScript\ScriptRegistration;
use ArtisanPackUI\Performance\View\Components\PerfScript;
final class AnalyticsScript extends PerfScript
{
public function __construct( string $src )
{
parent::__construct(
src: $src,
strategy: 'defer',
name: 'analytics',
);
}
protected function applyStrategy( ScriptRegistration $registration ): void
{
// Route all analytics scripts through the conditional strategy
// when Do-Not-Track is respected in the current request.
if ( '1' === request()->header( 'DNT' ) ) {
$registration->conditional();
return;
}
parent::applyStrategy( $registration );
}
}
Register it via AppServiceProvider::boot():
Blade::component( 'analytics-script', AnalyticsScript::class );
Custom chart implementation
MetricsChart reads its Chart.js payload from the data-chart-payload
attribute. Extend the Livewire component to swap in a different chart
library or a server-rendered SVG:
<?php
namespace App\Livewire\Performance;
use ArtisanPackUI\Performance\Livewire\MetricsChart as BaseMetricsChart;
class MetricsChart extends BaseMetricsChart
{
public function render()
{
return view( 'components.performance.metrics-chart-apex', [
'series' => $this->buildApexSeries(),
] );
}
protected function buildApexSeries(): array
{
return [
[
'name' => 'LCP',
'data' => $this->timeSeriesFor( 'LCP' ),
],
];
}
}
Then re-alias the Livewire component in a service provider:
\Livewire\Livewire::component(
'perf-metrics-chart',
\App\Livewire\Performance\MetricsChart::class,
);
Method overriding
Every non-final protected method on the bundled components is intended to be overridable. Common extension points:
| Component | Method | Purpose |
|---|---|---|
PerfScript |
applyStrategy(ScriptRegistration) |
Switch strategies at request time. |
PerfEmbed |
resolveFacade() |
Route unusual embed shapes through a custom optimizer. |
CriticalCss |
resolveRoute(?string) |
Map non-standard route resolution (e.g. subdomain-based). |
PerformanceDashboard |
refreshMetrics() |
Add custom telemetry before the metric fetch fires. |
CacheManager |
flushAll() |
Wrap the base action with authorization / audit logging. |
JavaScript Customization
The bundled JS lives at resources/js/:
web-vitals.js— RUM collector.speculative-rules.js— Speculation Rules polyfill + embed activator.metrics-chart.js— Chart.js bootstrap.
Event hooks
speculative-rules.js exposes hooks on window.PerformanceSpeculativeLoader:
window.PerformanceSpeculativeLoader.inject({
prerender: [ { where: { href_matches: '/pricing' }, eagerness: 'moderate' } ],
});
web-vitals.js respects the following dataset attributes when discovering
the endpoint:
<script data-perf-vitals-endpoint="/api/perf/metrics">— override the POST target.<script data-perf-vitals-sampled-out="true">— client-side sampling gate that suppresses the beacon entirely.
Alpine.js customization
The Livewire templates work without Alpine, but attach freely if it is already on the page:
<div
x-data="{ open: false }"
@toggle-cache-controls.window="open = !open"
>
<livewire:perf-cache-manager />
<div x-show="open"> … custom drawer … </div>
</div>
Wire your Alpine directives against Livewire's DOM by dispatching browser events from a subclassed component — this avoids fighting the Livewire morph pass on every render.
JS configuration options
web-vitals.js reads its runtime config from the data- attributes on
its own <script> tag. Any of the following can be set when you include
the bundle:
| Attribute | Effect |
|---|---|
data-perf-vitals-endpoint |
Endpoint URL. Defaults to /api/performance/metrics. |
data-perf-vitals-sampled-out |
When true, disable the beacon entirely. |
data-perf-vitals-route |
Explicit route name sent with each sample. |
data-perf-vitals-device |
Client-side device classifier (desktop, mobile, tablet). |
data-perf-vitals-connection |
Manual connection type override (rare). |
speculative-rules.js uses data-prefetch / data-prerender markers on
anchors. Add them via server-rendered HTML or via
document.querySelectorAll in the host app to trigger the fallback
<link rel="prefetch"> injection on browsers that lack the
Speculation Rules API.
Where to go next
README.md— feature-by-feature configuration reference.docs/security/audit-1.0.0.md— the pre-1.0 security audit.docs/development/code-style.md— code-style tooling / pre-commit workflow.- The
resources/viewsdirectory itself — the templates are short and well-commented; reading them is often faster than searching for the hook you want.