Laravel 13 性能优化指南
性能优化是提升用户体验和降低服务器成本的关键。本文将介绍 Laravel 13 的各种性能优化技巧。
配置缓存
缓存配置
1
| php artisan config:cache
|
缓存路由
缓存视图
缓存事件
清除缓存
1
| php artisan optimize:clear
|
数据库优化
查询优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| $posts = Post::with(['user', 'comments'])->get();
$users = User::select(['id', 'name', 'email'])->get();
User::chunk(1000, function ($users) { foreach ($users as $user) { } });
foreach (User::cursor() as $user) { }
|
索引优化
1 2 3 4 5 6 7 8
| Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('email')->unique(); $table->string('name'); $table->index(['name', 'email']); $table->index('created_at'); });
|
数据库连接池
1 2 3 4 5 6 7 8 9 10
| 'connections' => [ 'mysql' => [ 'driver' => 'mysql', 'pool' => [ 'max_connections' => 100, 'min_connections' => 10, ], ], ],
|
缓存策略
缓存查询结果
1 2 3 4 5 6 7 8 9 10 11 12
| use Illuminate\Support\Facades\Cache;
$users = Cache::remember('users.active', 3600, function () { return User::where('active', true)->get(); });
$stats = Cache::rememberForever('site.stats', function () { return [ 'users' => User::count(), 'posts' => Post::count(), ]; });
|
标签缓存
1 2 3
| Cache::tags(['users', 'posts'])->put('dashboard', $data, 3600);
Cache::tags(['users'])->flush();
|
原子锁
1 2 3 4 5 6 7 8 9 10 11
| use Illuminate\Support\Facades\Cache;
$lock = Cache::lock('process-order', 10);
if ($lock->get()) { try { } finally { $lock->release(); } }
|
队列优化
异步处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| use App\Jobs\ProcessPodcast; use App\Jobs\SendNotification;
ProcessPodcast::dispatch($podcast);
Bus::chain([ new ProcessPodcast($podcast), new SendNotification($user), ])->dispatch();
Bus::batch([ new ProcessFile(1), new ProcessFile(2), new ProcessFile(3), ])->dispatch();
|
队列配置
1 2 3 4 5 6 7 8 9 10
| 'connections' => [ 'redis' => [ 'driver' => 'redis', 'connection' => 'default', 'queue' => env('REDIS_QUEUE', 'default'), 'retry_after' => 90, 'block_for' => 5, ], ],
|
Eloquent 优化
延迟加载 vs 预加载
1 2 3 4 5 6 7 8 9 10 11
| $posts = Post::all(); foreach ($posts as $post) { echo $post->user->name; }
$posts = Post::with('user')->get(); foreach ($posts as $post) { echo $post->user->name; }
|
嵌套预加载
1 2 3 4 5
| $posts = Post::with(['user', 'comments.user'])->get();
$posts = Post::with(['user' => function ($query) { $query->select('id', 'name'); }])->get();
|
避免不必要的查询
1 2 3 4 5 6 7 8 9
| if ($user->posts()->exists()) { }
$users = User::whereHas('posts', function ($query) { $query->where('published', true); })->get();
|
视图优化
视图缓存
组件缓存
1 2 3 4 5 6 7 8 9 10 11 12 13
| use Illuminate\Support\Facades\Cache;
class RecentPostsComponent extends Component { public function render() { $posts = Cache::remember('recent.posts', 3600, function () { return Post::latest()->take(5)->get(); });
return view('components.recent-posts', compact('posts')); } }
|
资源优化
资源打包
资源预加载
1 2
| <link rel="preload" href="{{ asset('css/app.css') }}" as="style"> <link rel="preload" href="{{ asset('js/app.js') }}" as="script">
|
图片优化
1 2 3 4 5 6 7 8
| use Intervention\Image\Facades\Image;
$image = Image::make($file) ->resize(800, null, function ($constraint) { $constraint->aspectRatio(); $constraint->upsize(); }) ->encode('webp', 80);
|
OPcache 优化
PHP 配置
1 2 3 4 5 6 7
| opcache.enable=1 opcache.memory_consumption=256 opcache.interned_strings_buffer=16 opcache.max_accelerated_files=10000 opcache.validate_timestamps=0 opcache.revalidate_freq=0
|
预加载
1 2 3 4 5 6 7 8 9 10 11
| <?php
return [ 'enabled' => true, 'classes' => [ App\Models\User::class, App\Models\Post::class, App\Services\UserService::class, ], ];
|
Redis 优化
配置 Redis
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 'redis' => [ 'default' => [ 'url' => env('REDIS_URL'), 'host' => env('REDIS_HOST', '127.0.0.1'), 'password' => env('REDIS_PASSWORD'), 'port' => env('REDIS_PORT', '6379'), 'database' => env('REDIS_DB', '0'), 'options' => [ 'persistent' => true, 'read_timeout' => 60, ], ], ],
|
使用 Pipeline
1 2 3 4 5 6 7
| use Illuminate\Support\Facades\Redis;
Redis::pipeline(function ($pipe) { for ($i = 0; $i < 1000; $i++) { $pipe->set("key:{$i}", $i); } });
|
日志优化
条件日志
1 2 3 4 5 6
| if (app()->environment('local')) { Log::debug('Debug information', $data); }
Log::debug('User data', ['user' => fn() => $user->toArray()]);
|
日志级别
1 2
| 'level' => env('LOG_LEVEL', app()->environment('production') ? 'error' : 'debug'),
|
内存优化
使用生成器
1 2 3 4 5 6 7 8 9 10
| function getLargeDataset() { for ($i = 0; $i < 1000000; $i++) { yield $i; } }
foreach (getLargeDataset() as $item) { }
|
懒惰集合
1 2 3 4 5 6 7 8 9 10 11
| use Illuminate\Support\LazyCollection;
LazyCollection::make(function () { $handle = fopen('large-file.csv', 'r'); while ($line = fgets($handle)) { yield str_getcsv($line); } fclose($handle); })->chunk(1000)->each(function ($chunk) { });
|
监控和分析
性能分析
1 2 3 4 5 6 7 8 9 10 11
| use Illuminate\Support\Facades\DB;
DB::listen(function ($query) { if ($query->time > 100) { Log::warning('Slow query', [ 'sql' => $query->sql, 'bindings' => $query->bindings, 'time' => $query->time, ]); } });
|
调试栏
1
| composer require barryvdh/laravel-debugbar --dev
|
Telescope
1 2 3
| composer require laravel/telescope --dev php artisan telescope:install php artisan migrate
|
生产环境优化清单
部署前优化
1 2 3 4 5 6 7 8 9 10 11
| composer install --no-dev --optimize-autoloader
php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache
composer dump-autoload --optimize
|
环境配置
1 2 3 4 5 6 7 8 9 10 11
| APP_ENV=production APP_DEBUG=false APP_KEY=your-key
# 使用更快的缓存驱动 CACHE_DRIVER=redis QUEUE_CONNECTION=redis SESSION_DRIVER=redis
# 数据库连接池 DB_POOL_SIZE=10
|
性能测试
基准测试
1 2 3 4 5 6
| use Illuminate\Support\Benchmark;
Benchmark::dd([ 'Scenario 1' => fn () => User::with('posts')->get(), 'Scenario 2' => fn () => User::join('posts', 'users.id', '=', 'posts.user_id')->get(), ]);
|
负载测试
1 2 3 4 5
| ab -n 1000 -c 10 http://localhost/api/users
siege -c 10 -t 1M http://localhost/api/users
|
总结
Laravel 13 性能优化涉及多个方面,包括配置缓存、数据库优化、缓存策略、队列处理等。通过合理使用这些优化技巧,可以显著提升应用程序的性能。记住在生产环境中关闭调试模式、启用配置缓存、使用高效的缓存驱动,并持续监控应用程序的性能指标。性能优化是一个持续的过程,需要根据实际负载情况进行调整和改进。