【问题标题】:What are some best practices for client-server interaction?客户端-服务器交互的一些最佳实践是什么?
【发布时间】:2011-12-22 18:38:05
【问题描述】:

我正在构建一个工作网站,其中一个更重要的功能是显示数据的丰富内容网格。默认情况下,它每页仅显示 20 个项目,但我们在数据库中有大约 200 个项目可以过滤、排序和搜索。

我们的销售和营销团队还要求提供“列出所有”功能,以便他们可以在一个地方显示所有数据并滚动浏览而不是翻阅数据。

整个系统在服务器端使用 ASP.Net MVC,在客户端使用 jQuery 和 Flexigrid 构建,并使用 JSON 通过 AJAX 在两者之间交换数据。

我已经把实际的数据传输部分搞定了。包含 20 个结果的页面对整个请求需要 800 毫秒(通过 Flexigrid 向服务器发布请求并获取响应)。更多的是客户端处理需要一段时间。

我可以将一些客户端处理卸载到服务器。但这会使服务器端操作花费更长的时间,并使返回的文档的大小变得更大。在高速互联网连接的情况下这不是问题......但不一定是这种情况。

我的另一个选择是下载尽可能多的数据并将大部分数据处理转移到客户端。这将请求时间减少到基本上为零(仅获取更改的元素而不是整个数据集)。它在具有快速 CPU 和大量 RAM 的机器上运行良好,但也不一定如此。

由于至少有人将此标记为“不是一个真正的问题”,所以让我澄清一下......

  • 我可以做些什么来缓解客户端处理时间问题,而不会将太多的处理转移到服务器上,最终导致数据传输时间问题?
  • 在平衡客户端处理和服务器端处理方面有哪些最佳做法?
  • 是在服务器端出错还是在客户端出错?
  • 我可以使用哪些工具来更好地优化这些交换,以免事情继续出错?

【问题讨论】:

    标签: asp.net-mvc ajax flexigrid


    【解决方案1】:

    您在客户端处理什么需要这么长时间?处理 JSON 对象(即使是非常大的对象)不应过于密集。

    在编写数据客户端时进行大量 DOM 查找可能会减慢速度。减少 DOM 查找可以极大地提高性能。我相信平衡服务器和客户端处理的良好做法是在服务器上出错。由于服务器在您的控制之下,您始终可以选择升级您的服务器。将大部分处理工作保留在服务器上还可以让移动设备和旧计算机更轻松。

    您应该以增强用户体验的方式利用 AJAX 和客户端功能。根据用户的要求加载和处理数据。通过仅加载他们请求的内容,您可以减少服务器和客户端的负载。

    如果您还一遍又一遍地请求相同类型的数据,您可以查看服务器和客户端缓存。通过利用缓存,您可以减少请求时间和/或带宽。

    【讨论】:

    • 服务器向客户端发送一个 JSON 对象。然后将 JSON 对象加载到 Flexigrid 中。 Flexigrid 本身将对象读入表格,然后执行一些昂贵的document.createElement() 操作来格式化表格以供显示。它将对象转换为一个非常密集的 HTML 表格。
    【解决方案2】:

    事实证明,问题更多在于客户端的 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 用户格式化服务器端听起来是个好主意。
    • 我经历并重写了一些东西,以便在 AJAX 请求中发送整个表。在原来的系统中,只发送数据,使用 JS 处理并填充表格。一方面,我现在在 XHR 响应中发送 10 倍的信息。另一方面,页面在 IE 中的加载速度是可靠的 10 倍。
    【解决方案3】:

    我可以做些什么来缓解客户端处理时间问题,而不会将太多的处理转移到服务器上,以至于我最终会遇到数据传输时间问题?

    数据是否来自数据库?如果是这样,请限制那里的数据。这是db擅长的。我使用 flexigrid 并将所有分页排序和过滤保留在那里。 db 仅返回按请求排序和过滤的所需数据。服务器只需返回它,客户端只需渲染它。

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

    尽可能保持客户端光线充足

    在服务器端还是在客户端出错更好?

    是的,服务器功能更强大

    我可以使用哪些工具来更好地优化这些交换,以免事情继续出错?

    IE 开发人员工具使用网络选项卡查看网络上的内容

    【讨论】:

    • 这不是问题。分页、排序和过滤都在服务器上完成。但是当数据集是 200+ 行 30+ 列时,客户端渲染在 IE 上会显着变慢。这与 Flexigrid 中编码不良的事件处理程序有很大关系,而不是数据本身。
    • 如果数据被服务器端限制,那么客户端将永远不会收到这么大的数据集。例如客户端只会收到一页数据。当用户单击下一页时,flexigrid 会回调服务器并获取下一页。除非你想在一页上显示 200 多行???
    • 分页默认设置为在一页上限制为 5、10、15 或 20 个结果。但正如我在最初的问题中所说,销售/营销团队特别要求“查看全部”选项以在单个页面上显示所有数据。这是我尝试调试的“查看全部”时的性能。
    猜你喜欢
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 2012-05-24
    • 2021-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多