本文目录导读:

- 方法 1:手动硬编码(最简单,适合小型项目)
- 方法 2:使用工具生成 + PHP 文件读取
- 方法 3:PHP 动态提取(纯 PHP 方案,适合动态页面)
- 方法 4:使用 PHP 库(推荐生产环境)
- 方法 5:使用 HTTP 缓存 + 定时生成关键 CSS
- 一个完整的生产示例
在 PHP 中处理关键 CSS(Critical CSS),通常是为了优化首屏加载速度,将首屏渲染所需的 CSS 直接内联到 HTML 的 <head> 中,而将剩余 CSS 异步加载。
下面介绍几种在 PHP 中实现关键 CSS 的常见方法:
方法 1:手动硬编码(最简单,适合小型项目)
直接在 PHP 模板中将关键 CSS 作为字符串写入。
<!DOCTYPE html>
<html>
<head>
<style>
/* 关键 CSS - 首屏样式 */
.header { background: #333; color: white; }
.hero { font-size: 2rem; padding: 20px; }
/* 这里放页面折叠线以上所需的样式 */
</style>
<!-- 非关键 CSS 异步加载 -->
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
</head>
优点:零依赖,完全可控
缺点:维护困难,适合极简页面或静态页面
方法 2:使用工具生成 + PHP 文件读取
这是最主流的生产方案,先用 Node.js 工具(如 critical、PurgeCSS)生成关键 CSS 文件,然后在 PHP 中读取并内联。
生成关键 CSS
npm install -g critical critical index.html --base . --width 1300 --height 900 > critical.css
PHP 读取文件并内联
<?php
$criticalCSS = file_get_contents(__DIR__ . '/critical.css');
?>
<!DOCTYPE html>
<html>
<head>
<style><?= $criticalCSS ?></style>
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="styles.css"></noscript>
</head>
优点:生成准确,性能好
缺点:需要构建工具配合,不能动态生成(除非每次请求都跑 Node)
方法 3:PHP 动态提取(纯 PHP 方案,适合动态页面)
如果你要处理 PHP 动态生成的页面(如 CMS),可以编写一个 PHP 函数来解析 CSS 文件并提取匹配选择器。
示例:简单提取器
<?php
function extractCriticalCSS($html, $cssFile) {
// 1. 从 HTML 中提取 class 和 id
preg_match_all('/class="([^"]+)"/', $html, $classes);
preg_match_all('/id="([^"]+)"/', $html, $ids);
$selectors = array_merge($classes[1], $ids[1]);
// 2. 解析 CSS 文件
$css = file_get_contents($cssFile);
$critical = '';
foreach ($selectors as $selector) {
// 简单正则匹配 .className 或 #idName { ... }
$pattern = '/[\.#]' . preg_quote($selector, '/') . '\s*\{[^}]*\}/';
preg_match_all($pattern, $css, $matches);
$critical .= implode("\n", $matches[0]);
}
return $critical;
}
$html = '<div class="header"><h1 id="title">Hello</h1></div>';
$criticalCSS = extractCriticalCSS($html, 'styles.css');
?>
<style><?= $criticalCSS ?></style>
注意:这个方案过于简单,实际项目建议使用 PHP CSS 解析库(如 sabberworm/php-css-parser)。
方法 4:使用 PHP 库(推荐生产环境)
方案 A:sabberworm/php-css-parser
composer require sabberworm/php-css-parser
<?php
use Sabberworm\CSS\Parser;
$css = file_get_contents('styles.css');
$parser = new Parser($css);
$document = $parser->parse();
// 你需要自己实现选择器匹配逻辑
// 或配合 DOMDocument 分析当前页面的 DOM
方案 B:用 V8js 扩展运行 JavaScript 工具(高级)
如果你的服务器安装了 v8js 扩展,可以直接在 PHP 中运行 critical 包:
$v8 = new V8Js();
$result = $v8->executeString('
// 这里加载 critical 包的 JavaScript 代码
// ... 运行 critical.generate()
');
方法 5:使用 HTTP 缓存 + 定时生成关键 CSS
对于动态页面但内容变化不频繁,可以使用缓存:
<?php
function getCriticalCSS($url) {
$cacheKey = md5($url);
$cacheFile = __DIR__ . "/cache/critical_{$cacheKey}.css";
if (file_exists($cacheFile) && time() - filemtime($cacheFile) < 3600) {
return file_get_contents($cacheFile);
}
// 调用 Node.js 脚本生成
$criticalCSS = shell_exec("node generate-critical.js {$url}");
file_put_contents($cacheFile, $criticalCSS);
return $criticalCSS;
}
| 场景 | 推荐方法 |
|---|---|
| 静态网站 | 方法2(构建时生成) |
| 小型动态网站 | 方法1 + 手动维护 |
| 大型 CMS | 方法3 + 缓存 + CSS 解析器 |
| 高性能要求 | 方法5(预生成 + CDN 缓存) |
| 不想碰 Node | 方法3 + sabberworm/php-css-parser |
千万不要做的事情:
- 不要用 PHP 每次请求都重新解析完整的 CSS 文件(性能灾难)
- 不要把所有 CSS 都内联(违背关键 CSS 原则)
一个完整的生产示例
<?php
// 1. 获取页面内容(可能是模板渲染结果)
ob_start();
// 你的页面渲染逻辑...
$pageHTML = ob_get_clean();
// 2. 从缓存获取关键 CSS
$cacheKey = 'crit_' . md5($_SERVER['REQUEST_URI']);
$criticalCSS = apcu_fetch($cacheKey);
if ($criticalCSS === false) {
// 使用 Node 子进程生成(推荐放到后台队列处理)
$criticalCSS = file_get_contents(__DIR__ . '/critical/critical.css');
apcu_store($cacheKey, $criticalCSS, 3600);
}
// 3. 注入到页面
$pageHTML = str_replace('</head>',
"<style>{$criticalCSS}</style></head>",
$pageHTML);
// 4. 输出
echo $pageHTML;
这样既能享受关键 CSS 的性能优化,又不会给 PHP 造成过大的计算负担。