Tips and techniques to maximize Diffyne performance.
// Good
$this->items = Item::limit(50)->get();
// Avoid
$this->items = Item::all(); // Could be thousands// Good
$this->posts = Post::with(['user', 'comments'])->get();
// Avoid - N+1 problem
$this->posts = Post::all();
// Then accessing $post->user in loop// Good
$this->users = User::select('id', 'name', 'email')->get();
// Avoid
$this->users = User::all(); // Loads all columnsuse Illuminate\Support\Facades\Cache;
public function loadStats()
{
$this->stats = Cache::remember('dashboard-stats', 60, function() {
return [
'users' => User::count(),
'posts' => Post::count(),
'revenue' => Order::sum('total'),
];
});
}{{-- Good - syncs once on submit --}}
<input diff:model.defer="name">
{{-- Avoid - syncs on every keystroke --}}
<input diff:model.live="name">{{-- Good - waits 300ms after typing stops --}}
<input diff:model.live.debounce.300="search">
{{-- Avoid - sends request on every keystroke --}}
<input diff:model.live="search">{{-- Good - reasonable interval --}}
<div diff:poll.5s="refresh">
{{-- Avoid - too frequent --}}
<div diff:poll.100ms="refresh">// Good - focused component
class TodoList extends Component
{
public array $todos = [];
public function addTodo() { /* ... */ }
}
// Avoid - too many responsibilities
class Dashboard extends Component
{
public array $todos, $users, $posts, $stats, $notifications;
// 20+ methods...
}// Good
public int $userId;
public function hydrate()
{
$this->user = User::find($this->userId);
}
// Avoid - serializing entire model
public User $user;// Good
public function getTotalPrice()
{
return array_sum(array_column($this->items, 'price'));
}
// Avoid - storing computed value
public float $totalPrice;
public function updated()
{
$this->totalPrice = array_sum(...);
}public function dehydrate()
{
unset($this->temporaryData);
unset($this->largeObject);
}The Virtual DOM handles this automatically, but you can help:
{{-- Good - conditional rendering --}}
@if($showDetails)
<div>...</div>
@endif
{{-- Avoid - always rendering hidden element --}}
<div class="{{ $showDetails ? '' : 'hidden' }}">...</div>@foreach($items as $item)
<li key="{{ $item['id'] }}">{{ $item['name'] }}</li>
@endforeach<img src="placeholder.jpg" data-src="{{ $image }}" loading="lazy">// Good - single request
public function deleteSelected()
{
Item::whereIn('id', $this->selectedIds)->delete();
}
// Avoid - multiple requests
foreach ($selectedIds as $id) {
// Triggers separate request per item
}Diffyne automatically minifies responses. Ensure gzip is enabled on your server.
Serve diffyne.js from CDN for better caching.
public function expensiveOperation()
{
$start = microtime(true);
// Your code here
$time = microtime(true) - $start;
logger("Operation took: " . $time . "s");
}DB::enableQueryLog();
$this->loadData();
$queries = DB::getQueryLog();
logger("Queries executed: " . count($queries));- Enable caching (
DIFFYNE_CACHE=true) - Disable debug mode (
DIFFYNE_DEBUG=false) - Optimize database queries
- Add database indexes
- Use deferred/debounced model binding
- Limit query results
- Eager load relationships
- Enable gzip compression
- Use CDN for static assets
- Monitor with Laravel Telescope/Debugbar
Typical operation times:
| Operation | Time |
|---|---|
| Counter increment | 50-80ms |
| Form submission | 100-200ms |
| Search query | 150-300ms |
| List update | 80-150ms |
Payload sizes:
| Operation | Payload |
|---|---|
| Counter increment | ~50 bytes |
| Todo add | ~150 bytes |
| Search results | ~500-2000 bytes |
- Virtual DOM - How Diffyne achieves small payloads
- Component State - State management
- Testing - Test your components