优化JSON数据

课后整理 2020-12-20

JSON 是一个轻量级并易于解析的数据格式,它按照JavaScript对象和数组字面语法来编写。

【示例1】下面代码是用JSON 编写的用户列表。

[{
    "id" : 1,
    "username" :  "alice",
    "realname" :  "Alice ",
    "email" :  "alice@163.com"
}, {
    "id" : 2,
    "username" :  "bob",
    "realname" :  "Bob ",
    "email" :  "bob@163.com"
}, {
    "id" : 3,
    "username" :  "carol",
    "realname" :  "Carol ",
    "email" :  "carol@163.com"
}, {
    "id" : 4,
    "username" :  "dave",
    "realname" :  "Dave ",
    "email" :  "dave@163.com"
}]

用户为一个对象,用户列表为一个数组,与JavaScript 中其他数组或对象的写法相同。这意味着如果对象被包装在一个回调函数中,JSON数据可以成为能够运行的JavaScript 代码。

在JavaScript中解析JSON可简单地使用小括号()。

function parseJSON(responseText) { 
   return ('(' + responseText +  ')');
}

【示例2】上面JSON数据也可以提炼成一个更简单的版本,将名字缩短。

[{
    "i" : 1,
    "u" :  "alice",
    "r" : "Alice  ",
    "e" :  "alice@163.com"
}, {
    "i" : 2,
    "u" :  "bob",
    "r" : "Bob  ",
    "e" :  "bob@163.com"
}, {
    "i" : 3,
    "u" :  "carol",
    "r" : "Carol  ",
    "e" :  "carol@163.com"
}, {
    "i" : 4,
    "u" :  "dave",
    "r" : "Dave  ",
    "e" :  "dave@163.com"
}]

JSON精简版本将相同的数据以更少的结构和更小的字节尺寸传送给浏览器。

【示例3】也可以完全去掉属性名,与原格式相比,这种格式可读性更差,但更利索,文件尺寸非常小:大约只有标准JSON 格式的一半。

[
     [ 1, "alice",  "Alice ", "alice@163.com" ],
     [ 2, "bob",  "Bob", "bob@163.com" ],
     [ 3, "carol",  "Carol ", "carol@163.com" ],
     [ 4, "dave",  "Dave ", "dave@163.com" ]
]

【示例4】在解析示例3的JSON数据时,需要保持数据的顺序,也就是说,这种精简格式在进行格式转换时必须保持和第一个JSON格式一样的属性名。

function parseJSON(responseText) {
    var users = [];
    var usersArray = ('(' +  responseText + ')');
    for(var i = 0, len =  usersArray.length; i < len; i++) {
        users[i] = {
            id : usersArray[i][0],
            username :  usersArray[i][1],
            realname :  usersArray[i][2],
            email :  usersArray[i][3]
        };
    }
    return users;
}

在上面代码中,使用()将字符串转换为一个本地JavaScript 数组,然后再将它转换为一个对象数组,用一个更复杂的解析函数换取了较小的文件尺寸和更快的时间。数组形式的JSON 在每一项性能比较中均获胜,它文件尺寸最小,下载最快,平均解析时间最短。

事实上JSON可以被本地执行有几个重要的性能影响。当使用XHR时,JSON 数据作为一个字符串返回。该字符串通过()转换为一个本地对象。然而,当使用动态脚本标签插入时,JSON 数据被视为另一个JavaScript 文件并作为本地码执行。为做到这一点,数据必须被包装在回调函数之中,这就是所谓的JSONP(JSON填充)。

【示例5】下面示例代码使用JSONP 格式编写用户列表。

parseJSON([{
    "id" : 1,
    "username" :  "alice",
    "realname" :  "Alice ",
    "email" :  "alice@163.com"
}, {
    "id" : 2,
    "username" :  "bob",
    "realname" :  "Bob ",
    "email" :  "bob@163.com"
}, {
    "id" : 3,
    "username" :  "carol",
    "realname" :  "Carol",
    "email" :  "carol@163.com"
}, {
    "id" : 4,
    "username" :  "dave",
    "realname" :  "Dave ",
    "email" :  "dave@163.com"
}]);

因为回调包装的原因,JSONP略微增加了文件尺寸,但是与其在解析性能上的改进相比这点增加微不足道。由于数据作为本地JavaScript处理,它的解析速度与本地JavaScript 一样快。

JSONP文件大小和下载时间与XHR 测试基本相同,而解析时间几乎快了10倍。标准JSONP 的解析时间为0,因为根本用不着解析,它已经是本地格式了。简化版JSONP 和数组JSONP 也是如此,只是每种JSONP都需要转换成标准JSONP 直接使用的格式。

最快的JSON 格式是使用数组的JSONP 格式,虽然这种格式只比使用XHR 的JSON 略快,但是这种差异随着列表尺寸的增大而增大。如果所从事的项目需要一个由10000 或100000 个单元构成的列表,那么使用JSONP比使用JSON 好很多。