为了优化性能,我应该将 Web 数据存储为 CSV 还是 JSON?

Mar*_*kus 2 javascript csv performance json request

我正在使用一个对于网络用户(尤其是智能手机用户)来说相对较大的数据集。我担心表现。对于用户来说哪个问题更大?

\n\n
    \n
  1. 强制客户端浏览器获取/请求大数据文件 ( JSON)。
  2. \n
  3. 强制客户端的浏览器将较小的文件 ( CSV) 重新格式化为较大的文件 ( JSON) 以便可以使用。
  4. \n
\n\n

当我将数据编译为 时JSON,它大约为570KB \xe2\x80\x93,远远大于我通常使用的大小。这被直接剥离了(例如,我已将每个键减少为单个字符)。

\n\n

当我将数据编译为 时CSV,大约为220KB。但是,无论如何,我都需要浏览器将其重新JSON格式化。

\n\n

这是一个小例子。一份CSV文件:

\n\n
"year","birth","101","102","103","104","105"\n1981,"Australia",5972,1099,573,747,667\n1981,"China",141,4,3,2,2\n1981,"India",139,5,4,6,2\n1981,"Indonesia",371,9,14,5,6\n1981,"Malaysia",838,72,42,11,14 \n
Run Code Online (Sandbox Code Playgroud)\n\n

...与相同数据相比JSON

\n\n
[{"year":1981,"birth":"Australia","101":5972,"102":1099,"103":573,"104":747,"105":667},\n{year":1981,"birth":"China","101":141,"102":4,"103":3,"104":2,"105":2},\n{year":1981,"birth":"India","101":139,"102":5,"103":4,"104":6,"105":2},\n{year":1981,"birth":"Indonesia","101":371,"102":9,"103":14,"104":5,"105":6},\n{year":1981,"birth":"Malaysia","101":838,"102":72,"103":42,"104":11,"105":14}]\n
Run Code Online (Sandbox Code Playgroud)\n\n

TLDR:对于性能来说,哪一个更重要:(1) 最小化数据文件的大小,或 (2) 最小化浏览器必须执行的数据处理量?

\n

Dai*_*Dai 5

前言:

我认为你想要做的是一种过早的微优化(https://en.wikipedia.org/wiki/Program_optimization),这是因为大多数网络服务器无论如何都会 GZip HTTP 响应,所以就实际而言传输的数据担心 CSV 和扩展的 JSON 表示形式将具有大致相同的 GZip 大小,因为它们具有相同的信息熵。

另外,我建议阅读 Google 的这篇文章(日期为 2019 年 6 月):https://v8.dev/blog/cost-of-javascript-2019 - 简而言之:JavaScript 很便宜,您只需要担心移动设备上的优化,而不是台式机/笔记本电脑。

反正:

除了 CSV 和 JSON 对象之外,还有一些其他选择。

JSON 数组:

一种选择可能是两全其美的,那就是使用 JSON 数组,如下所示:

[
 [ "year","birth","101","102","103","104","105" ],
 [ 1981,"Australia",5972,1099,573,747,667 ],
 [ 1981,"China",141,4,3,2,2 ],
 [ 1981,"India",139,5,4,6,2 ],
 [ 1981,"Indonesia",371,9,14,5,6 ],
 [ 1981,"Malaysia",838,72,42,11,14 ]
]
Run Code Online (Sandbox Code Playgroud)

您可以使用命名const数组索引来访问每个数据成员:

const Idx = {
    YEAR: 0,
    BIRTH: 1,
    _101: 2,
    _102: 3,
    _104: 4,
    // etc
};

var data = JSON.parse( text ); // the array from above

for( var i = 1; i < data.length; i++ ) {
    var row = data[i];

    console.log( "Year: %d, Birth: %s", row[Idx.YEAR], row[Idx.BIRTH] );
}
Run Code Online (Sandbox Code Playgroud)

您还可以拥有自己的物化函数来将每一行转换为强类型对象:

function Item( row ) {
    this.year = row[Idx.YEAR];
    this.birth = row[Idx.BIRTH];
}

var data = JSON.parse( text ); // the array from above

var items = data.map( row => new Item( row ) );
Run Code Online (Sandbox Code Playgroud)

构造函数调用数组

将每个记录表示为父数组中的数组的另一种替代方法是将每个记录表示为构造函数调用 - 但这不起作用JSON.parse- 您必须使用eval()不推荐)直接在服务器内的网页中呈现数据- 端生成脚本,或者让客户端将其加载到元素中<script>(这就是 JSONP 的工作原理,但很危险)。

当我将数据渲染到网页以供第三方数据可视化组件(例如 D3 或各种其他图表库)使用时,我自己使用这种方法:

function Item( year, birth, _101, _102, _103, _104, _105 ) {
    this.year = year;
    this.birth = birth;
    this._101 = _101;
    this._102 = etc...
}

data = [
    new Item( 1981,"Australia",5972,1099,573,747,667 ),
    new Item( 1981,"China",141,4,3,2,2 ),
    new Item( 1981,"India",139,5,4,6,2 ),
    new Item( 1981,"Malaysia",838,72,42,11,14 ),
    // etc
];

renderChart( data );
Run Code Online (Sandbox Code Playgroud)

例如,当我需要执行客户端数据转换并且我不想将不同格式的数据的两个副本呈现给响应时,我会使用此方法。但正如我所说,这种技术不起作用JSON.parse,因为 json 必须只是静态数据,而不是构造函数调用。