agentsclimarketplace

Livewire optimize

Skill edulazaro/laraclaude/skills/livewire-optimize

Detect and fix Livewire performance issues - heavy renders, excessive queries, unnecessary reactivity.From its SKILL.md

Install
npx -y skills add edulazaro/laraclaude --skill livewire-optimize

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 12 stars12 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

9.6 KB, as published. Nobody here has run it

Subcommands

SubcommandDescription
reportScan all Volt components and report performance issues without changes
fixScan all Volt components, report issues, and auto-fix what is safe
fix --dry-runShow what fixes would be applied without writing changes
<file-path>Scan a single file and report performance issues
fix <file-path>Scan a single file and auto-fix performance issues

Overview

This skill analyzes Livewire/Volt components for performance anti-patterns that cause slow page loads, excessive server requests, large payloads, and unnecessary re-renders. It focuses on issues that degrade user experience at scale.

Instructions

Step 1: Determine scope

Parse the argument:

  • No argument or report: Scan all Volt components under resources/views/livewire/.
  • fix (no path): Same scope, apply safe fixes.
  • fix --dry-run: Show proposed fixes without applying.
  • <file-path>: Single file report.
  • fix <file-path>: Single file fix.

Use Glob to find Volt components:

resources/views/livewire/**/*.blade.php

Filter to files containing new class extends Component.

Step 2: Run each detection rule

Rule 1: Queries inside render() or blade template

