暗黑模式访客地图排障记录
问题背景
首页左侧使用了第三方 MapMyVisitors 访客地图组件。
明亮模式下显示正常,但暗黑模式连续出现了这些问题:
- 地图看起来只有海洋和少量访客点,陆地几乎消失。
- 地图外层容器、内层地图区域、海洋底色之间有明显分层。
- 暗黑模式下绿色访客点不够清楚。
- 用户要求只修暗黑模式,明亮模式保持不变。
表面看这像是一次普通调色,但后续排查证明,根因不只是颜色值。
最初现象
用户的反馈很集中:
- 暗黑模式看不到陆地。
- 刷新后问题依然存在。
- 明亮模式没有问题。
这组现象说明问题大概率不在全站主题切换逻 辑,而在这个第三方组件自己的暗黑渲染路径里。
如果是全局主题或页面布局的问题,亮色模式通常也会被波及。但这里亮色模式一直正常,所以排查重点需要收缩到组件本身。
第一轮排查:先排除本地样式覆盖
先检查了首页相关文件:
src/pages/index.jssrc/pages/index.module.css
重点看了几类风险点:
- 有没有对地图做
filter - 有没有对地图做反色、亮度、对比度处理
- 有没有全局 SVG 样式误伤第三方地图内部节点
结果是:
- 本地样式主要只是圆角、边框、背景和阴影。
- 没有会直接把陆地盖掉的滤镜。
- 没有发现明显的全局样式误伤。
这一轮的结论是:问题不像是“我们自己的 CSS 把地图遮住了”,更像是第三方地图组件自身在暗黑模式下没有稳定把陆地表现出来。
第二轮排查:确认第三方脚本参数到底控制什么
首页里这个组件通过切换脚本 URL 参数来区分亮暗模式,参数包括:
clcoctcmocmn
最初可以猜测:
cl对应 land,也就是陆地co对应 ocean,也就是海洋
但不能只靠命名猜,因为第三方服务未必完全按直觉工作。
所以后续改成直接读取第三方脚本源码和生成结果来验证。
第三轮排查:读取 map.js 源码
通过抓取第三方 map.js 源码,发现这个组件不是单纯靠一层 SVG 把世界地图完整画出来,而是分成了两层。
第一层是背景图层。
脚本里会根据参数生成一个背景图地址,形式类似:
//mapmyvisitors.com/generated_content/backs/bg-w_320-co_xxxxxx-cl_xxxxxx.png
这说明:
co和cl会先生成一张底图 PNG- 这张图负责最底层的海洋和陆地
第二层是动态层。
脚本随后又会异步请求 widget_call_home.js,再用 jvectormap 在上层绘制:
- 地图交互层
- 访客点
- 标签和统计内容
关键结论是:
陆地可见性并不完全取决于上层 SVG 是否存在,更取决于底层背景图是否稳定加载,以及陆地和海洋之间是否 有足够对比。
这也解释了用户看到的现象:上层访客点还能出现,但底层陆地一旦不稳定,视觉上就像整张图只剩海洋和几个点。
第四轮排查:验证 cl 和 co 的真实作用
为了避免只看变量名做判断,又直接抓取了第三方生成的背景图,并对颜色结果做了比对。
最终确认:
cl确实控制陆地颜色co确实控制海洋颜色
这一步排除了“参数理解反了”的可能。
也就是说,陆地不可见并不是因为把海洋和陆地颜色写反了,而是两个更深层的问题叠加在一起:
- 暗黑配色在小尺寸地图上对比不够
- 组件过度依赖第三方远端生成的底图
为什么单纯改颜色不够
中间尝试过几组不同的暗黑参数,包括:
- 更浅的陆地色
- 更深的海洋色
- 更亮的文本色
- 更明显的访客点颜色
这些改动能改善观感,但不能彻底解决问题。
原因有三个:
- 用户刷新后问题仍然存在,说明不是一次性的状态残留
- 第三方底图来自远端动态生成,表现并不完全可控
- 即使参数理论上合理,也不能保证用户端每次都得到一致结果
所以如果继 续只依赖第三方远端底图,这个问题会一直处于“理论上应该正常,但实际不稳定”的状态。
最终方案:把暗黑模式陆地图层本地化
最后采用了一个更稳定的方案。
保留第三方组件负责的动态部分:
- 访客点
- 统计文字
- 交互层
只把暗黑模式下的底层地图背景本地化。
这样做以后:
- 陆地是否显示,不再依赖第三方远端底图的即时表现
- 亮色模式完全不动
- 第三方动态数据仍然保留
对应新增的本地资源是:
static/img/mapmyvisitors-dark-bg.png
对应样式处理在:
src/pages/index.module.css
这里的核心思路是把不稳定的部分收缩掉,只保留第三方组件真正有价值的动态能力。
额外处理:修复主题切换残留
除了底图本身,另一个潜在风险是明暗主题切换时,第三方脚本未必会完整重建。
所以在首页组件里额外做了处理,让访客地图在主题切换时重新挂载。
对应文件:
src/pages/index.js
这样做的目的是:
- 从亮色切到暗色时,第三方脚本重新初始化
- 避免沿用上一种主题下的残留 DOM 和旧状态
视觉收尾:让地图和整站暗色风格统一
陆地恢复之后,问题就从“功能不可用”变成了“视觉还不够协调”。
用户后续提出了两个很关键的审美反馈:
- 海洋颜色和地图内层、外层容器颜色不统一
- 绿色访客点不够清楚
所以又做了两轮收尾优化。
统一海洋色和容器色
把暗黑模式下的海洋色抽成统一变量:
--dark-map-sea: #1c2836;
外层容器和内层地图容器都使用同一个海洋底色,这样视觉上就不会再像两层分离的盒子,而是更像一整张地图自然嵌在侧边卡片里。