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

Javascript 为了优化性能,我应该将web数据存储为CSV还是JSON?,javascript,json,performance,csv,request,Javascript,Json,Performance,Csv,Request,我使用的数据集对于网络用户来说相对较大,尤其是智能手机用户。我担心表现。对用户来说,哪个问题更大 强制客户端浏览器获取/请求大型数据文件(JSON) 强制客户端浏览器将较小的文件(CSV)重新格式化为较大的文件(JSON),以便使用 当我将数据编译为JSON时,它大约是570KB,比我通常使用的要大得多。这是完全精简的(例如,我将每个键减少为一个字符) 当我将数据编译为CSV时,大约是220KB。但是,我仍然需要浏览器将其重新格式化为JSON格式 这里有一个小例子。一个CSV文件: "year"

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

  • 强制客户端浏览器获取/请求大型数据文件(
    JSON
  • 强制客户端浏览器将较小的文件(
    CSV
    )重新格式化为较大的文件(
    JSON
    ),以便使用
  • 当我将数据编译为JSON时,它大约是570KB,比我通常使用的要大得多。这是完全精简的(例如,我将每个键减少为一个字符)

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

    这里有一个小例子。一个
    CSV
    文件:

    "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 
    
    。。。与
    JSON
    相同的数据相比:

    [{"year":1981,"birth":"Australia","101":5972,"102":1099,"103":573,"104":747,"105":667},
    {year":1981,"birth":"China","101":141,"102":4,"103":3,"104":2,"105":2},
    {year":1981,"birth":"India","101":139,"102":5,"103":4,"104":6,"105":2},
    {year":1981,"birth":"Indonesia","101":371,"102":9,"103":14,"104":5,"105":6},
    {year":1981,"birth":"Malaysia","101":838,"102":72,"103":42,"104":11,"105":14}]
    
    TLDR:什么对性能更重要:(1)最小化数据文件的大小,或(2)最小化浏览器必须处理的数据量?

    前言: 我认为您想要做的是一种过早的微优化(),这是因为大多数Web服务器无论如何都会有GZip HTTP响应,所以就实际传输的数据而言,CSV和扩展JSON表示将具有大致相同的GZip大小,因为它们具有相同的信息熵

    此外,我建议您阅读谷歌(日期为2019年6月)的这篇文章:简而言之,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 ]
    ]
    
    您可以使用命名的
    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] );
    }
    
    构造函数调用数组 将每条记录表示为父数组中的数组的另一种替代方法是将每条记录表示为构造函数调用-但是这不适用于
    JSON.parse
    -您必须使用
    eval()
    不建议使用),在服务器端生成脚本中直接在网页中呈现数据,或者让客户端将其加载到
    元素中(这是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 );
    

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

    网络请求将是异步的,因此,如果需要稍微多一些时间,您的用户不会失去与页面的交互。另一方面,csv解析如果速度慢,则会阻止交互,假设您没有使用服务工作者。因此,从用户的角度来看,假设是最坏的情况,json更可取。然而,在实践中,我怀疑这两种解决方案中的任何一种都会导致明显的相对于另一种的速度减慢。@M-N您可以在web worker中执行CSV解析,并通过消息将具体化的数据返回到web页面。也就是说,我不建议用JavaScript处理CSV数据,因为JavaScript没有(广泛支持的)字符串和流处理支持(例如,由于JavaScript字符串是不可变的,并且没有可变的字符串生成器,因此构建CSV字符串并执行大量
    string。split
    调用将浪费内存,导致字符串副本和分配过多)关于为什么投票失败的反馈将被理解。我想补充的是,V8在某些移动设备上运行时关闭了优化编译器。这是一个考虑避免大量数据处理的原因。谢谢@ DAI。JSON数组是一个好主意,尽管我怀疑物化功能本身是否会影响PE。R性能,考虑到我需要调用它的次数。我也在考虑对我(程序员)的方便。JSON的优点之一是代码易于理解!@Markus查看性能是否会出现问题的唯一方法是针对您的情况进行分析和基准测试。我不知道您打算对数据做什么,所以我还不能推测性能会是什么样子。我看到我的答案被否决了(还有其他人投了赞成票)。请在评论回复中回答为什么我的答案被否决。@Jai,数据提供了一个交互式viz(链接到图表的地图)。每当用户与viz交互时(例如,每当重新绘制图表或地图改变以反映时间流逝时),我都会调用数据。
    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 );