| name | performance-guide |
| description | Performance optimization for PHP, JavaScript, databases, and caching strategies |
| license | MIT |
| compatibility | opencode |
| metadata | {"type":"optimization","languages":"php, javascript, sql"} |
Database Performance
N+1 Problem
Problem:
$users = User::all();
foreach ($users as $user) {
echo $user->profile->bio;
}
Solution - Eager Loading:
$users = User::with('profile')->get();
$qb->select('u', 'p')
->from(User::class, 'u')
->leftJoin('u.profile', 'p');
$query->select($db->quoteName(['u.*', 'p.bio']))
->from($db->quoteName('#__users', 'u'))
->leftJoin($db->quoteName('#__profiles', 'p') . ' ON p.user_id = u.id');
Select Only Needed Columns
$users = User::all();
$users = User::select(['id', 'name', 'email'])->get();
Indexing Strategy
CREATE INDEX idx_users_status ON users(status);
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_posts_created_at ON posts(created_at DESC);
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
Query Analysis
EXPLAIN SELECT * FROM users WHERE status = 'active';
Chunking Large Datasets
User::all()->each(fn($user) => process($user));
User::chunk(1000, function ($users) {
foreach ($users as $user) {
process($user);
}
});
User::lazy()->each(fn($user) => process($user));
PHP Performance
Avoid Computation in Loops
foreach ($items as $item) {
$count = count($items);
}
$count = count($items);
foreach ($items as $item) {
}
Use Appropriate Data Structures
$allowed = ['admin', 'moderator', 'user'];
if (in_array($role, $allowed)) { }
$allowed = ['admin' => true, 'moderator' => true, 'user' => true];
if (isset($allowed[$role])) { }
String Concatenation
$html = '';
foreach ($items as $item) {
$html .= '<li>' . $item . '</li>';
}
$parts = [];
foreach ($items as $item) {
$parts[] = '<li>' . $item . '</li>';
}
$html = implode('', $parts);
Generators for Large Data
function getUsers(): array
{
return User::all()->toArray();
}
function getUsers(): Generator
{
foreach (User::cursor() as $user) {
yield $user;
}
}
JavaScript/Vue Performance
Virtual DOM Optimization
<template>
<!-- Use v-once for static content -->
<header v-once>{{ staticTitle }}</header>
<!-- Use v-memo for expensive re-renders -->
<div v-memo="[item.id, item.selected]">
<ExpensiveComponent :item="item" />
</div>
<!-- Always key v-for -->
<div v-for="item in items" :key="item.id">
{{ item.name }}
</div>
</template>
Lazy Loading
const HeavyComponent = defineAsyncComponent(() =>
import('./HeavyComponent.vue')
)
const routes = [
{
path: '/dashboard',
component: () => import('./views/Dashboard.vue')
}
]
Debounce & Throttle
import { useDebounceFn, useThrottleFn } from '@vueuse/core'
const search = useDebounceFn((query: string) => {
fetchResults(query)
}, 300)
const scroll = useThrottleFn(() => {
updateScrollPosition()
}, 100)
Web Workers for Heavy Computation
self.onmessage = (e) => {
const result = heavyComputation(e.data)
self.postMessage(result)
}
const worker = new Worker('./worker.ts')
worker.postMessage(data)
worker.onmessage = (e) => {
result.value = e.data
}
Caching Strategies
Cache Layers
Request → Application Cache → Database Cache → Database
(Redis/Memcached) (Query Cache)
Laravel Example
$users = Cache::remember('users:active', 3600, function () {
return User::where('status', 'active')->get();
});
Cache::tags(['users'])->put("user:{$id}", $user, 3600);
Cache::tags(['users'])->flush();
$users = Cache::lock('users:lock')->block(5, function () {
return Cache::remember('users:all', 3600, fn() => User::all());
});
HTTP Caching Headers
return response($content)
->header('Cache-Control', 'public, max-age=3600')
->header('ETag', md5($content));
Profiling Tools
| Tool | Use Case |
|---|
| Xdebug | PHP step debugging & profiling |
| Blackfire | PHP performance profiling |
| Laravel Telescope | Request/query debugging |
| Symfony Profiler | Built-in profiling toolbar |
| Chrome DevTools | JS performance & network |
| Vue DevTools | Component render performance |
EXPLAIN ANALYZE | SQL query analysis |
Quick Wins Checklist