Preconnect 到底该用在哪些域名上?
我在优化一个电商网站的首屏加载速度,听说 preconnect 能减少 DNS、TCP 和 TLS 的握手时间,就试着加了几个。但不确定是不是加多了反而有副作用?
比如我现在页面里用了 CDN 图片、第三方统计脚本、还有支付接口,这三个都加了 preconnect:
<link rel="preconnect" href="https://cdn.example.com" rel="external nofollow" >
<link rel="preconnect" href="https://analytics.vendor.com" rel="external nofollow" >
<link rel="preconnect" href="https://pay.gateway.com" rel="external nofollow" >
但 Lighthouse 报告说“避免不必要的 preconnect”,而且我注意到有些请求其实只在用户点击后才触发(比如支付),这种也需要提前连吗?到底怎么判断哪些值得 preconnect?
1. 关键资源优先,比如首屏必须加载的CDN资源,你加的
https://cdn.example.com是对的;2. 第三方脚本如果阻塞渲染(比如某些A/B测试工具),可以preconnect;
3. 交互后才触发的请求(比如支付接口)就别preconnect了,纯浪费;
你现在的配置里,支付网关那个可以去掉,用户点击支付按钮时才用的连接没必要提前建立。统计脚本要看具体情况,如果是异步加载不影响首屏的也可以去掉。
实测方法很简单:用Chrome DevTools的Performance面板记录加载过程,看哪些域名请求出现在关键渲染路径上。只给这些加preconnect就行,一般2-3个足够了。
代码可以这样优化:
注意加上crossorigin属性,特别是要加载跨域资源时。再提醒下,preconnect有效期很短(Chromium默认大概10秒),所以对首屏之后很久才用到的资源基本没用。
先说你这三个域名的情况:
cd.example.com 这种静态资源域名,如果图片、CSS、JS 是首屏就加载的,加 preconnect 没问题,甚至可以加 dns-prefetch 或 prefetch 一起配合用;
analytics.vendor.com 这种埋点脚本,如果是在首屏就自动发请求(比如 pageview 上报),那也值得 preconnect;但如果只是页面加载完几秒后才发请求,或者用户不滚动就不触发,那加了也没用,反而浪费连接池;
pay.gateway.com 这种明显是交互后才用的(用户点支付按钮才跳),千万别 preconnect,Lighthouse 说的“不必要的”基本就是指这类。
额外提醒几个坑:
preconnect 会提前建立 TCP 和 TLS 握手,占用浏览器的并发连接数(Chrome 默认每个域名最多 6 个连接),如果全站域名都 preconnect,可能把关键请求的连接数挤占了;
最好控制在 3 个以内,最多别超过 6 个;
可以结合用户行为做动态 preconnect,比如用户鼠标悬停在支付按钮上时,再动态插入 link 标签去 preconnect,这样更精准;
验证方式很简单:打开 Chrome DevTools 的 Network 面板,过滤 XHR 或 doc 类型,看哪些请求是首屏必须的,再结合 Lighthouse 的“减少关键请求深度”建议,优先处理那些延迟高、体积大、且跨域的资源。
最后说句实话,preconnect 不是万能药,很多情况下优化资源加载顺序、减少请求数、压缩体积比它更管用,别本末倒置。