【发布时间】:2019-07-12 13:31:36
【问题描述】:
我需要将一个大型数据集写入网页(使用服务器端渲染),该数据集将由页面中运行的 JavaScript 组件使用。此数据由一个数据网格组件和一个图表组件的对象数组组成(因此每个数组元素都是一个数据网格行)。
出于性能原因,我想使用 JavaScript 对象构造函数而不是对象字面量(使用构造函数对对象进行了 JIT 编译器优化,并且它们使用更少的在线空间,因为省略了属性名称)。我也可以原生使用Date 构造函数。
这是我现在的做法:
<script type="text/javascript">
function WeeklySalesRow( weekName, date, totalSales, profit, loss, turnover, deltaSalesPercentage, etc )
{
this.weekName = weekName;
this.date = date;
this.totalSales = totalSales;
this.profit = profit;
this.loss = loss;
// etc
}
var weeklySalesData = [
@{
Boolean first = true;
foreach( WeeklySalesRow row in this.Model.WeeklySalesData ) {
if( !first ) this.WriteLine( "," ); first = false;
this.Write( "new WeeklySalesRow( \"{0}\", new Date({1}), {2}, {3}, {4}, etc )", row.WeekName, row.Date.ToUnixTimestamp(), row.TotalSales, row.Profit, row.Loss, row.Turnover, etc );
}
}
];
function onDomContentLoaded( e ) {
var chartCompoennt = ...
chartComponent.loadData( weeklySalesData );
}
</script>
像这样渲染:
// [...]
var weeklySalesData = [
new WeeklySalesRow( "2018W1", new Date(1514764800), 1100, 200, 900, 50, 0.56, etc ),
new WeeklySalesRow( "2018W2", new Date(1515369600), 1200, 100, 800, 45, 0.80, etc ),
new WeeklySalesRow( "2018W3", new Date(1515974400), 1300, 50, 700, 65, 0.12, etc ),
new WeeklySalesRow( "2018W4", new Date(1516752000), 1400, 25, 600, 80, 0.45, etc ),
new WeeklySalesRow( "2018W5", new Date(1517443200), 1500, 12, 500, 90, 0.123, etc ),
// etc...
];
// [...]
比以下更简洁:
var weeklySalesData = [
{ weekName: "2018W1", date: "2018-01-01", totalSales: 1100, profit: 200, loss: 900, turnover: 50, deltaSalesPercentage: 0.56, etc },
{ weekName: "2018W2", date: "2018-01-08", totalSales: 1200, profit: 100, loss: 800, turnover: 50, deltaSalesPercentage: 0.56, etc },
{ weekName: "2018W3", date: "2018-01-17", totalSales: 1300, profit: 50, loss: 700, turnover: 50, deltaSalesPercentage: 0.56, etc },
{ weekName: "2018W4", date: "2018-01-23", totalSales: 1400, profit: 25, loss: 600, turnover: 50, deltaSalesPercentage: 0.56, etc },
{ weekName: "2018W5", date: "2018-02-01", totalSales: 1500, profit: 12, loss: 500, turnover: 50, deltaSalesPercentage: 0.56, etc },
];
我知道能够直接解析 JSON 的运行时组件(例如 fetch 和 XMLHttpRequest)能够减轻使用对象文字符号(例如解析器检查数组和看到所有对象文字共享相同的属性名称集,因此可以在运行时为它们定义一个内部隐藏基类) - 但该优化不适用于这种情况,因为数据正在呈现到 SSR 网络中-page 并且我知道即使是最近的性能基准测试也没有显示针对“所有数组元素看起来相似”场景的任何解析器或编译器优化)。
有没有办法让 Json.NET 自动为我执行此操作,使用反射自动生成 JavaScript 构造函数和 JavaScript 构造函数调用?
【问题讨论】:
-
我从未使用过它,但鉴于
JsonToken包含StartConstructor和EndConstructor的条目,我会说...也许?您是否尝试过编写自定义转换器? -
你能把构造函数的值生成为一个列表吗?如果是这样,您可以让构造函数接受该列表而不是
(parm1, param2, param3)等,或者通过apply(this, parameterArray)调用它。但是,您确定属性名称的开销如此之大吗?试图忽略它们似乎是过早的优化 - 我希望压缩有效负载可以消除传输它们的“问题”。 -
没有办法自动执行此操作,但您可以通过调用
JsonWriter.WriteStartConstructor(string name)的 customJsonConverter和稍后的JsonWriter.WriteEndCOnstructor()来执行此操作。有关详细信息,请参阅When using a JsonWriter, what's the purpose of WriteStartConstructor?。自定义转换器可以通过使用反射或serializer.ContractResolver进行通用化。 -
您的问题是,Json.NET 有没有办法自动为我执行此操作... 使用反射的通用
JsonConverter是否足够?
标签: javascript c# serialization json.net