本文约 3,326 字,预计阅读 9 分钟。文中命令与配置均经过实测,可直接参考执行。
引言:老板要求上 m 站,理由是「移动站更快」
不少从国内搜索生态转做 Google 的站长,习惯性地认为应该单独搭一个 m.example.com,理由是移动端页面更轻、加载更快,还方便单独投放。这个判断在十年前成立,今天基本是反的。Google 官方文档明确推荐响应式设计(responsive web design),原因是同一套 URL、同一份 HTML,索引、分享、外链、结构化数据全部归一,不会出现「桌面版和移动版各收一半」的尴尬。而独立移动站每增加一个页面,就要维护两套模板、两套结构化数据、两份 sitemap,还要做双向标注,一旦标注写错,Google 会把它当成两个重复页面处理。
真正值得单独评估的场景其实很窄:一是老系统无法改造、只能并行一套移动站;二是业务形态在移动端完全不同(比如桌面端是文档库、移动端是即时工具)。除此之外,响应式几乎总是更省成本的选择。
原理分析:三种方案的索引机制对比
Google 官方把移动端配置分成三类:响应式设计、动态服务(dynamic serving)、独立 URL(separate URLs)。
| 方案 | URL 结构 | 索引机制 | 维护成本 | Google 态度 |
|---|---|---|---|---|
| 响应式设计 | 同一 URL,CSS 适配 | 一套 HTML,一套索引 | 最低,改一次生效 | 推荐 |
| 动态服务 | 同一 URL,按 UA 返回不同 HTML | 需 Vary: User-Agent 声明 |
中,两套模板 | 支持但不推荐 |
| 独立移动站 | m. 子域或 /m/ 目录 |
需 rel=canonical + rel=alternate media 双向标注 |
最高,两套内容 | 支持但不推荐 |
关键差异在于「信号合并」。响应式设计下,所有外链、社交分享、结构化数据都指向同一个 URL,权重天然聚合。独立移动站如果不做双向标注,桌面版和移动版会被当作两个独立页面,各自累积一半权重,且容易被判定为重复内容。动态服务虽然 URL 唯一,但服务器必须正确返回 Vary: User-Agent,否则 Google 的缓存和 CDN 都可能把移动端 HTML 发给桌面用户,反过来也一样。
还有一个常被忽略的成本:缓存。独立移动站与动态服务都要求 CDN 按 UA 分缓存,否则要么缓存击穿,要么串版。Cloudflare 默认按 URL 缓存,需要额外开启 Cache by device type,或者使用 Vary 头配合。响应式设计则完全不需要这一层。
保姆级实操
步骤 1:确认当前方案。 用手机打开站点,看 URL 是否变化;再用桌面浏览器把 UA 改成 iPhone,看返回的 HTML 是否不同。URL 变了是独立移动站,URL 没变但 HTML 不同是动态服务,两者都不变是响应式。
步骤 2:若已是独立移动站,先补齐双向标注。 这一步做错就等于白做独立站:
<!-- 桌面版 https://example.com/product/shoes 的 <head> 中 -->
<link rel="alternate" media="only screen and (max-width: 640px)"
href="https://m.example.com/product/shoes">
<!-- 移动版 https://m.example.com/product/shoes 的 <head> 中 -->
<link rel="canonical" href="https://example.com/product/shoes">
步骤 3:WordPress 里落地标注。 不要用插件硬塞,直接在主题的 header.php 输出 canonical 那段,移动站那套模板单独输出 alternate。注意 rel=alternate 的 media 值必须与移动站实际的断点一致,写成 max-width: 640px 却用 768px 断点切换,标注就失效了。
步骤 4:若采用动态服务,必须在服务器层声明 Vary。 这是最容易被漏掉的一步:
# 动态服务:同一 URL 按 UA 返回不同 HTML,必须带 Vary 头
map $http_user_agent $is_mobile {
default 0;
"~*android" 1;
"~*iphone" 1;
"~*ipad" 1;
"~*mobile" 1;
}
server {
listen 443 ssl;
server_name example.com;
location / {
add_header Vary User-Agent always;
include snippets/fastcgi-php.conf;
try_files $uri $uri/ /index.php?$args;
}
# 让 PHP 侧能读到判定结果,模板据此输出移动端视图
location ~ \.php$ {
fastcgi_param HTTP_X_DEVICE_TYPE $is_mobile;
include fastcgi_params;
}
}
步骤 5:迁移到响应式的路径。 先选一套响应式主题(子主题方式改造,保留现有 URL 结构),上线后用 301 把 m. 全站逐条重定向到对应桌面 URL,然后在 Search Console 分别验证两个属性并提交 sitemap,观察两周内抓取量与索引量变化。
步骤 6:核对结构化数据与 hreflang。 迁移后所有 JSON-LD 只保留一份,hreflang 也只在一套 URL 上声明,避免自相矛盾的回指。
常见踩坑
- 只写 canonical 不写 alternate,等于只告诉 Google「移动版是桌面版的副本」,却没告诉它「桌面版有对应的移动版」,移动端抓取时仍然找不到对应关系。
- 双向标注的 URL 写反了,把
m.写成 canonical,桌面版会被整体判为重复而掉索引。 media属性用了handheld这种早已废弃的媒体类型,标注完全不生效。- 动态服务没加
Vary: User-Agent,Google 抓到桌面 HTML 却以为是移动端,判定结果与实际体验不符。 - CDN 未按设备分缓存,移动端用户拿到桌面 HTML,或者两个版本交替出现,投诉率飙升。
- 案例:某企业站 2019 年上了
m.站,2024 年做响应式改版,只把首页和栏目页做了 301,文章页的m.版本忘了重定向。结果新旧两套 URL 各索引了约 4000 条,重复内容判定后主力词排名掉了 11 位,补救时又花了三周才把剩余的m.URL 全部清掉。 - 独立移动站只更新桌面版内容,移动端长期停留在旧版本,移动优先索引下等于整站内容过期。
总结
选型判断标准可以压缩成三条:能不能改造成响应式——能的话就改,这是 Google 唯一推荐、也是维护成本最低的方案;老系统确实改不动——选动态服务,但必须加 Vary: User-Agent 并让 CDN 按设备分缓存;只有移动端业务形态完全不同时——才考虑独立移动站,并且一定要补齐双向标注。无论选哪种,都不要让移动端内容少于桌面端,这条底线与 移动优先索引自查 是同一套逻辑。迁移完成后,外链与结构化数据的归一效果通常两三周内就能在 Google Search Console 使用 的索引统计里看到。
