【发布时间】:2020-11-24 23:30:34
【问题描述】:
在我的 Blazor 应用程序中,我有一个具有类似方法的组件。 (我已经用其中的代码替换了 GetFromJsonAsync 调用,以缩小缓慢的部分。)
private async Task GetData()
{
IsLoading = true;
string url = $".../api/v1/Foo"; // will return a 1.5 MB JSON array
var client = clientFactory.CreateClient("MyNamedClient");
Console.WriteLine($"starting");
List<Foo> results;
Task<HttpResponseMessage> taskResponse = client.GetAsync(url, HttpCompletionOption.ResponseContentRead, default);
var sw = Stopwatch.StartNew();
using (HttpResponseMessage response = await taskResponse)
{
response.EnsureSuccessStatusCode();
var content = response.Content!;
if (content == null)
{
throw new ArgumentNullException(nameof(content));
}
string contentString = await content.ReadAsStringAsync();
sw.Stop();
Console.WriteLine($"Read string: {sw.Elapsed}");
sw.Restart();
results = System.Text.Json.JsonSerializer.Deserialize<List<Foo>>(contentString);
}
sw.Stop();
Console.WriteLine($"Deserialize: {sw.Elapsed}");
StateHasChanged();
IsLoading = false;
我的 1.5 MB 下载需要 1-6 秒,但其余操作(在此期间 UI 被阻止)需要 10-30 秒。 这只是在ReadFromJsonAsync(内部调用System.Text.Json.JsonSerializer.Deserialize)中的缓慢反序列化,还是这里发生了其他事情? 我怎样才能提高获取这么多数据集的效率(虽然我认为它并没有那么大!)
为了简化,我已经注释掉了绑定到 Results 的任何内容,而我只是有一个绑定到 IsLoading 的指示器。这告诉我更新 DOM 或渲染没有问题。
当我在自动化集成测试中尝试同一组代码时,只需要 3 秒左右。 WebAssembly 在反序列化方面真的那么慢吗?如果是这样,是在我的网站上到处检索非常小的数据集的唯一解决方案吗?这对我来说似乎不对。
这是运行上述代码所产生的浏览器控制台日志:
VM1131:1 Fetch finished loading: GET "https://localhost:5001/api/v1/Foo".
read string 00:00:05.5464300
Deserialize: 00:00:15.4109950
L: GC_MAJOR_SWEEP: major size: 3232K in use: 28547K
L: GC_MAJOR: (LOS overflow) time 18.49ms, stw 18.50ms los size: 2048K in use: 187K
L: GC_MINOR: (LOS overflow) time 0.33ms, stw 0.37ms promoted 0K major size: 3232K in use: 2014K los size: 2048K in use: 187K
无论如何,这是 Chrome 性能图表。绿色是下载,橙色是“执行微任务”,我认为这意味着 WebAssembly 工作。
【问题讨论】:
-
看看Newtonsoft是否更好
-
我已经编辑了示例以使其更清晰,并且实际上将下载与反序列化分开。
-
答案可能是“是的,它很慢”,它作为解释的 IL 代码运行。迁移到 .net 5 时可能会有一些小的改进,但直到我们获得 AoT 编译才会接近“正常”速度。不知道那是什么时间线。
-
关于什么使它变慢或如何解决的任何建议?是检索较小数据块的唯一方法吗?有什么方法可以使序列化更简单,或者以某种方式处理未序列化/结构化数据较少的数据?
-
1.5 MB 是大量的 JSON 下载和反序列化。你绝对需要下载那么多数据吗?可以分页吗?出于好奇,JavaScript 需要多长时间来反序列化它?
标签: performance blazor blazor-client-side blazor-webassembly