Ajax请求本身极快,性能瓶颈实际在于网络传输、服务器响应、主线程阻塞或缓存策略等环节,而非HTML中编写方式。

HTML 中直接写 XMLHttpRequest 或 fetch 不会拖慢异步请求
“HTML Ajax”本身不是一种技术——它只是指在 HTML 页面中发起的 Ajax 请求。真正执行网络请求的是浏览器 JavaScript 引擎,和 HTML 文件本身无关。只要没在 DOMContentLoaded 或 load 事件前阻塞式加载大量脚本、或在主线程里做密集计算,Ajax 请求的发起和响应处理不会因为“写在 HTML 里”而变慢。
常见误解来源:有人把内联 <script></script> 放在 底部,又在里面调用 fetch(),结果页面渲染卡顿,误以为是 Ajax 拖慢了;实际是 JS 执行阻塞了渲染,或者请求返回后 DOM 操作太重。
- 请求发起本身极快(微秒级),耗时主要在网络传输和服务器响应
- HTML 文件大小不影响 Ajax 性能,但若内联大量 JS 逻辑(比如每次请求都重新解析模板字符串),会增加主线程压力
- 用
async或defer加载外部脚本,比内联长脚本更利于首屏性能
用 fetch 发起请求时,不加 cache: 'no-store' 可能导致“假慢”
浏览器对 GET 请求默认启用 HTTP 缓存,如果接口本该实时(比如获取最新订单状态),却命中了本地缓存,你会看到“请求飞快完成”,但数据是旧的——这容易被误判为“Ajax 响应快”,实则是逻辑错误带来的感知偏差。
尤其当后端没正确设置 Cache-Control,而前端又没显式控制缓存策略时,问题更隐蔽。
立即学习“前端免费学习笔记(深入)”;
- 实时性要求高的接口,显式加
cache: 'no-store'或cache: 'reload' - 避免依赖默认缓存行为,特别是开发环境用 DevTools 的 “Disable cache” 只影响手动刷新,不影响脚本发起的
fetch -
POST请求天然不缓存,但若用GET传参数模拟 POST,仍会走缓存
多个并发 fetch 请求在 Chrome 中可能触发“pending”堆积
Chrome 对同一域名的并发连接数默认限制为 6(HTTP/1.1)。如果你在循环里无节制地发 20 个 fetch,前 6 个立即发出,剩下 14 个显示为 pending,直到有连接空闲——这不是 Ajax 慢,是浏览器限流。
这种现象在列表页批量拉取用户头像、商品 SKU 数据等场景特别明显,用户会感觉“点了按钮半天没反应”。
- 用
Promise.allSettled()+ 分批(如每批 4 个)控制并发量,比全量Promise.all()更稳妥 - HTTP/2 能缓解该问题,但需服务端支持且 TLS 配置正确;光改前端无效
- DevTools Network 面板中看 Initiator 列,能快速区分是 JS 主动发起,还是浏览器预加载/资源加载导致的 pending
把 XMLHttpRequest 当成“更可控”方案?其实现代 fetch 更轻量
有人坚持用 XMLHttpRequest,认为它支持 abort()、上传进度、同步请求等“高级功能”。但同步请求已废弃(会阻塞整个页面),而 fetch + AbortController 同样支持中断,上传进度也完全可通过 ReadableStream 或分块 FormData 实现。
更大的问题是:手写 XMLHttpRequest 容易漏掉错误边界(比如 readyState === 4 但 status 是 0 或 500),而 fetch 至少帮你屏蔽了网络层失败(如 CORS、DNS 错误)与 HTTP 状态码的混淆。
-
fetch默认不带 cookie,要发带凭证的请求必须加credentials: 'include' -
XMLHttpRequest的onprogress是上传专用,fetch没内置上传进度,但可用TransformStream或服务端 SSE 替代 - 真需要细粒度控制(如断点续传、自定义 header 写入时机),优先考虑封装一层而不是退回
XMLHttpRequest
真正影响 Ajax 感知速度的,从来不是“用了 HTML 还是 JS”,而是请求链路中的任意一环:DNS 查询、TLS 握手、服务端处理、响应体大小、JS 回调里是否做了大数组 map 或未节流的 innerHTML 插入。盯着“Ajax”本身优化,往往绕开了真正的瓶颈。



















