Laravel生产环境启动慢、接口卡顿的核心原因是缓存未启用、路由未编译、自动加载松散;必须执行config:cache和route:cache以固化配置与路由,跳过每次请求的重复解析,否则将额外增加5–15ms启动开销。

生产环境 Laravel 启动慢、接口响应卡、数据库查询反复执行——核心问题通常不是代码写得“不够优雅”,而是缓存没开、路由没编译、自动加载太松散。这些优化项不改业务逻辑,但能立竿见影压低 30%–70% 的首字节时间(TTFB)。
config:cache 和 route:cache 必须开,但不能乱开
这两个命令把 PHP 配置文件和路由注册逻辑固化成单个数组文件,跳过每次请求时的 require 和动态解析。没开它们,Laravel 每次都要扫描 config/ 下全部 PHP 文件、重跑 RouteServiceProvider::map(),白白多出 5–15ms 启动开销。
-
php artisan config:cache生成bootstrap/cache/config.php;它会忽略.env中未在配置文件里显式调用的变量(比如你写了APP_DEBUG=true但 config/app.php 里没用env('APP_DEBUG'),那这个值不会进缓存) -
php artisan route:cache只支持控制器方法路由,闭包路由(Route::get('/', function () { ... }))会直接报错退出;API 路由若用了Route::apiResource()默认是安全的 - 开了之后,改了
config/app.php或新增了routes/web.php里的路由,必须手动php artisan config:clear+php artisan config:cache,否则变更无效
避免 N+1 查询,with() 不等于万能解
Eloquent 的 with() 是防 N+1 的第一道防线,但它本身有陷阱:预加载了整张关联表,却只用其中一两个字段;或在循环里嵌套 with() 导致重复加载。
- 只取必要字段:
Post::with(['user:id,name,email'])->get(),避免拉回用户所有字段(尤其是password_hash这类敏感或大字段) - 条件性加载用
loadMissing():$post->loadMissing('author'),比无脑with()更省——它只在$post->author还没被加载过时才查库 - 不要在 Blade 模板循环里写
{{ $post->user->name }}同时又没预加载;Debugbar 的 “Queries” 面板里出现一串相同 SQL,基本就是 N+1 已发生
Redis 缓存 key 设计和过期时间不能拍脑袋
缓存失效策略写错,比不缓存还伤性能。硬编码 key 或统一设 24 小时过期,轻则缓存雪崩,重则返回脏数据。
- key 必须带可变因子:
Cache::remember('posts_list_'.$request->input('category').'_'.$request->input('page'), 3600, ...),否则不同分类请求全打到同一个 key 上 - 过期时间按数据更新频率分级:用户个人资料缓存 10 分钟,站点全局配置缓存 1 小时,热门文章列表缓存 15 分钟——别全用
3600 - 慎用
Cache::forever():Redis 内存有限,长期不淘汰的 key 会挤占空间;真要永久缓存,得配合事件监听(如模型saved事件触发Cache::forget())
composer dump-autoload --classmap-authoritative 是隐藏提速点
默认 Composer 自动加载靠 PSR-4 规则实时扫描目录,生产环境没必要。启用权威类映射后,它直接查一个静态数组找类路径,跳过全部文件系统 stat() 调用。
- 执行
composer dump-autoload --classmap-authoritative --optimize-autoloader,生成vendor/composer/autoload_classmap.php - 部署时加
--no-dev:composer install --no-dev --optimize-autoloader,删掉 phpunit、debugbar 这些开发依赖的自动加载项 - 检查
composer.json的autoload.files是否塞了几十个工具函数文件——每个都会被require_once,应只留真正高频、无命名空间的辅助函数
最常被跳过的其实是缓存失效逻辑:你以为缓存设了 1 小时就万事大吉,但用户编辑文章后,相关列表缓存、详情缓存、搜索缓存是否同步失效?这比怎么设缓存更难搞对。



















