JavaScript Worker运行异常:切换页面时加载缓慢或出现不可访问错误
先还原你的场景和代码:
你用JavaScript Worker异步请求PHP后端数据,Worker代码(ajax-worker.js)如下:
self.onmessage = function(e){ var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { postMessage(xhttp.responseText); } }; xhttp.open("GET", e.data, true); xhttp.send(); }
初始化Worker的前端代码:
let worker = new window.Worker('http://localhost:8100/ajax-worker.js'); worker.postMessage('http://localhost:8100/Audit/get_total_confirmed'); worker.onmessage = function(e){ var e = JSON.parse(e.data); document.querySelector('#stat_confirmed_listings').innerHTML = e.msg; }
当前功能正常,但切换到网站其他页面时,页面加载耗时极长,甚至出现“unreachable page”错误,只有等Worker完成请求或重启服务器后才能恢复。
1. Worker 未被主动终止,导致连接/资源泄漏
这是最可能的原因:当你离开当前页面(跳转、刷新),如果没手动终止Worker,它会一直在后台运行那个AJAX请求。浏览器对同一个域名的并发请求有上限(比如Chrome默认是6个),服务器端的并发连接/进程数也有限,这些挂着的Worker请求会占满资源池,导致新页面的请求无法被处理,进而出现加载慢或无法访问的情况。
解决方法:在页面卸载前主动终止Worker,释放资源:
// 在初始化Worker的代码后添加这段 window.addEventListener('beforeunload', () => { if (worker) { worker.terminate(); // 强制终止Worker worker = null; // 释放引用,辅助垃圾回收 } });
2. 后端接口阻塞,耗尽服务器资源
如果你的PHP后端用的是同步处理模型(比如Apache+PHP-FPM),当Audit/get_total_confirmed接口处理耗时过长(比如慢数据库查询、IO阻塞),会一直占用PHP-FPM进程。如果服务器的PHP-FPM进程数设置较少,这些被Worker占用的进程会导致新的页面请求没有可用进程处理,从而出现页面无法访问的问题。
排查与优化建议:
- 检查后端接口耗时:在PHP代码中添加日志记录接口的开始/结束时间,或用浏览器Network面板查看请求的
Timing信息,确认接口本身是否存在性能问题。 - 查看PHP-FPM状态:若开启了
pm.status_path,访问对应状态页,查看是否有大量进程处于busy状态。 - 优化后端逻辑:给慢查询添加数据库索引,将阻塞操作改为异步处理(比如用消息队列),或适当增加PHP-FPM进程数(注意不要超过服务器CPU/内存上限)。
3. 隐性请求阻塞问题(概率较低)
虽然当前功能正常,但可以排查Worker发起的请求是否长期处于pending状态:打开浏览器开发者工具的Network面板,找到Worker的请求,查看它的状态是否一直卡在pending或stalled。如果是,可能是后端未正确返回响应,或浏览器的缓存/连接设置存在问题。
排查建议:
- 检查后端接口是否存在超时但未主动关闭连接的情况;
- 查看响应头的
Connection、Cache-Control等设置是否合理,避免浏览器一直保持无效连接。
内容的提问来源于stack exchange,提问作者Juliver Galleto

