本文目录导读:

- 方法 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 造成过大的计算负担。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播