Data Formats 数据格式
When considering data transmission techniques, you must take into account several factors: feature set, compatibility, performance, and direction (to or from the server). When considering data formats, the only scale you need for comparison is speed.
在考虑数据传输技术时,你必须考虑这些因素:功能集,兼容性,性能,和方向(发给服务器或者从服务器接收)。在考虑数据格式时,唯一需要比较的尺度的就是速度。
There isn't one data format that will always be better than the others. Depending on what data is being transferred and its intended use on the page, one might be faster to download, while another might be faster to parse. In this section, we create a widget for searching among users and implement it using each of the four major categories of data formats. This will require us to format a list of users on the server, pass it back to the browser, parse that list into a native JavaScript data structure, and search it for a given string. Each of the data formats will be compared based on the file size of the list, the speed of parsing it, and the ease with which it's formed on the server.
没有哪种数据格式会始终比其他格式更好。根据传送什么数据、用于页面上什么目的,某种格式可能下载更快,另一种格式可能解析更快。在本节中,我们创建了一个窗口小部件用于搜索用户信息并用四种主流的数据格式实现它。这要求我们在服务器端格式化一个用户列表,将它返回给浏览器,将列表解析成JavaScript数据格式,并搜索特定的字符串。每种数据格式将比较列表的文件大小,解析速度,和服务器上构造它们的难易程度。
XML
When Ajax first became popular, XML was the data format of choice. It had many things going for it: extreme interoperability (with excellent support on both the server side and the client side), strict formatting, and easy validation. JSON hadn't been formalized yet as an interchange format, and almost every language used on servers had a library available for working with XML.
当Ajax开始变得流行起来它选择了XML数据格式。有很多事情是围绕着它做的:极端的互通性(服务器端和客户端都能够良好支持),格式严格,易于验证。(那时)JSON还没有正式作为交换格式,几乎所有的服务器端语言都有操作XML的库。
Here is an example of our list of users encoded as XML:
这里是用XML编码的用户列表的例子:
<?xml version="1.0" encoding='UTF-8'?>
<users total="4">
<user id="1">
<username>alice</username>
<realname>Alice Smith</realname>
<email>alice@alicesmith.com</email>
</user>
<user id="2">
<username>bob</username>
<realname>Bob Jones</realname>
<email>bob@bobjones.com</email>
</user>
<user id="3">
<username>carol</username>
<realname>Carol Williams</realname>
<email>carol@carolwilliams.com</email>
</user>
<user id="4">
<username>dave</username>
<realname>Dave Johnson</realname>
<email>dave@davejohnson.com</email>
</user>
</users>
Compared to other formats, XML is extremely verbose. Each discrete piece of data requires a lot of structure, and the ratio of data to structure is extremely low. XML also has a slightly ambiguous syntax. When encoding a data structure into XML, do you make object parameters into attributes of the object element or independent child elements? Do you make long, descriptive tag names, or short ones that are efficient but indecipherable? Parsing this syntax is equally ambiguous, and you must know the layout of an XML response ahead of time to be able to make sense of it.
与其他格式相比,XML极其冗长。每个离散的数据片断需要大量结构,所以有效数据的比例非常低。而且XML语法有些轻微模糊。当数据结构编码为XML之后,你将对象参数放在对象元素的属性中,还是放在独立的子元素中?标签名使用长命名或者短小高效却难以辨认的名字?语法解析同样含混,你必须先知道XML响应报文的布局,然后才能搞清楚它的含义。
In general, parsing XML requires a great deal of effort on the part of the JavaScript programmer. Aside from knowing the particulars of the structure ahead of time, you must also know exactly how to pull apart that structure and painstakingly reassemble it into a JavaScript object. This is far from an easy or automatic process, unlike the other three data formats.
一般情况下,解析XML要占用JavaScript程序员相当一部分精力。除了要提前知道详细结构之外,你还必须确切地知道如何解开这个结构然后精心地将它们写入JavaScript对象中。这远非易事且不能自动完成,不像其他三种数据格式那样。
Here is an example of how to parse this particular XML response into an object:
下面是如何将特定XML报文解析到对象的例子:
function parseXML(responseXML) {
var users = [];
var userNodes = responseXML.getElementsByTagName('users');
var node, usernameNodes, usernameNode, username,
realnameNodes, realnameNode, realname,
emailNodes, emailNode, email;
for (var i = 0, len = userNodes.length; i < len; i++) {
node = userNodes[i];
username = realname = email = '';
usernameNodes = node.getElementsByTagName('username');
if (usernameNodes && usernameNodes[0]) {
usernameNode = usernameNodes[0];
username = (usernameNodes.firstChild) ?
usernameNodes.firstChild.nodeValue : '';
}
realnameNodes = node.getElementsByTagName('realname');
if (realnameNodes && realnameNodes[0]) {
realnameNode = realnameNodes[0];
realname = (realnameNodes.firstChild) ?
realnameNodes.firstChild.nodeValue : '';
}
emailNodes = node.getElementsByTagName('email');
if (emailNodes && emailNodes[0]) {
emailNode = emailNodes[0];
email = (emailNodes.firstChild) ?
emailNodes.firstChild.nodeValue : '';
}
users[i] = {
id: node.getAttribute('id'),
username: username,
realname: realname,
email: email
};
}
return users;
}
As you can see, it requires checking each tag to ensure that it exists before reading its value. It is heavily dependent on the structure of the XML.
正如你所看到的,在读值之前,它需要检查每个标签以保证它存在。这在很大程度上依赖于XML的结构。
A more efficient approach would be to encode each of the values as an attribute of the <user> tag. This results in a smaller file size for the same amount of data. Here is an example of the user list with the values encoded as attributes:
一个更有效的方式是将每个值都存储为<user>标签的属性。数据相同而文件尺寸却更小。这个例子中的用户列表,将值放置在标签属性中:
<?xml version="1.0" encoding='UTF-8'?>
<users total="4">
<user id="1-id001" username="alice" realname="Alice Smith" email="alice@alicesmith.com" />
<user id="2-id001" username="bob" realname="Bob Jones" email="bob@bobjones.com" />
<user id="3-id001" username="carol" realname="Carol Williams" email="carol@carolwilliams.com" />
<user id="4-id001" username="dave" realname="Dave Johnson" email="dave@davejohnson.com" />
</users>
Parsing this simplified XML response is significantly easier:
解析此简化版XML响应报文要容易得多:
function parseXML(responseXML) {
var users = [];
var userNodes = responseXML.getElementsByTagName('users');
for (var i = 0, len = userNodes.length; i < len; i++) {
users[i] = {
id: userNodes[i].getAttribute('id'),
username: userNodes[i].getAttribute('username'),
realname: userNodes[i].getAttribute('realname'),
email: userNodes[i].getAttribute('email')
};
}
return users;
}
XPath
Though it is beyond the scope of this chapter, XPath can be much faster than getElementsByTagName when parsing an XML document. The caveat is that it is not universally supported, so you must also write fallback code using the older style of DOM traversal. At this time, DOM Level 3 XPath has been implemented by Firefox, Safari, Chrome, and Opera. Internet Explorer 8 has a similar but slightly less advanced interface.
虽然它超出了本章内容的范围,但XPath在解析XML文档时比getElementsByTagName快得多。需要注意的是,它并未得到广泛支持,所以你必须使用古老风格的DOM遍历方法编写备用代码。现在,DOM级别3的XPath已经被如下浏览器实现:Firefox,Safari,Chrome,和Opera。Internet Explorer 8有一个类似的但略微先进的接口。
Response sizes and parse times 响应报文大小和解析时间
Let's take a look at the performance numbers for XML in the following table.
让我们来看一看下表中的XML性能数据:
As you can see, using favoring attributes over child tags leads to a smaller file size and a significantly faster parse time. This is mostly due to the fact that you don't have to walk the DOM on the XML structure as much, and can instead simply read attributes.
正如你所看到的,与使用子标签相比,使用属性时文件尺寸更小,特别是解析时间更快。其原因很大程度上基于这样的事实:你不需要在XML结构上访问DOM那么多次,而只是简单地读取属性。
Should you consider using XML? Given its prevalence in public APIs, you often have no choice. If the data is only available in XML, you roll up your sleeves and write code to parse it. But if there is any other format available, prefer that instead. The performance numbers you see here for verbose XML are extremely slow compared to more advanced techniques. For browsers that support it, XPath would improve the parse time, but at the cost of writing and maintaining three separate code paths (one for browsers that support DOM Level 3 XPath, one for Internet Explorer 8, and one for all other browsers). The simple XML format compares more favorably, but is still an order of magnitude slower than the fastest format. XML has no place in high-performance Ajax.
你是否考虑使用XML?鉴于开发API如此流行使,你经常别无选择。如果数据只有XML格式可用,那么你卷起袖子写代码解析它吧。但是如果有其他格式可用,那么宁愿取代它。你在这里看到的标准XML的性能数据与更先进的技术相比,显得太慢了。如果浏览器支持的话,XPath可改善解析时间,但代价是编写并维护三个代码分支(为支持DOM级别3的XPath的浏览器写一个,为Internet Explorer 8写一个,为其他浏览器写一个)。简化XML格式更有利,但比那些最快的格式还是慢一个数量级。在高性能Ajax中没有XML的地位。
JSON
Formalized and popularized by Douglas Crockford, JSON is a lightweight and easy-to-parse data format written using JavaScript object and array literal syntax. Here is an example of the user list written in JSON:
通过Douglas Crockford的发明与推广,JSON是一个轻量级并易于解析的数据格式,它按照JavaScript对象和数组字面语法所编写。下例是用JSON书写的用户列表:
[
{"id":1, "username":"alice", "realname": "Alice Smith", "email":"alice@alicesmith.com"},
{"id":2, "username":"bob", "realname": "Bob Jones", "email":"bob@bobjones.com"},
{"id":3, "username":"carol", "realname": "Carol Williams","email":"carol@carolwilliams.com"},
{"id":4, "username":"dave", "realname": "Dave Johnson", "email":"dave@davejohnson.com"}
]
The users are represented as objects, and the list of users is an array, just as any other array or object would be written out in JavaScript. This means that when evaled or wrapped in a callback function, JSON data is executable JavaScript code. Parsing a string of JSON in JavaScript is as easy as using eval():
用户表示为一个对象,用户列表成为一个数组,与JavaScript中其他数组或对象的写法相同。这意味着如果它被包装在一个回调函数中,JSON数据可称为能够运行的JavaScript代码。在JavaScript中解析JSON可简单地使用eval():
function parseJSON(responseText) {
return eval('(' + responseText + ')');
}
Just as with XML, it is possible to distill this format into a simpler version. In this case, we can replace the attribute names with shortened (though less readable) versions:
正如XML那样,它也可以提炼成一个更简单的版本。这种情况下,我们可将名字缩短(尽管可读性变差):
[
{ "i": 1, "u": "alice", "r": "Alice Smith", "e": "alice@alicesmith.com" },
{ "i": 2, "u": "bob", "r": "Bob Jones", "e": "bob@bobjones.com" },
{ "i": 3, "u": "carol", "r": "Carol Williams", "e": "carol@carolwilliams.com" },
{ "i": 4, "u": "dave", "r": "Dave Johnson", "e": "dave@davejohnson.com" }
]
This gives us the same data with less structure and fewer bytes overall to transmit to the browser. We can even take it a step further and remove the attribute names completely. This format is even less readable than the other two and is much more brittle, but the file size is much smaller: almost half the size of the verbose JSON format.
它将相同的数据以更少的结构和更小的字节尺寸传送给浏览器。更进一步,我们干脆完全去掉属性名。与其他两种格式相比,这种格式可读性更差,但也更利索,文件尺寸非常小:大约只有标准JSON格式的一半。
[
[ 1, "alice", "Alice Smith", "alice@alicesmith.com" ],
[ 2, "bob", "Bob Jones", "bob@bobjones.com" ],
[ 3, "carol", "Carol Williams", "carol@carolwilliams.com" ],
[ 4, "dave", "Dave Johnson", "dave@davejohnson.com" ]
]
Successful parsing requires that the order of the data must be maintained. That being said, it is trivial to convert this format into one that maintains the same attribute names as the first JSON format:
解析过程需要保持数据的顺序。也就是说,它在进行格式转换时必须保持和第一个JSON格式一样的属性名:
function parseJSON(responseText) {
var users = [];
var usersArray = eval('(' + 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;
}
In this example, we use eval() to convert the string into a native JavaScript array. That array of arrays is then converted into an array of objects. Essentially, you are trading a smaller file size and faster eval() time for a more complicated parse function. The following table lists the performance numbers for the three JSON formats, transferred using XHR.
在这个例子中,我们使用eval()将字符串转换为一个本地JavaScript数组。然后再将它转换到一个对象数组,本质上讲,你用一个更复杂的解析函数换取了较小的文件尺寸和更快的eval()时间。下表列出这三种JSON格式的性能数据,以XHR传输。
JSON formed using arrays wins every category, with the smallest file size, the fastest average download time, and the fastest average parse time. Despite the fact that the parse function has to iterate through all 5,000 entries in the list, it is still more than 30% faster to parse.
数组形式的JSON在每一项中均获胜,它文件尺寸最小,下载最快,平均解析时间最短。尽管解析函数不得不遍历列表中所有5'000个单元,它还是快出了30%。
JSON-P
The fact that JSON can be executed natively has several important performance implications. When XHR is used, JSON data is returned as a string. This string is then evaluated using eval() to convert it into a native object. However, when dynamic script tag insertion is used, JSON data is treated as just another JavaScript file and executed as native code. In order to accomplish this, the data must be wrapped in a callback function. This is known as "JSON with padding," or JSON-P. Here is our user list formatted as JSON-P:
事实上JSON可被本地执行有几个重要的性能影响。当使用XHR时JSON数据作为一个字符串返回。该字符串使用eval()转换为一个本地对象。然而,当使用动态脚本标签插入时,JSON数据被视为另一个JavaScript文件并作为本地码执行。为做到这一点,数据必须被包装在回调函数之中。这就是所谓的“JSON填充”或JSON-P。下面是我们用JSON-P格式书写的用户列表:
parseJSON([
{"id":1, "username":"alice", "realname":"Alice Smith", "email":"alice@alicesmith.com"},
{"id":2, "username":"bob", "realname":"Bob Jones", "email":"bob@bobjones.com"},
{"id":3, "username":"carol", "realname":"Carol Williams", "email":"carol@carolwilliams.com"},
{"id":4, "username":"dave", "realname":"Dave Johnson", "email":"dave@davejohnson.com"}
]);
JSON-P adds a small amount to the file size with the callback wrapper, but such an increase is insignificant compared to the improved parse times. Since the data is treated as native JavaScript, it is parsed at native JavaScript speeds. Here are the same three JSON formats transmitted as JSON-P.
JSON-P因为回调包装的原因略微增加了文件尺寸,但与其解析性能的改进相比这点增加微不足道。由于数据作为本地JavaScript处理,它的解析速度像本地JavaScript一样快。下面是JSON-P传输三种JSON数据的时间:
File sizes and download times are almost identical to the XHR tests, but parse times are almost 10 times faster. The parse time for verbose JSON-P is zero, since no parsing is needed; it is already in a native format. The same is true for simple JSON-P and array JSON-P, but each had to be iterated through to convert it to the format that verbose JSON-P gives you naturally.
文件大小和下载时间与XHR测试基本相同,而解析时间几乎快了10倍。标准JSON-P的解析时间为0,因为根本用不着解析,它已经是本地格式了。简化版JSON-P和数组JSON-P也是如此,只是每种都需要转换成标准JSON-P直接给你的那种格式。
The fastest JSON format is JSON-P formed using arrays. Although this is only slightly faster than JSON transmitted using XHR, that difference increases as the size of the list grows. If you are working on a project that requires a list with 10,000 or 100,000 elements in it, favor JSON-P over JSON.
最快的JSON格式是使用数组的JSON-P格式。虽然这只比使用XHR的JSON略快,但是这种差异随着列表尺寸的增大而增大。如果你所从事的项目需要一个10'000或100'000个单元构成的列表,那么JSON-P比JSON好很多。
There is one reason to avoid using JSON-P that has nothing to do with performance: since JSON-P must be executable JavaScript, it can be called by anyone and included in any website using dynamic script tag insertion. JSON, on the other hand, is not valid JavaScript until it is evaled, and can only be fetched as a string using XHR. Do not encode any sensitive data in JSON-P, because you cannot ensure that it will remain private, even with random URLs or cookies.
还有一个与性能无关的原因要避免使用JSON-P:因为JSON-P必须是可执行的JavaScript,它使用动态脚本标签注入技术可在任何网站中被任何人调用。从另一个角度说,JSON在运行之前并不是有效的JavaScript,使用XHR时只是被当作字符串获取。不要将任何敏感的数据编码为JSON-P,因为你无法确定它是否包含私密信息,或者包含随机的URL或cookie。
Should you use JSON? 你应该使用JSON吗?
JSON has several advantages when compared to XML. It is a much smaller format, with less of the overall response size being used as structure and more as data. This is especially true when the data contains arrays rather than objects. JSON is extremely interoperable, with encoding and decoding libraries available for most server-side languages. It is trivial to parse on the client side, allowing you to spend more time writing code to actually do something with the data. And, most importantly for web developers, it is one of the best performing formats, both because it is relatively small over the wire and because it can be parsed so quickly. JSON is a cornerstone of high-performance Ajax, especially when used with dynamic script tag insertion.
与XML相比JSON有许多优点。这种格式小得多,在总响应报文中,结构占用的空间更小,数据占用的更多。特别是数据包含数组而不是对象时。JSON与大多数服务器端语言的编解码库之间有着很好的互操作性。它在客户端的解析工作微不足道,使你可以将更多写代码的时间放在其他数据处理上。对网页开发者来说最重要的是,它是表现最好的格式之一,即因为在线传输相对较小,也因为解析十分之快。JSON是高性能Ajax的基石,特别是使用动态脚本标签插入时。
HTML
Often the data you are requesting will be turned into HTML for display on the page. Converting a large data structure into simple HTML can be done relatively quickly in JavaScript, but it can be done much faster on the server. One technique to consider is forming all of the HTML on the server and then passing it intact to the client; the JavaScript can then simply drop it in place with innerHTML. Here is an example of the user list encoded as HTML:
通常你所请求的数据以HTML返回并显示在页面上。JavaScript能够比较快地将一个大数据结构转化为简单的HTML,但是服务器完成同样工作更快。一种技术考虑是在服务器端构建整个HTML然后传递给客户端,JavaScript只是简单地下载它然后放入innerHTML。下面是用HTML编码用户列表的例子:
<ul class="users">
<li class="user" id="1-id002">
<a href="http://www.site.com/alice/" class="username">alice</a>
<span class="realname">Alice Smith</span>
<a href="mailto:alice@alicesmith.com" class="email">alice@alicesmith.com</a>
</li>
<li class="user" id="2-id002">
<a href="http://www.site.com/bob/" class="username">bob</a>
<span class="realname">Bob Jones</span>
<a href="mailto:bob@bobjones.com" class="email">bob@bobjones.com</a>
</li>
<li class="user" id="3-id002">
<a href="http://www.site.com/carol/" class="username">carol</a>
<span class="realname">Carol Williams</span>
<a href="mailto:carol@carolwilliams.com" class="email">carol@carolwilliams.com</a>
</li>
<li class="user" id="4-id002">
<a href="http://www.site.com/dave/" class="username">dave</a>
<span class="realname">Dave Johnson</span>
<a href="mailto:dave@davejohnson.com" class="email">dave@davejohnson.com</a>
</li>
</ul>
The problem with this technique is that HTML is a verbose data format, more so even than XML. On top of the data itself, you could have nested HTML tags, each with IDs, classes, and other attributes. It's possible to have the HTML formatting take up more space than the actual data, though that can be mitigated by using as few tags and attributes as possible. Because of this, you should use this technique only when the client-side CPU is more limited than bandwidth.
此技术的问题在于,HTML是一种详细的数据格式,比XML更加冗长。在数据本身的最外层,可有嵌套的HTML标签,每个都具有ID,类,和其他属性。HTML格式可能比实际数据占用更多的空间,尽管可通过尽量少用标签和属性缓解这一问题。正因为这个原因,你只有当客户端CPU比带宽更受限时才使用此技术。
On one extreme, you have a format that consists of the smallest amount of structure required to parse the data on the client side, such as JSON. This format is extremely quick to download to the client machine; however, it takes a lot of CPU time to convert this format into HTML to display on the page. A lot of string operations are required, which are one of the slowest things you can do in JavaScript.
一种极端情况是,你有一种格式包含最少数量的结构,需要在客户端解析数据,例如JSON。这种格式下载到客户机非常快,然而它需要很多CPU时间转化成HTML以显示在页面上。这需要很多字符串操作,而字符串操作也是JavaScript最慢的操作之一。
On the other extreme, you have HTML created on the server. This format is much larger over the wire and takes longer to download, but once it's downloaded, displaying it on the page requires a single operation:
另一种极端情况是,你在服务器上创建HTML。这种格式在线传输数据量大,下载时间长,但一旦下载完,只需一个操作就可以显示在页面上:
document.getElementById('data-container').innerHTML = req.responseText;
The following table shows the performance numbers for the user list encoded using HTML. Keep in mind the main different between this format and all others: "parsing" in this case refers to the action of inserting the HTML in the DOM. Also, HTML cannot be easily or quickly iterated through, unlike a native JavaScript array.
下表显示了使用HTML编码用户列表时的性能数据。请记住这种格式与其他几种格式的差别:“解析”在这种情况下指的是将HTML插入DOM的操作。此外,HTML不能像本地JavaScript数组那样轻易迅速地进行迭代操作。
As you can see, HTML is significantly larger over the wire, and also takes a long time to parse. This is because the single operation to insert the HTML into the DOM is deceptively simple; despite the fact that it is a single line of code, it still takes a significant amount of time to load that much data into a page. These performance numbers do deviate slightly from the others, in that the end result is not an array of data, but instead HTML elements displayed on a page. Regardless, they still illustrate the fact that HTML, as a data format, is slow and bloated.
正如你所看到的,HTML传输数据量明显偏大,也需要长时间来解析。因为将HTML插入到DOM的单一操作看似简单,尽管它只有一行代码,却仍需要时间向页面加载很多数据。与其他测试相比这些性能数据确实有轻微的偏差,最终结果不是数据数组,而是显示在页面上的HTML元素。无论如何,它们仍显示出HTML的一个事实:作为数据格式,它缓慢而且臃肿。
Custom Formatting 自定义格式
The ideal data format is one that includes just enough structure to allow you to separate individual fields from each other. You can easily make such a format by simply concatenating your data with a separator character:
最理想的数据格式只包含必要的结构,使你能够分解出每个字段。你可以自定义一种格式只是简单地用一个分隔符将数据连结起来:
Jacob;Michael;Joshua;Matthew;Andrew;Christopher;Joseph;Daniel;Nicholas;Ethan;William;Anthony;Ryan;David;Tyler;John
These separators essentially create an array of data, similar to a comma-separated list. Through the use of different separators, you can create multidimensional arrays. Here is our user list encoded as a character-delimited custom format:
这些分隔符基本上创建了一个数据数组,类似于一个逗号分隔的列表。通过使用不同的分隔符,你可以创建多维数组。这里是用自定义的字符分隔方式构造的用户列表:
1:alice:Alice Smith:alice@alicesmith.com;
2:bob:Bob Jones:bob@bobjones.com;
3:carol:Carol Williams:carol@carolwilliams.com;
4:dave:Dave Johnson:dave@davejohnson.com
This type of format is extremely terse and offers a very high data-to-structure ratio (significantly higher than any other format, excluding plain text). Custom formats are quick to download over the wire, and they are fast and easy to parse; you simply call split() on the string, using your separator as the argument. More complex custom formats with multiple separators require loops to split all the data (but keep in mind that these loops are extremely fast in JavaScript). split() is one of the fastest string operations, and can typically handle separator-delimited lists of 10,000+ elements in a matter of milliseconds. Here is an example of how to parse the preceding format:
这种格式非常简洁,与其他格式相比(不包括纯文本),其数据/结构比例明显提高。自定义格式下载迅速,易于解析,只需调用字符串的split()将分隔符作为参数传入即可。更复杂的自定义格式具有多种分隔符,需要在循环中分解所有数据(但是请记住,在JavaScript中这些循环是非常快的)。split()是最快的字符串操作之一,通常可以在数毫秒内处理具有超过10'000个元素的“分隔符分割”列表。下面的例子给出解析上述格式的方法:
function parseCustomFormat(responseText) {
var users = [];
var usersEncoded = responseText.split(';');
var userArray;
for (var i = 0, len = usersEncoded.length; i < len; i++) {
userArray = usersEncoded[i].split(':');
users[i] = {
id: userArray[0],
username: userArray[1],
realname: userArray[2],
email: userArray[3]
};
}
return users;
}
When creating you own custom format, one of the most important decisions is what to use as the separators. Ideally, they should each be a single character, and they should not be found naturally in your data. Low-number ASCII characters work well and are easy to represent in most server-side languages. For example, here is how you would use ASCII characters in PHP:
当创建你的自定义格式时,最重要的决定是采用何种分隔符。理想情况下,它应当是一个单字符,而且不能存在于你的数据之中。ASCII字符表中前面的几个字符在大多数服务器端语言中能够正常工作而且容易书写。例如,下面讲述如何在PHP中使用ASCII码:
function build_format_custom($users) {
$row_delimiter = chr(1); // /u0001 in JavaScript.
$field_delimiter = chr(2); // /u0002 in JavaScript.
$output = array();
foreach ($users as $user) {
$fields = array($user['id'], $user['username'], $user['realname'], $user['email']);
$output[] = implode($field_delimiter, $fields);
}
return implode($row_delimiter, $output);
}
These control characters are represented in JavaScript using Unicode notation (e.g., /u0001). The split() function can take either a string or a regular expression as an argument. If you expect to have empty fields in your data, then use a string; if the delimiter is passed as a regular expression, split() in IE ignores the second delimiter when two are right next to each other. The two argument types are equivalent in other browsers.
这些控制字符在JavaScript中使用Unicode标注(例如,/u0001)表示。split()函数可以用字符串或者正则表达式作参数。如果你希望数据中存在空字段,那么就使用字符串;如果分隔符是一个正则表达式,IE中的split()将跳过相邻两个分隔符中的第二个分隔符。这两种参数类型在其他浏览器上等价。
// Regular expression delimiter.
var rows = req.responseText.split(//u0001/);
// String delimiter (safer).
var rows = req.responseText.split("/u0001");
Here are the performance numbers for a character delimited custom format, using both XHR and dynamic script tag insertion:
这里是字符分隔的自定义格式的性能数据,使用XHR和动态脚本标签注入:
Either XHR or dynamic script tag insertion can be used with this format. Since the response is parsed as a string in both cases, there is no real difference in performance. For very large datasets, it's hands down the fastest format, beating out even natively executed JSON in parse speed and overall load time. This format makes it feasible to send huge amounts of data to the client side in a very short amount of time.
XHR和动态脚本标签注入都可以使用这种格式。两种情况下都要解析字符串,在性能上没有实质上的差异。对于非常大的数据集,它是最快的传输格式,甚至可以在解析速度和下载时间上击败本机执行的JSON。用此格式向客户端传送大量数据只用很少的时间。