客户端和服务器交互的最佳实践有哪些?

9
我正在为工作建立一个网站,其中一个更重要的功能是显示数据的丰富内容网格。默认情况下,每页仅显示20个项目,但我们的数据库中有大约200个可以进行过滤、排序和搜索的项目。
我们的销售和市场团队还要求具有“全部列出”的功能,以便他们可以在一个地方显示所有数据并滚动而不是翻页查看数据。
整个系统是在服务器端使用ASP.Net MVC构建的,在客户端使用jQuery和Flexigrid,并使用JSON通过AJAX交换数据。
我已经相当确定了实际的数据传输部分。20个结果的页面需要800毫秒才能完成整个请求(通过Flexigrid向服务器POST请求并获取响应)。更多的是客户端处理需要一段时间。
我可以将一些客户端处理转移到服务器上。但这会使服务器端操作花费更长的时间,并使返回的文档大小变得更大。在高速互联网连接的情况下不会有问题...但这并不一定是这种情况。
我拥有的另一个选择是尽可能多地下载数据并将大部分数据处理转移到客户端。这将把请求时间削减到基本上为零(仅获取更改的元素而不是整个数据集)。它将在CPU快速且具有大量RAM的计算机上运行得非常好,但这也不一定是这种情况。
既然至少有一个人将其标记为“不是一个真正的问题”,让我澄清一下...
- 我可以采取什么措施来缓解客户端处理时间问题,而不会将太多处理转移到服务器,以至于最终出现数据传输时间问题? - 在平衡客户端处理和服务器端处理时,有哪些最佳实践? - 是更倾向于服务器还是客户端更好? - 有哪些工具可以用来更好地优化这些交换,以使事情不再出错?
3个回答

2
你在客户端处理什么需要花费这么长时间?处理JSON对象(即使是非常大的对象)也不应该过于繁重。
写入数据时,进行了很多DOM查找可能会减慢速度。减少DOM查找可以极大地帮助性能。我认为,在平衡服务器和客户端处理方面的良好实践是在服务器上出错。由于服务器在你的控制下,你可以随时选择升级你的服务器。将大部分处理保留在服务器上也会使移动设备和旧计算机更加容易。
你应该利用AJAX和客户端能力来增强用户体验。按照用户请求的方式加载和处理数据。只加载他们请求的内容,可以减少服务器和客户端的负载。
如果你也在反复请求相同类型的数据,你可以考虑使用服务器和客户端缓存。通过利用缓存,可以减少请求时间和/或带宽。

服务器向客户端发送一个JSON对象。然后将该JSON对象加载到Flexigrid中。Flexigrid本身会将该对象读入表格,然后执行一些昂贵的document.createElement()操作以格式化表格以供显示。它将对象转换为HTML表格是如此密集的过程。 - EAMann

1
事实证明,问题更多地与客户端JavaScript引擎有关,而不是我正在处理的数据。我花了大部分时间来对过程进行基准测试,并计时各种操作。
在Chrome中,所有东西都运行得很快。在Firefox中,所有东西都运行得相当快(虽然不如Chrome快)。真正的性能滞后者是Internet Explorer。
当我加载整个数据集 - 所有200行 - Flexigrid尝试对表格中的每个单元格进行一些后处理。正如您在屏幕截图中看到的那样,每行有29个单元格...因此我们需要查看总共5800次格式化操作。
我能够从较低级别的单元格循环中提取一些更昂贵的操作(即创建jQuery对象),以便它们每行只运行一次,但最终我仍然遇到了与IE相关的性能问题。
为了给您一些现实世界的基准,我将代码设置为在达到某些事件之前输出总时间:
  • populate 在浏览器首次发送XHR请求时触发
  • addData 在请求返回并在JSON对象解析之前触发
  • addCellProp 在数据初始解析后迭代遍历表格中的每个单元格时触发
  • done 在所有操作完成后触发

处理20行数据(默认):

------------------------------------------------------
| browser | populate | addData | addCellProp | done  |
------------------------------------------------------
| Chrome  | 0        | 84      | 123         | 286   |
| IE9     | 0        | 151     | 309         | 799   |
| IE8     | 0        | 226     | 481         | 1105  |

正在处理完整的数据集(此机器上有179行):

------------------------------------------------------
| browser | populate | addData | addCellProp | done  |
------------------------------------------------------
| Chrome  | 0        | 318     | 669         | 1963  |
| IE9     | 0        | 157     | 1813        | 9428  |
| IE8     | 0        | 229     | 2188        | 13335 |

最耗费时间的操作在于addCellPropdone之间。我已经尽可能地提高了代码的效率,但是当您在运行这么多次数据集时,特别是在操作DOM时,你所能做的只有那么多。

我修改了Flexigrid(尽管有很多不建议这样做的建议),使其尽可能少地触及DOM,实际上加快了速度。当我开始进行这项研究时,IE9需要20到30秒才能触发done事件。

不幸的真相是,并非所有平台都是平等的,而且IE似乎不是处理此类显示内数据的最佳引擎。

更好的方法可能是在服务器端创建和操作HTML表格,并在IE用户请求时将整个东西(标记和所有内容)发送到浏览器,而不是依靠IE从原始JSON对象中创建标记。


每个事件的跨浏览器基准测试真的很有启发性。它确实有助于澄清问题的根源。为IE用户在服务器端进行格式化听起来是一个可靠的想法。 - Kevin M
我已经仔细检查并重写了代码,以便整个表格在AJAX请求中一次性发送。在原始系统中,只有数据被发送,并使用JS来处理并填充表格。一方面,现在在XHR响应中发送了10倍的信息。另一方面,在IE中页面加载速度可靠地提高了10倍。 - EAMann

0

我有什么办法可以缓解客户端处理时间问题,而不会将太多处理转移到服务器,导致数据传输时间问题?

如果数据来自数据库,那么请在数据库中限制数据。这是数据库的优点。我使用flexigrid并将所有分页、排序和过滤都保留在那里。数据库只返回所请求的已排序和过滤的必需数据。服务器只需要返回它,客户端只需要呈现它。

在平衡客户端处理和服务器端处理方面,有哪些最佳实践?

尽可能保持客户端轻量化。

在服务器端或客户端方面犯错误更好?

是的,服务器拥有更强大的能力。

有哪些工具可以用来更好地优化这些交换,以便事情不会继续出错?

IE开发人员工具使用网络选项卡查看传输内容。


这不是问题所在。分页、排序和过滤都是在服务器上完成的。但当数据集超过200行30列时,IE浏览器上客户端渲染速度会显著减慢。这与Flexigrid中编码不良的事件处理程序有很大关系,而不是数据本身。 - EAMann
如果数据在服务器端受到限制,那么客户端将永远不会接收到如此大的数据集。例如,客户端只会接收一页的数据。当用户点击下一页时,Flexigrid会回调服务器并获取下一页的数据。除非您想在一个页面上显示200多行? - Leigh Ciechanowski
分页默认设置为每页限制显示5、10、15或20个结果。但正如我在最初的问题中所指出的,销售/营销团队特别要求提供“查看全部”选项,以便在单个页面上显示所有数据。我试图调试的是执行“查看全部”时的性能问题。 - EAMann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接