本文目录导读:

在 PHP 中实现 DNS 预取(DNS Prefetch)主要有两种方式,取决于你的具体需求:
HTML 层面的 DNS 预取(最常用)
在 PHP 生成的 HTML 中插入 完整的示例: 通过 HTTP 响应头实现 DNS 预取: 自动生成需要预取的域名: 对于更高级的需求,可以考虑: 根据你的具体场景选择合适的实现方式,HTML 方式就足够大多数情况使用了。
<link>
<?php
// 在 <head> 中添加 DNS 预取
function addDnsPrefetch($domain) {
echo '<link rel="dns-prefetch" href="//' . $domain . '">';
}
// 使用示例
addDnsPrefetch('cdn.example.com');
addDnsPrefetch('api.example.com');
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">My Site</title>
<?php
$dnsPrefetchDomains = [
'cdn.example.com',
'fonts.googleapis.com',
'ajax.googleapis.com',
'images.example.com'
];
foreach ($dnsPrefetchDomains as $domain) {
echo '<link rel="dns-prefetch" href="//' . $domain . '">' . PHP_EOL;
}
?>
</head>
<body>
<!-- 页面内容 -->
</body>
</html>
HTTP 头部方式(更高级)
<?php
// 在 PHP 脚本开始处设置
function setDnsPrefetchHeaders($domains) {
$link = '';
foreach ($domains as $domain) {
$link .= '<' . $domain . '>; rel=dns-prefetch, ';
}
// 移除末尾的逗号和空格
$link = rtrim($link, ', ');
header('Link: ' . $link);
}
// 使用示例
$domains = [
'https://cdn.example.com',
'https://fonts.googleapis.com',
'https://api.example.com'
];
setDnsPrefetchHeaders($domains);
?>
动态生成 DNS 预取
<?php
class DnsPrefetch {
private $domains = [];
public function addDomain($url) {
$parsedUrl = parse_url($url);
if (isset($parsedUrl['host'])) {
$this->domains[$parsedUrl['host']] = true;
}
}
public function render() {
foreach (array_keys($this->domains) as $domain) {
echo '<link rel="dns-prefetch" href="//' . $domain . '">' . PHP_EOL;
}
}
public function getHeaders() {
$links = [];
foreach (array_keys($this->domains) as $domain) {
$links[] = '<' . $domain . '>; rel=dns-prefetch';
}
return implode(', ', $links);
}
}
// 使用示例
$prefetch = new DnsPrefetch();
$prefetch->addDomain('https://cdn.example.com/images/logo.png');
$prefetch->addDomain('https://api.example.com/data');
$prefetch->addDomain('https://fonts.googleapis.com/css');
// 输出到 HTML
$prefetch->render();
// 或者设置 HTTP 头
header('Link: ' . $prefetch->getHeaders());
?>
性能优化建议
<?php
// 批量预取缓存域名
class DomainPrefetchOptimizer {
private static $defaultDomains = [
'cdn.domain.com',
'static.domain.com'
];
public static function getPrefetchTags() {
$html = '';
foreach (self::$defaultDomains as $domain) {
$html .= '<link rel="dns-prefetch" href="//' . $domain . '">' . PHP_EOL;
}
return $html;
}
// 只在特定页面添加额外预取
public static function conditionalPrefetch($pageType) {
$additionalDomains = [];
switch ($pageType) {
case 'product':
$additionalDomains[] = 'cdn.images.com';
$additionalDomains[] = 'product-api.com';
break;
case 'checkout':
$additionalDomains[] = 'payment-gateway.com';
$additionalDomains[] = 'shipping-api.com';
break;
}
return $additionalDomains;
}
}
// 在主模板中使用
echo DomainPrefetchOptimizer::getPrefetchTags();
foreach (DomainPrefetchOptimizer::conditionalPrefetch('product') as $domain) {
echo '<link rel="dns-prefetch" href="//' . $domain . '">' . PHP_EOL;
}
?>
注意事项
https:// 前缀现代替代方案
preconnect:比 dns-prefetch 更强,会建立 TCP 连接prefetch:预取整个资源preload:立即加载关键资源<?php
// preconnect 示例(比 dns-prefetch 更进阶)
function addPreconnect($domain) {
echo '<link rel="preconnect" href="//' . $domain . '">';
echo '<link rel="dns-prefetch" href="//' . $domain . '">';
}
?>