文/ 天机阁首席性能优化师
(云端之上,紫袍道人手持星盘,星盘中映射出无数域名光点)
"今日传授尔等DNS预解析大法。须知域名解析,如同叩开仙门,需未雨绸缪方能瞬息而至。且看这三界寻址术------"
第一章:DNS三界境界
凡界:被动解析
html
<!-- 传统解析方式 -->
<a href="https://api.immortal.com">进入仙门</a>
<!-- 首次访问需经历:
1. DNS查询(50-300ms)
2. TCP握手(1 RTT)
3. TLS协商(1-2 RTT)
-->
灵界:主动预解析
html
<!-- 预解析之术 -->
<link rel="dns-prefetch" href="//cdn.taoist.org">
<link rel="preconnect" href="https://fonts.immortal.com" crossorigin>
<!-- 效果:
- dns-prefetch:提前解析DNS(节省50-300ms)
- preconnect:提前建立连接(节省1-2 RTT)
-->
仙界:资源预加载
html
<!-- 终极预加载 -->
<link rel="prefetch" href="//static.taoist.org/main.js" as="script">
<link rel="preload" href="//fonts.taoist.org/dao.woff2" as="font" crossorigin>
<!-- 区别:
- prefetch:低优先级预加载(空闲时加载)
- preload:高优先级立即加载
-->
第二章:预解析九式
第一式:开天眼(识别关键域名)
javascript
// 自动检测页面中的域名
function findCriticalDomains() {
const domains = new Set();
// 收集所有外部资源链接
document.querySelectorAll('a[href^="http"], img[src^="http"]').forEach(el => {
const url = new URL(el.href || el.src);
if (url.hostname !== location.hostname) {
domains.add(url.hostname);
}
});
return Array.from(domains);
}
第二式:刻符咒(动态插入预解析)
javascript
// 动态添加dns-prefetch
function addPrefetchLinks(domains) {
const head = document.head;
domains.forEach(domain => {
const link = document.createElement('link');
link.rel = 'dns-prefetch';
link.href = `//${domain}`;
head.appendChild(link);
});
}
第三式:分阴阳(区分关键/非关键)
html
<!-- 关键域名:立即预连接 -->
<link rel="preconnect" href="https://api.daoist.com">
<link rel="preconnect" href="https://cdn.daoist.com" crossorigin>
<!-- 非关键域名:仅DNS预解析 -->
<link rel="dns-prefetch" href="//analytics.daoist.com">
<link rel="dns-prefetch" href="//third-party.ad.com">
第四式:借东风(HTTP头部控制)
http
Link: <https://static.daoist.com>; rel=preconnect; crossorigin
Link: <https://fonts.daoist.com>; rel=dns-prefetch
nginx
# Nginx配置示例
location / {
add_header Link "</static/main.js>; rel=preload; as=script";
add_header Link "</style.css>; rel=preload; as=style";
}
第五式:观星象(性能监控)
javascript
// 测量DNS查询时间
const timing = performance.getEntriesByType('resource').map(res => {
return {
name: res.name,
dnsTime: res.domainLookupEnd - res.domainLookupStart,
connectTime: res.connectEnd - res.connectStart
};
});
console.table(timing);
第六式:布结界(安全防护)
html
<!-- 仅预解析可信域名 -->
<link rel="dns-prefetch" href="//trusted.cdn.com">
<!-- 不预解析的潜在风险域名 -->
<meta http-equiv="x-dns-prefetch-control" content="off">
第七式:调四时(智能触发)
javascript
// 滚动到可视区域时预解析
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const domain = new URL(entry.target.href).hostname;
addPrefetch([domain]);
}
});
});
document.querySelectorAll('a[data-prefetch]').forEach(link => {
observer.observe(link);
});
第八式:炼金丹(CDN优化)
javascript
// 动态获取最优CDN节点
function getOptimalCDN() {
return fetch('/api/cdn-endpoint')
.then(res => res.json())
.then(data => {
const link = document.createElement('link');
link.rel = 'preconnect';
link.href = `https://${data.nearestNode}`;
document.head.appendChild(link);
return data.nearestNode;
});
}
第九式:渡劫飞升(协议升级)
html
<!-- HTTP/2 Server Push -->
<link rel="preload" href="/static/main.js" as="script">
<!-- 配合服务端推送 -->
第三章:优化心法
arduino
"DNS优化五要:
1️⃣ 关键性(区分核心/非核心资源)
2️⃣ 预见性(提前解析可能访问的域名)
3️⃣ 安全性(避免恶意域名预解析)
4️⃣ 动态性(根据用户行为智能调整)
5️⃣ 度量性(持续监控优化效果)"
第四章:实战演练
完整实施方案
html
<!DOCTYPE html>
<html>
<head>
<!-- 核心域名预连接 -->
<link rel="preconnect" href="https://api.daoist.com">
<link rel="preconnect" href="https://static.daoist.com" crossorigin>
<!-- 次要域名DNS预解析 -->
<link rel="dns-prefetch" href="//analytics.secure.com">
<link rel="dns-prefetch" href="//cdn.thirdparty.org">
<!-- 关键资源预加载 -->
<link rel="preload" href="/css/main.css" as="style">
<link rel="preload" href="/js/app.js" as="script">
<!-- 动态预解析控制 -->
<meta http-equiv="x-dns-prefetch-control" content="on">
<script>
// 异步加载非关键预解析
window.addEventListener('load', () => {
const prefetchDomains = [
'//img.daoist.com',
'//comment.daoist.com'
];
prefetchDomains.forEach(domain => {
const link = document.createElement('link');
link.rel = 'dns-prefetch';
link.href = domain;
document.head.appendChild(link);
});
});
</script>
</head>
<body>
<!-- 内容 -->
</body>
</html>
高级智能预加载
javascript
class IntelligentPrefetcher {
constructor() {
this.observedLinks = new Set();
this.observer = new IntersectionObserver(this.handleIntersection.bind(this));
}
handleIntersection(entries) {
entries.forEach(entry => {
if (entry.isIntersecting) {
const url = new URL(entry.target.href);
this.prefetchResources(url);
this.observer.unobserve(entry.target);
}
});
}
prefetchResources(url) {
// DNS预解析
const dnsLink = document.createElement('link');
dnsLink.rel = 'dns-prefetch';
dnsLink.href = `//${url.hostname}`;
document.head.appendChild(dnsLink);
// 预连接(仅限主域名)
if (url.hostname === 'api.daoist.com') {
const preconnect = document.createElement('link');
preconnect.rel = 'preconnect';
preconnect.href = url.origin;
document.head.appendChild(preconnect);
}
}
watch(selector) {
document.querySelectorAll(selector).forEach(link => {
if (!this.observedLinks.has(link.href)) {
this.observer.observe(link);
this.observedLinks.add(link.href);
}
});
}
}
// 使用示例
const prefetcher = new IntelligentPrefetcher();
prefetcher.watch('a[data-prefetch]');
第五章:优化禁忌
魔道案例
html
<!-- 错误:过度预解析 -->
<link rel="dns-prefetch" href="//ad.dubious-site.com">
<link rel="dns-prefetch" href="//tracker.shady-network.com">
<!-- 错误:关键资源未预加载 -->
<script src="/js/critical.js"></script> <!-- 阻塞渲染 -->
正道解法
html
<!-- 正确:安全可控的预解析 -->
<meta http-equiv="x-dns-prefetch-control" content="on">
<link rel="dns-prefetch" href="//trusted-cdn.com">
<!-- 正确:关键资源预加载 -->
<link rel="preload" href="/js/critical.js" as="script">
<body>
<!-- 其他内容 -->
<script src="/js/critical.js" defer></script>
</body>
(突然星盘震动,出现DNS污染异象)
弟子:"师尊!预解析的CDN域名被劫持了!"
道人:"莫慌!且看这招安全防护大法------"
道人掐诀念咒,星盘中浮现防护代码:
javascript
// 安全预解析验证
function safePrefetch(domain) {
return fetch(`/api/verify-domain?domain=${encodeURIComponent(domain)}`)
.then(res => res.json())
.then(data => {
if (data.trusted) {
const link = document.createElement('link');
link.rel = 'dns-prefetch';
link.href = `//${domain}`;
document.head.appendChild(link);
}
});
}
// 只预解析白名单域名
const allowedDomains = ['static.daoist.com', 'api.daoist.com'];
allowedDomains.forEach(safePrefetch);
飞升天象:
当DNS优化修炼至大乘期,可:
- 实现0ms DNS缓存命中率
- 关键资源加载时间缩短50%
- 支持智能预测用户行为
- 抵御DNS劫持攻击
(道人化作星光,融入星盘之中,浮现最后箴言)
"记住,优化之道在于'恰到好处'。如同春雨润物,既不可不足,亦不可过度......"
(星盘展开,化作《DNS优化真经》)
<真经展开,显现完整优化知识图谱> <第二元神显化:关注天机阁,解锁更多性能秘法>
核心难点解析
- 技术选择矩阵
graph TD
A[资源类型] -->|静态CDN| B(dns-prefetch)
A -->|API接口| C(preconnect)
A -->|关键JS/CSS| D(preload)
A -->|下页资源| E(prefetch)
- 性能对比数据
javascript
// 不同技术的收益对比
const optimizationStats = {
dnsPrefetch: {
latencySaved: '50-300ms',
memoryImpact: '低',
bestFor: '跨域第三方资源'
},
preconnect: {
latencySaved: '1-2 RTT',
memoryImpact: '中',
bestFor: '核心API/CDN'
},
preload: {
latencySaved: '100-500ms',
memoryImpact: '高',
bestFor: '首屏关键资源'
}
};
- 智能预测算法
javascript
// 基于用户行为的预测
class PredictivePrefetcher {
constructor() {
this.visitedPaths = new Map();
}
trackPage(path) {
const count = this.visitedPaths.get(path) || 0;
this.visitedPaths.set(path, count + 1);
}
getNextLikelyPaths() {
return Array.from(this.visitedPaths.entries())
.sort((a, b) => b[1] - a[1])
.slice(0, 3)
.map(([path]) => path);
}
prefetchForPath(path) {
const resources = {
'/shop': ['//static.daoist.com/shop.js', '//api.daoist.com/products'],
'/blog': ['//static.daoist.com/blog.css', '//cdn.daoist.com/comments.js']
};
(resources[path] || []).forEach(url => {
const domain = new URL(url).hostname;
addPrefetch(domain);
});
}
}
- 跨浏览器方案
javascript
// 浏览器特性检测与降级
function setupOptimizations() {
// 检测支持情况
const supportsPreload = 'relList' in document.createElement('link') &&
document.createElement('link').relList.supports('preload');
const supportsPrefetch = 'relList' in document.createElement('link') &&
document.createElement('link').relList.supports('prefetch');
// 根据支持情况应用优化
if (supportsPreload) {
// 现代浏览器方案
preloadCriticalResources();
} else if (supportsPrefetch) {
// 降级方案
prefetchFallbacks();
} else {
// 最简方案
basicDnsPrefetch();
}
}
- 安全防护措施
javascript
// CSP策略配合
const cspHeader = `
default-src 'self';
connect-src 'self' api.daoist.com static.daoist.com;
script-src 'self' 'unsafe-inline' static.daoist.com;
style-src 'self' 'unsafe-inline' fonts.daoist.com;
img-src 'self' data: cdn.daoist.com;
font-src fonts.daoist.com;
report-uri /csp-violation-report;
`;
// 在Nginx中配置
add_header Content-Security-Policy $csp_header;