本地开发环境慢?localhost的锅!

本地开发环境慢?localhost 的锅!

一场历时三小时的性能追杀

第一章:晴空霹雳

"后台响应速度太慢了,查询要 300ms 以上,降到 50ms。"

接到这个需求的时候,我心想:不就是几个简单的 SELECT 查询吗?加个索引、优化下 SQL,手到擒来。

太天真了。

第二章:全面围剿

三个端点,全是简单的元数据查询:

sql 复制代码
SELECT id, code, name, table_name FROM meta_entity WHERE is_deleted = 0 ORDER BY code ASC;
SELECT ... FROM meta_entity_prop WHERE parent = ? AND is_deleted = 0 ORDER BY sort ASC;
SELECT ... FROM meta_enum_item WHERE parent = ? AND is_deleted = 0 ORDER BY create_time ASC;

于是开始了一轮又一轮的优化:

第一轮:索引 ------建覆盖索引,消除全表扫描。没解决。

第二轮:SQL 改写 ------把两次查询合成一次 JOIN,减少数据库往返。没解决。

第三轮:代码级优化 ------发现 resultSetToList 里在行循环中重复调用 ResultSetMetaData.getColumnLabel(),这可是 JDBC 驱动级操作!果断提到循环外面。还是没解决。

第四轮:祭出 Arthas------发现 Arthas 跟 Dragonwell JDK + JRebel 有兼容问题,Netty term server 绑定端口后立刻 CLOSE。Arthas 阵亡。

第五轮:JDK 内置 JFR ------启动参数居然带着 -XX:TieredStopAtLevel=1!这不等于让法拉利挂一档跑高速吗?赶紧去掉。依然没解决。

第六轮:XRebel------换上 Tomcat,XRebel 终于亮了。所有请求都在 10ms 内完成。完美!

......等等。

第三章:鬼打墙

如果 XRebel 说后端只用了 10ms,那 300ms 去哪儿了?

我盯着 Chrome DevTools 的 Network 面板,陷入了沉思:

复制代码
等待服务器响应 (TTFB):  313.90 ms  ← 这 313ms 在等什么?
下载内容:                 8.95 ms   ← 后端返回后浏览器秒收

后端 10ms 完成,浏览器却等了 313ms 才收到。中间的 300ms 凭空消失了。

那一刻我想到了所有可能的原因:

  • Vite 代理层有 bug?升级 Vite,优化 proxy,装上超时处理和监控日志。
  • 前端 JS 处理太慢?检查 Vue 渲染性能。
  • 操作系统 TCP 栈有问题?检查 Windows 网络配置。
  • 服务器 HikariCP 连接池满了?调大最小连接数。

我像个无头苍蝇一样在代码里来回乱撞。每一个可能的方向都是死胡同。

第四章:真相大白

折腾了三个小时之后,我瘫在椅子上,盯着浏览器的地址栏发呆。

然后我注意到------

地址栏里赫然写着:http://localhost:3000

等等。

我之前用 curl 直接调后端的时候,用的可是 127.0.0.1:8080

一个念头闪过。我抄起 Chrome,在地址栏里敲下:

复制代码
http://127.0.0.1:3000

回车。

页面刷出来了。我点了一下设计器。操作流畅得像在本地原生应用里一样。

我不信邪,打开 Network 面板,看了下请求耗时:

「15ms」

我揉了揉眼睛。

「12ms」

「8ms」

「6ms」

终章:localhost 的诅咒

真相让人哭笑不得:

Windows 上 localhost 不是直接走 127.0.0.1 的。

localhost 是一个 DNS 名称。Windows 会先尝试解析到 IPv6 地址 ::1,连接失败后再回退到 IPv4 的 127.0.0.1。这个 IPv6 → IPv4 回退过程 每次都要耗费 200-300ms。

而我的所有优化------索引、JOIN、列名预取、升级 Vite、换 Tomcat------它们都在正确地工作着。只是被操作系统自己给坑了。

花了一百万改装一辆赛车,结果赛道入口被一块石头堵了。

每次请求都要经历:

复制代码
浏览器 → localhost (DNS解析 ::1 → 超时 → 回退 127.0.0.1) → Vite 代理 → Java 后端
         ↑ 白白浪费 300ms                         ↑ 10ms 完成

改成 127.0.0.1 后:

复制代码
浏览器 → 127.0.0.1 (直连) → Vite 代理 → Java 后端
         ↑ 0ms              ↑ 10ms 完成

教训

排查性能问题时,先看一眼浏览器的地址栏------有时候最蠢的问题隐藏在最显眼的地方。

以及,localhost127.0.0.1 在 Windows 上不是一回事。


附:解决方案

方案 操作
立竿见影 浏览器地址栏用 http://127.0.0.1:3000 替代 http://localhost:3000
一劳永逸 修改 C:\Windows\System32\drivers\etc\hosts,确保 127.0.0.1 localhost 排在 ::1 localhost 前面
终极方案 禁用 IPv6(不推荐,可能影响其他网络功能)
相关推荐
宿6749 小时前
vue3-async
前端·javascript·vue.js
Dreams°12316 小时前
【Java后端+Vue前后端分离:内网正常、公网访问异常|5个高频经典踩坑完整复盘】
java·开发语言·vue.js
小蒜学长16 小时前
基于Springboot+Vue的环保行动志愿者招募系统设计与实现(代码+数据库+LW)
java·数据库·vue.js·spring boot·后端
天道kabuto17 小时前
踩坑复盘:为什么在输入框按个回车,页面就偷偷刷新了?
vue.js
吴长建先生17 小时前
Vue.js支付回调页面如何设计才能保障对账准确性?
vue.js
leoZ23117 小时前
第 2 篇:搭建地基——Vue3 + Vite + Tailwind v4 + shadcn-vue
前端·javascript·vue.js·人工智能·目标检测·数据挖掘·语音识别
吴长建先生18 小时前
支付回调接口设计与代码规范:如何提升团队工程化能力
vue.js
zttbee18 小时前
vue2的API大白话讲解
前端·vue.js·前端框架
卤蛋fg621 小时前
vue 抽屉组件挂载到指定元素内显示,,表格自适应弹窗宽高
vue.js
天道kabuto2 天前
vue-i18n 升级 9.x 踩坑:正则表达式引发的“花括号”惨案
vue.js