通过URL读取XML文档导致Unity WebGL游戏卡顿冻结
Unity WebGL加载XML文件冻结问题解决
问题情况
Unity编辑器中通过GitHub仓库原始URL读取XML文件,并将数据存入自定义类类型的ArrayList中完全正常,但打包为WebGL版本后,加载包含该脚本的场景时游戏直接冻结。Chrome开发者工具报错2 FS.syncfs operations in flight at once, probably just doing extra work,同时浏览器CPU占用率拉满。
原调用逻辑是在void Start()中执行StartCoroutine(ReadXML("xxxxxxx"))启动协程,原协程代码如下:
IEnumerator ReadXML(string url) { try { xmldoc = XDocument.Load(@url); var query = from p in xmldoc.Elements("popupNotify").Elements("popNoti") select p; foreach (XElement record in query) { PopNotifi popNoti = new(record.Element("text").Value, record.Element("colliderName").Value, record.Element("type").Value, record.Element("duration").Value); popNotifiList.Add(popNoti); } } catch (Exception e) { Debug.LogError(e.Message); } yield return url; }
问题原因
- 同步网络请求阻塞主线程:
XDocument.Load(@url)是同步IO操作,在WebGL环境中,同步网络请求会直接阻塞主线程,导致游戏冻结,同时触发FS.syncfs相关报错。 - 协程逻辑无效:
yield return url是无意义的操作,没有实现真正的异步等待,协程全程在主线程同步执行,加剧阻塞问题。
解决方案
改用Unity官方推荐的UnityWebRequest进行异步网络请求,获取XML文本后再解析,确保不会阻塞主线程。修改后的代码如下:
IEnumerator ReadXML(string url) { try { using (UnityWebRequest webRequest = UnityWebRequest.Get(url)) { // 异步等待请求完成,不阻塞主线程 yield return webRequest.SendWebRequest(); if (webRequest.result == UnityWebRequest.Result.Success) { // 解析下载到的XML文本 string xmlText = webRequest.downloadHandler.text; xmldoc = XDocument.Parse(xmlText); var query = from p in xmldoc.Elements("popupNotify").Elements("popNoti") select p; foreach (XElement record in query) { // 增加空值判断,避免节点不存在时抛出异常 PopNotifi popNoti = new PopNotifi( record.Element("text")?.Value ?? "", record.Element("colliderName")?.Value ?? "", record.Element("type")?.Value ?? "", record.Element("duration")?.Value ?? ""); popNotifiList.Add(popNoti); } } else { Debug.LogError($"XML请求失败: {webRequest.error}"); } } } catch (Exception e) { Debug.LogError($"XML解析异常: {e.Message}"); } }
关键修改点
- 使用
UnityWebRequest.Get发起异步网络请求,通过yield return webRequest.SendWebRequest()实现非阻塞等待,适配WebGL环境的线程模型。 - 替换
XDocument.Load(url)为XDocument.Parse(xmlText),避免直接同步加载网络资源。 - 增加空值安全访问(
?.Value ?? ""),防止XML节点缺失导致的空引用异常。 - 移除无效的
yield return url,规范协程逻辑。
内容的提问来源于stack exchange,提问作者Vernwalker
相关产品推荐
相关产品推荐

