什么更快? Ajax 加载 JSON 或 Ajax 加载完整输出

Posted

技术标签:

【中文标题】什么更快? Ajax 加载 JSON 或 Ajax 加载完整输出【英文标题】:What's faster? Ajax loading JSON or Ajax loading complete output 【发布时间】:2011-07-14 01:22:40 【问题描述】:

我想看到对此的不同看法/意见。

我让 Jquery 通过 ajax 调用一个函数。它以两种方式加载数据:

    ajax 脚本从同一个服务器加载 JSON 数据,然后使用 JS 解析并附加到 html 中。

    ajax 脚本通过调用的 php 脚本直接加载完整的 html / 脚本设置,然后 JS 将其附加到 html div。

我假设 #1 更快,因为它加载一个基本的 JSON 数组,然后使用 JS 解析它并附加到 html。

意见?

谢谢!

【问题讨论】:

它是什么样的数据,数据/标记比率是多少? 【参考方案1】:

您应该使用 document.createDocumentFragment 会带来更好的性能。附加到这个片段只会占用内存,并且在你准备好之前不会修改 DOM 本身。我相信 document.createElement 仍然优于 innerHTML,因为它绕过了字符串解析。您总是可以运行一堆基准测试来查看结果。

基准:http://jsperf.com/innertext-vs-fragment 来源:https://developer.mozilla.org/en-US/docs/Web/API/document.createDocumentFragment

【讨论】:

【参考方案2】:

有很多变数。 #1 可能会更快,前提是您的 javascript 不是零散地组装结果并假设数据明显小于等效标记。如果您正在零碎地组装结果,或者如果数据不比标记小很多,那么它可能会更慢。它还取决于用户的网络连接速度与他们的 CPU 和浏览器的速度(Chrome 相当快,IE7 相当慢)等。

关于零碎的事情:例如,如果您正在加载一个 200 行的表,并且您正在构建这样的行:

// ...stuff that initializes `tableBody` and clears out old stuff...
for (index = 0; index < stuff.length; ++index) 
    tr = $("tr");
    tr.append("td").html(stuff[i].a);
    tr.append("td").html(stuff[i].b);
    tr.append("td").html(stuff[i].c);
    tableBody.append(tr);

...那么与浏览器通过等效标记的方式相比,这可能会相当慢。

但是,如果您的做法更像这样:

markup = [];
for (index = 0; index < stuff.length; ++index) 
    markup.push("<tr>");
    markup.push("<td>" + stuff[i].a + "</td>");
    markup.push("<td>" + stuff[i].b + "</td>");
    markup.push("<td>" + stuff[i].c + "</td>");
    markup.push("</tr>");

tableBody.append(markup.join(""));

...您的状态更好,因为您可以最大限度地利用浏览器快速解析 HTML 的能力(从根本上说,浏览器的功能和优化目标)。

乍一看,与直接使用 DOM 方法或 jQuery 构建结构相比,构建字符串然后将其交给浏览器可能更快(甚至明显更快),这似乎有点违反直觉。但你想得越多,就越明显(是的,我已经测试过它)为什么会这样。 DOM 是浏览器必须映射到其内部结构的抽象,并且您对 DOM 方法的每次调用都会跨越 JavaScript 和浏览器的 DOM 引擎之间的边界层。相比之下,添加到数组很快,join 很快(即使字符串 concat 在现代浏览器上也很快)。给浏览器一个完整的字符串可以使层之间的行程最小化,并让浏览器直接构建其内部结构,而不用担心它们的 DOM 等价物(直到/除非你以后要求它们)。我最后一次测试这个是几年前,结果是戏剧性的。我应该用当前的浏览器再试一次;不过今天没时间……

【讨论】:

这是一个 10 行的输出。所以这是非常基础的。事实上,我最初设置了您提供的第二种方式,但我改为第一种,认为它更快。我想我需要尝试一下;如果差异小于 100 毫秒,则无需乱用它。 @Michael:如果是 10 行,我们就说必须有 很多 列或涉及非常非常复杂的结构,您才能注意到差异。 :-) 这与在内存中构建精确的 DOM 对象相比如何?标记 = $("
");使用 .append() 到“标记”,然后附加到实际的 DOM?
@iivel:对不起,我不明白你要我比较的东西。 @T.J. - 我想知道将字符串推入数组与在内存中构建 DOM 对象是否存在明显的性能差异。如果你还没有测试的话,我得在有时间的时候把一些东西弄出来。【参考方案3】:

基准测试会告诉您什么是最快的。

【讨论】:

【参考方案4】:

不久前我自己的经验发现,使用innerHTML 构建大块HTML 比使用document.createElement() 构建它要快得多。它快得多了,我什至不再费心编写速度测试了。对于小而浅的结构,速度差异可以忽略不计,对于他们来说,我仍然会使用createElement(),但任何更复杂的东西都会作为字符串转储。

以前我对innerHTML 持怀疑态度,所以当我坐下来编写测试时,我感到很惊讶。

我建议您自己尝试并编写自己的速度测试。

【讨论】:

【参考方案5】:

这个问题的答案取决于许多因素,包括:

客户端计算机速度(旧机器通常会因复杂的 JS 解析和计算而窒息) 网络速度和生成内容的大小(这主要适用于转化为更大的结果 html 的大型数据集) 函数正在执行的数据操作的性质

【讨论】:

一般来说,在一个基本的数据集输出上,你会推荐只使用常规的 php 渲染吗?我现在的输出非常基本;不超过 10 行数据,每行每个值不超过 128 个字符。 @Michael:这真的取决于。标记和数据的分离通常是一个好主意,只要缺点不超过优点(请参阅上面的一些潜在问题)。从您的评论来看,您所做的事情相当微不足道,因此尽早加强良好实践并将数据与标记分开应该不会有什么坏处。只是我的 2c :)【参考方案6】:

不可能说这两种解决方案中的哪一种更快:这完全取决于您在做什么,无论是在 PHP 端还是在 JS 端。

您应该考虑的主要是开发这些解决方案的难度——以及是否意味着重复一些工作:

PHP 在您的服务器上运行;你控制环境;并且不必针对每种浏览器调整您的代码 如果您使用 Ajax 显示某些内容,您可能也希望显示使用非 Ajax 的内容 - 这意味着您可能已经有一些 PHP 代码来呈现它;如果是这样的话,在 JS 中复制它可能需要更多的工作才能重新使用它。

在你的服务器上做事意味着:

可能需要更多的网络使用:发送 HTML 而不是数据可能意味着更大的负载 - 但使用压缩,这应该不会产生太大的影响。 您的服务器上的负载要多一些(不过,您可以缓存一些内容)- 但渲染通常比从数据库中获取数据消耗的资源更少

最后,如果我能指出我在这个问题上给出的答案:Why is it a bad practice to return generated HTML instead of JSON? Or is it?

【讨论】:

以上是关于什么更快? Ajax 加载 JSON 或 Ajax 加载完整输出的主要内容,如果未能解决你的问题,请参考以下文章

AJAX和JSON

Ajax和JSON

ajax3

在线游戏,或者比 ajax 更快的东西来发送/接收数据

ajax 请求的 json vs xml 的优缺点是啥? [关闭]

AJAX