关掉yii_debug、启用schemacache、将cache换为redis,三步可使多数项目首屏提速40%以上;需确保调试模式真正关闭、schemacache指向有效缓存组件、redis配置正确且无锁竞争。

页面加载慢不是 Yii 本身的问题,而是缓存没开、查询没压、配置还停在开发模式——关掉 YII_DEBUG、启用 schemaCache、把 cache 换成 Redis,这三步做完,多数项目首屏能快 40% 以上。
关掉调试模式并确认生产环境配置生效
调试模式开着时,Yii 会记录 SQL、堆栈、变量快照,每个请求多花 20–30ms,高并发下直接拖垮响应。关键不是“设了没”,而是“有没有被覆盖”。
-
index.php顶部必须有defined('YII_DEBUG') or define('YII_DEBUG', false);,且不能被后续 config 文件重置 - 检查
Yii::getLogger()->getTargets()是否还有FileTarget在写日志;高频日志 I/O 是隐形瓶颈 - OPcache 必须启用:
opcache.enable=1且opcache.revalidate_freq=0(生产环境禁用脚本变更检测)
启用并验证 schemaCache 是否真正起作用
ActiveRecord 每次新建模型都会查一次 information_schema,10 个模型 = 10 次元数据查询。不配 schemaCache,等于每天白跑几百条无意义 SELECT。
- 在
db组件里明确写'enableSchemaCache' => true,光设schemaCacheDuration不生效 -
schemaCache必须指向一个已启用的缓存组件(比如'schemaCache' => 'cache'),否则自动退化为无缓存 - 用
Yii::$app->db->getSchema()->getTableSchema('user')手动调一次,再看 Redis 或 APCu 里有没有schemacache:开头的 key
把 FileCache 换成 Redis 并避免缓存锁竞争
FileCache 在 Linux 下高并发写入会触发文件锁,flock() 等待导致请求排队;DbCache 若没给 cache_key 字段建索引,查缓存就变全表扫描。
- 替换
cache组件类为yii\redis\Cache,别只改 class 名,还要配'keyPrefix' => 'prod_'隔离环境 - 如果还在用
DbCache,立刻在cache表上执行:CREATE INDEX idx_cache_key ON cache (cache_key); - FragmentCache 的
duration别设为 0;设了 0 又不手动invalidate(),缓存永不更新,页面就卡在旧数据
消灭 N+1 查询:with() 不是可选项,是必填项
列表页里循环写 $order->user->name,就是典型的 N+1:1 次主查 + N 次关联查。哪怕只有 20 条数据,也多发 20 次 SQL。
- 控制器中必须显式预加载:
Order::find()->with(['user', 'items.product'])->all(),而不是靠 getter 触发懒加载 - 深层关联如
order→user→profile→avatar,用with(['user.profile.avatar'])一行展开,不要嵌套 with - 纯数据展示场景加
asArray():->asArray()->all(),跳过 ActiveRecord 对象构造,内存和 CPU 都省 15%+
最常被忽略的一点:缓存组件配了,但 schemaCache 指向的 cache 组件自己却没启用——这种“缓存套缓存失效”的链路问题,得逐层 var_dump(Yii::$app->get('cache')) 看实例状态,不能只信配置文件。











