config:cache 和 route:cache 是 laravel 性能第一道门槛,必须在生产环境启用;未缓存时需动态加载二十多个配置文件并解析路由,缓存后仅读取单个 config.php 和 routes-v7.php 文件,可将启动时间从 20ms 压至 3ms。

config:cache 和 route:cache 必须在生产环境启用,否则 Laravel 每次请求都会重复解析全部配置和路由文件,启动开销直接翻倍。
为什么 config:cache 和 route:cache 是性能第一道门槛
没缓存时,Laravel 要 require 二十多个 config/*.php 文件、再执行 RouteServiceProvider 动态注册所有路由;缓存后,只读一个 bootstrap/cache/config.php 和 bootstrap/cache/routes-v7.php —— 这不是“锦上添花”,而是从 20ms 启动时间压到 3ms 的硬性操作。
- 仅启用
config:cache就能减少约 40% 的配置加载耗时 -
route:cache对中大型项目效果更明显,尤其当路由数超 200 条时,匹配速度提升常达 5 倍以上 - 闭包路由(
Route::get('/', function () { ... }))不支持缓存,必须改写为控制器方法 - 修改任何配置或路由后,必须手动运行
php artisan config:clear或php artisan route:clear,否则变更不生效
with() 预加载不是“用了就行”,得看关联深度和字段粒度
with() 解决 N+1 是基础,但滥用会导致“查得多、用得少”——比如 Post::with('user.posts.comments')->get() 一次拉出三层嵌套,实际页面只显示用户名,其余全浪费。
- 只预加载真正需要的关联:用
with('user:id,name,avatar')限定字段,避免整张 users 表被 SELECT * - 多层嵌套慎用
with(),优先考虑分步查询或 API 分页聚合 - 对大列表页,用
loadMissing()替代全量预加载,按需补数据 - 用
DB::enableQueryLog()+dd(DB::getQueryLog())确认是否真减少了查询次数,别凭感觉
缓存键设计不当,比不缓存还危险
缓存失效逻辑混乱、键名无区分度,会导致用户看到别人的数据,或缓存永远不更新。这不是性能问题,是数据一致性事故。
- 别用固定字符串做键:
Cache::remember('posts', 3600, ...)—— 所有用户共享同一份热门文章 - 带上下文:登录用户 ID、角色、地域等关键维度要进键名,例如
'posts_homepage_user_'.$userId - 避免在循环里调用
Cache::get(),先批量查数据库再统一塞缓存,或用Cache::many() - 用 Redis 的
cache tags(需开启redis驱动并配置cache.tags)批量失效,比遍历 key 更可靠
OPcache 和 Composer autoloader 优化不是“部署脚本里加两行”就完事
PHP 层的优化容易被忽略,但它影响的是每个请求的底层执行效率,尤其在高并发下收益极明显。
-
opcache.validate_timestamps=0在生产环境必须关闭,否则每次请求都检查 PHP 文件修改时间,白费 OPcache -
composer dump-autoload --classmap-authoritative生成绝对路径类映射,跳过 PSR-4 自动扫描,类加载快 30%+ - 确保
autoload.files和autoload.classmap只包含真实需要的文件,冗余项会拖慢整个 autoloader -
APP_DEBUG=true会禁用部分缓存机制并加载调试类,生产环境务必设为false,且不能靠 .env 覆盖 —— 要确认最终值