Pattern to detect: Database queries executed during render. Look for:

  • Model::where(, Model::find(, DB::table(, DB::select( inside the render() method
  • ->get(), ->first(), ->count(), ->pluck(), ->paginate() inside render()
  • Queries inside blade template via {{ Model::where(...) }} or @php blocks
  • Relationship access that triggers lazy loading in blade: $this->model->relation-> where relation was not eager-loaded

These queries run on EVERY re-render (every Livewire request).

Report format:

[RENDER-QUERY] file.blade.php:89
  Query `User::where('active', true)->get()` inside render() runs on every re-render.
  Move to mount() and store result, or use #[Computed] with cache.

Fix: Move query to a #[Computed] method with appropriate caching, or move to mount() if the data is static.

Rule 2: Excessive public properties (payload bloat)

Pattern to detect: Volt components with more than 15 public properties.

Count all public $prop declarations in the PHP class block. Each public property is serialized and sent in every Livewire request/response.

Report format:

[EXCESSIVE-PROPS] file.blade.php
  Component has 23 public properties. Each is serialized on every request.
  Consider grouping related properties into a public array, using form objects,
  or splitting into sub-components.

Fix: No auto-fix (requires architectural decision). Report with specific suggestions based on the property types found.

Rule 3: wire:poll with heavy components

Pattern to detect: wire:poll or wire:poll.Xs on components that:

  • Have more than 10 public properties
  • Contain queries in render()
  • Have a polling interval under 5 seconds

Report format:

[HEAVY-POLL] file.blade.php:12
  wire:poll.2s on component with 18 public properties and render() queries.
  Each poll sends full component state. Consider:
  - Increasing interval to 10s+
  - Using wire:poll.visible to pause when tab is hidden
  - Extracting polled data to a smaller sub-component

Fix: Add .visible modifier if missing. Suggest increasing interval in report.

Rule 4: Large arrays/collections as public properties

Pattern to detect: Public properties that are assigned large datasets:

  • $this->items = Model::all()->toArray() or Model::get()->toArray() (unbounded queries)
  • Array properties populated in mount() from queries without ->limit() or ->take()
  • Properties assigned from ->pluck()->toArray() on tables known to have many rows

Report format:

[LARGE-PAYLOAD] file.blade.php:34
  Public property `$allLocations` assigned from `Location::all()->toArray()`.
  This could be thousands of items serialized on every request.
  Consider: server-side search, pagination, or lazy loading.

Fix: No auto-fix. Report only.

Rule 5: Components missing lazy loading

Pattern to detect: <livewire:component-name> tags in blade templates (parent components) where the child component:

  • Is below the fold (inside tabs, accordions, or far down in the layout)
  • Has heavy mount() logic (queries, file operations)
  • Is inside @if blocks that may not be initially visible

Look for child components rendered inside:

  • Tab panels (role="tabpanel", x-show, conditional display)
  • Accordion bodies
  • Modal bodies
  • Elements with hidden or display:none initial state

Report format:

[MISSING-LAZY] parent.blade.php:156
  <livewire:properties.features> is inside a hidden tab panel.
  Use <livewire:properties.features lazy /> to defer loading until visible.

Fix: Add lazy attribute to the <livewire: tag.

Rule 6: Missing #[Computed] on repeated method calls

Pattern to detect: Methods in the PHP class block that are called multiple times in the blade template without #[Computed] attribute.

Look for:

  • $this->methodName() appearing 2+ times in the blade section
  • The method in the PHP block does NOT have #[Computed] attribute
  • The method performs work (queries, calculations, array operations) - not simple getters

Report format:

[MISSING-COMPUTED] file.blade.php
  Method `getVisibleFields()` called 4 times in template without #[Computed].
  Each call executes the method body. Add #[Computed] to cache within request.

Fix: Add #[Computed] attribute above the method. Add use Livewire\Attributes\Computed; import if not present. Rename method to remove get prefix if following Livewire 3 conventions (e.g., getVisibleFields() -> visibleFields() with $this->visibleFields access in blade).

Rule 7: Multiple wire:model.live in same form

Pattern to detect: <form> elements (or containers with wire:submit) containing more than 2 wire:model.live bindings without debounce.

Each wire:model.live field sends a server request on every input change. Multiple such fields in one form compound the problem.

Report format:

[EXCESSIVE-LIVE-BINDING] file.blade.php:45-89
  Form contains 5 wire:model.live bindings without debounce.
  Each keystroke on any field triggers a full server roundtrip.
  Consider:
  - Using wire:model (update on submit only) for most fields
  - Adding .debounce.300ms for fields that need live updates
  - Using wire:model.blur for fields that only need update on focus loss

Fix: Convert wire:model.live to wire:model for fields that don't need real-time updates. Keep wire:model.live.debounce.300ms for search/filter fields.

Rule 8: Monolithic components that should be split

Pattern to detect: Components where:

  • The PHP class block exceeds 200 lines
  • There are more than 10 public methods (excluding lifecycle hooks)
  • The blade template exceeds 400 lines
  • Multiple unrelated concerns are handled (e.g., CRUD + filters + modals + exports)

Report format:

[MONOLITHIC-COMPONENT] file.blade.php
  Component has 285 PHP lines, 18 methods, 520 template lines.
  Consider splitting into:
  - A parent coordinator component
  - Separate filter component
  - Separate table/list component
  - Separate modal components

Fix: No auto-fix. Report with specific splitting suggestions based on the component's structure.

Step 3: Generate report

Group findings by severity and impact:

Severity levels:

  • CRITICAL: Causes visible performance degradation (render queries, heavy polling, large payloads)
  • WARNING: Wastes resources but may not be immediately visible (excessive props, missing lazy, missing computed)
  • INFO: Best practices that improve performance marginally (live bindings, monolithic components)

Output format:

## Livewire Performance Report

### resources/views/livewire/properties/index.blade.php

- [CRITICAL] Line 89: Query inside render() - User::where('active', true)->get()
- [CRITICAL] Line 12: wire:poll.2s with 18 public properties
- [WARNING] Component has 23 public properties (payload bloat)
- [INFO] 5 wire:model.live bindings in form without debounce

### resources/views/livewire/calendar.blade.php

- [WARNING] Method getVisibleFields() called 4x without #[Computed]
- [WARNING] <livewire:event-list> in hidden tab without lazy

---
**Summary**: 2 critical, 3 warnings, 1 info across 2 files.
**Estimated impact**: Fixing critical issues could reduce server load by ~60% on affected pages.

Step 4: Apply fixes (if fix mode)

Safe auto-fixes (applied automatically):

  • Add #[Computed] to methods called multiple times in blade
  • Add use Livewire\Attributes\Computed; import
  • Add lazy to child components in hidden containers
  • Add .visible to wire:poll directives
  • Convert wire:model.live to wire:model in forms (except search/filter fields)
  • Add .debounce.300ms to remaining wire:model.live bindings

Unsafe fixes (report only):

  • Moving queries out of render() (changes component behavior)
  • Reducing public properties (requires architectural changes)
  • Splitting monolithic components (major refactor)
  • Changing poll intervals (may affect functionality)
  • Removing large array properties (requires alternative data loading strategy)

For each safe fix, show before/after context. For --dry-run, display but do not apply.

Keep looking

Skills are one crate of 628,853. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.