frankenphp 开 early hints 对 laravel 几乎无实际收益,因其不自动解析 html 或推送资源,需手动在响应体生成前触发 103 并写入 link 头,而 laravel 渲染机制与执行时机使其极难落地;更有效的优化是 opcache 预加载、worker 常驻、静态资源直供、http/3 及基础配置调优。

FrankenPHP 开 Early Hints 对 Laravel 页面几乎没有实际收益,除非你明确在应用层主动触发 103 Early Hints 并配合前端资源预加载逻辑。
Early Hints 不是自动开启的优化项
很多人误以为开启 early_hints 配置后,FrankenPHP 会自动分析 HTML、提取 <link rel="stylesheet"> 或 <script></script> 并发推送。事实并非如此:FrankenPHP(包括 Caddy 底层)只提供发送 103 响应的能力,它不会解析 PHP 输出内容,也不会自动做资源发现或预加载决策。
这意味着:Laravel 默认渲染流程中,103 完全不会被发出——除非你在控制器、中间件或视图渲染前手动调用 header('HTTP/1.1 103 Early Hints') 并写入 Link 头。
- FrankenPHP 的
http.early_hints配置只是“允许发送”,不是“自动发送” - Laravel 框架本身不感知 Early Hints,
response()、view()、Blade 渲染均不触发它 - 浏览器只有收到
103+ 合法Link: /app.css>; rel=preload; as=style才会提前发起请求
Laravel 场景下手动加 Early Hints 很难落地
你想在 Laravel 中真正用上 Early Hints,得解决三个硬性前提,而它们在实践中几乎不可靠:
- 必须在响应主体(HTML)生成前就确定所有关键资源路径——但 Laravel 的
@vite、@routes、@stack、服务注入的 JS/CSS 都在视图渲染阶段才确定 - 无法在中间件里安全写
103:一旦输出任何内容(包括空格、BOM、错误日志),HTTP 头就已发送,再发103会报错headers already sent - 如果你用 Octane + FrankenPHP worker 模式,
103更容易失败——因为响应生命周期由 Octane 控制,FrankenPHP 的 early_hints 钩子可能被绕过
实测中,哪怕强行在 AppServiceProvider::boot() 里调用 header(),也大概率因 Laravel 内部缓冲或输出顺序问题被忽略或报错。
比 Early Hints 更有效且开箱即用的替代方案
对 Laravel 页面加载速度有真实影响的,是那些能立即生效、无需改代码、也不依赖浏览器支持率的功能:
-
opcache.preload+opcache.enable_cli=1:减少每次请求的 PHP 文件编译开销,Laravel 框架类加载快 40%+ - FrankenPHP 的
workers.max_requests设为0(无限)+hot_reload: false:让框架 bootstrap 常驻内存,避免重复初始化容器和服务提供者 - 静态资源走 Caddy 原生
file_server路由,跳过 PHP 层:CSS/JS/图片直接由 FrankenPHP(Caddy)返回,不进 Laravel 生命周期 - HTTP/3 启用:FrankenPHP 默认支持,只需 TLS 配置正确,对首屏资源并行加载提升明显,且无需修改任何 PHP 代码
这些才是 FrankenPHP 在 Laravel 环境里真正能“开箱即用”的性能杠杆。Early Hints 属于边缘优化,需要深度定制渲染链路,投入产出比极低。
真要压榨那几十毫秒,优先检查 APP_DEBUG=true 是否关了、config:cache 和 route:cache 是否跑了、DB 查询有没有 N+1——这些地方的收益,远超折腾一个几乎没人用的 103 响应头。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











