客户机-服务器交互的一些最佳实践是什么?

时间:2021-03-30 20:03:18

I'm building a website for work, and one of the more important features is a rich content grid displaying data. By default, it only displays 20 items per page, but we have ~200 items in the database that can be filtered, sorted, and searched.

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

Our sales and marketing team has also requests a "list all" feature so they can display all of the data in one place and scroll through rather than page through the data.

我们的销售和营销团队也要求“列出所有”功能,这样他们就可以在一个地方显示所有的数据,而不是通过数据浏览页面。

客户机-服务器交互的一些最佳实践是什么?

This entire system is built using ASP.Net MVC on the server side, jQuery and Flexigrid on the client side, and uses JSON to exchange data between the two via AJAX.

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

I've gotten the actual data transfer part pretty solid. A page of 20 results takes 800ms for the entire request (POST a request to the server via Flexigrid and get the response). It's more the client-side processing that takes a while.

我已经得到了实际的数据传输部分。一个包含20个结果的页面需要为整个请求花费800ms(通过Flexigrid向服务器发送请求并获得响应)。这是需要一段时间的客户端处理。

I could offload some of the client-side processing to the server. But this would make the server-side operation take longer and make the size of the document returned that much larger. Not a problem in situations with a high-speed Internet connection ... but that's not necessarily the case.

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

The other option I have is to download as much data as possible and shift the majority of the data processing to the client. This cuts the request time down to basically nil (only fetching changed elements rather than the entire data set). It will work pretty well on machines with fast CPUs and a lot of RAM, but that's not necessarily the case, either.

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

Since at least one person flagged this as "not a real question," let me clarify ...

既然至少有一个人认为这不是一个真正的问题,让我澄清一下……

  • What can I possibly do to alleviate the client-side processing time issues without moving so much processing to the server that I end up with a data transfer time issue?
  • 我可以做什么来缓解客户端处理时间问题,而不需要将如此多的处理转移到服务器,从而导致数据传输时间问题?
  • What are some best practices when it comes to balancing client-side processing with server-side processing?
  • 在平衡客户端处理和服务器端处理时,有哪些最佳实践?
  • Is it better to err on the side of the server or the client?
  • 在服务器端或客户端犯错更好吗?
  • What are some tools I can use to better optimize these exchanges so that things don't continue to go awry?
  • 我可以使用哪些工具来更好地优化这些交换,这样事情就不会继续出错?

3 个解决方案

#1


2  

What are you processing on the client side that is taking so long? Processing a JSON object (even a very large one) should not be too intensive.

你在客户端处理什么事情花费了这么长时间?处理JSON对象(即使是非常大的对象)也不应该太密集。

A lot of DOM look ups when writing your data client side could slow things down. Reducing DOM lookups can greatly help performance. I believe good practice for balancing server & client side processing is to error on the server. Since the server is under your control you can always choose to upgrade your server. Keeping the majority of processing on the server will also make things easier for mobile devices and older computers.

在编写数据客户端时,许多DOM查找可能会减慢进程。减少DOM查找可以极大地提高性能。我认为平衡服务器端和客户端处理的良好实践是在服务器上出错。因为服务器在你的控制之下,你可以选择升级你的服务器。保持服务器上的大部分处理也将使移动设备和旧电脑的工作变得更容易。

You should utilize AJAX & client side capabilities in a way that enhances the user experience. Load and process data as it is requested by the users. By loading only what they request you can decrease the load on your server & client.

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

If you are also requesting the same sort of data over and over you can look in to both server & client side caching. By utilizing caching you can reduce request times and/or bandwidth.

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

#2


1  

As it turns out, the problem is more with the JavaScript engines on the client side than the data I'm working with. I've spent much of the day benchmarking the process and timing various operations.

事实证明,与我正在处理的数据相比,客户端JavaScript引擎的问题更大。我花了一天的大部分时间对流程进行基准测试,并为各种操作计时。

Everything runs quickly in Chrome. Everything runs pretty fast (thought not as fast as Chrome) in Firefox. The real performance laggard is Internet Explorer.

所有东西在Chrome上运行都很快。在Firefox中,一切运行得都非常快(不像Chrome那样快)。真正性能落后的是Internet Explorer。

When I load the entire data set - all 200 rows - Flexigrid attempts to do some post-processing on every cell in the table. As you can see in the screenshot, each row has 29 cells ... so we're looking through a bunch of formatting operations a total of 5800 times.

当我加载整个数据集(全部为200行)时,Flexigrid尝试对表中的每个单元进行一些后处理。正如您在屏幕截图中看到的,每一行有29个单元格……我们要看一堆格式化操作总共5800次。

I was able to pull some of the more expensive operations (i.e. creating jQuery objects) out of the lower-level cell loop so they're only run once per row, but ultimately I'm still running into IE-related performance issues.

我能够从底层的单元格循环中取出一些更昂贵的操作(例如创建jQuery对象),因此它们每一行只运行一次,但是最终我还是会遇到与ip相关的性能问题。

To give you some real-world benchmarks, I set the code to spit out the total time before it hits certain events:

为了给您提供一些真实世界的基准,我设置了代码,以便在遇到某些事件之前指出总时间:

  • populate fires when the browser first sends off the XHR request
  • 当浏览器第一次发送XHR请求时触发填充
  • addData fires after the request has returned and before the JSON object is parsed
  • addData在请求返回后和JSON对象解析之前触发
  • addCellProp fires after the initial parsing of data and iterates through each cell in the table
  • addCellProp在对数据进行初始解析后触发,并在表中的每个单元格中迭代
  • done fires when everything is finsihed
  • 当一切都很清楚时就开火

Processing 20 rows of data (default):

处理20行数据(默认):

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

Processing the full data set (179 rows on this machine):

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

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

The most expensive operation is between addCellProp and done. I've gone through and made the code as efficient as possible, but there's only so much you can do when you're running through that many iterations of a data set, particularly when manipulating the DOM.

最昂贵的操作是在addCellProp和done之间进行。我已经对代码进行了尽可能高效的处理,但是当您运行数据集的多次迭代时,特别是在操作DOM时,您所能做的只有这么多。

I've modified Flexigrid (despite many recommendations not to) to touch the DOM as little as possible and that's actually sped things up quite a bit. When I started this research, IE9 would take between 20 and 30 seconds to hit the done event.

我修改了Flexigrid(尽管有很多建议不这么做)以尽可能少地接触DOM,这实际上加快了速度。当我开始这项研究时,IE9会在20到30秒之间完成。

The unfortunate truth here is that not all platforms are created equal, and IE doesn't seem to be the best engine for working with data within the display in this fashion.

不幸的是,并不是所有的平台都是平等的,IE似乎并不是在这种方式下使用数据的最佳引擎。

A better approach might be to create and manipulate the HTML table on the server side and send the entire thing (markup and all) to the browser when requested for IE users rather than depending on IE to create the markup from a raw JSON object.

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

#3


0  

What can I possibly do to alleviate the client-side processing time issues without moving so much processing to the server that I end up with a data transfer time issue?

我可以做什么来缓解客户端处理时间问题,而不需要将如此多的处理转移到服务器,从而导致数据传输时间问题?

Is the data coming out of a database? If so restrict the data there. This is what the db is good at. I use flexigrid and keep all the paging sorting and filtering there. The db only returns the required data sorted and filtered as requested. All the server has to do is return it and all the client has to do is render it.

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

What are some best practices when it comes to balancing client-side processing with server-side processing?

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

Keep client side light as possible

尽可能保持客户端轻

Is it better to err on the side of the server or the client?

在服务器端或客户端犯错更好吗?

Yes server has much more power

是的,服务器有更多的能量

What are some tools I can use to better optimize these exchanges so that things don't continue to go awry?

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

IE developer tools use the network tab to see what's coming over the wire

IE开发工具使用network选项卡来查看线路上的内容

#1


2  

What are you processing on the client side that is taking so long? Processing a JSON object (even a very large one) should not be too intensive.

你在客户端处理什么事情花费了这么长时间?处理JSON对象(即使是非常大的对象)也不应该太密集。

A lot of DOM look ups when writing your data client side could slow things down. Reducing DOM lookups can greatly help performance. I believe good practice for balancing server & client side processing is to error on the server. Since the server is under your control you can always choose to upgrade your server. Keeping the majority of processing on the server will also make things easier for mobile devices and older computers.

在编写数据客户端时,许多DOM查找可能会减慢进程。减少DOM查找可以极大地提高性能。我认为平衡服务器端和客户端处理的良好实践是在服务器上出错。因为服务器在你的控制之下,你可以选择升级你的服务器。保持服务器上的大部分处理也将使移动设备和旧电脑的工作变得更容易。

You should utilize AJAX & client side capabilities in a way that enhances the user experience. Load and process data as it is requested by the users. By loading only what they request you can decrease the load on your server & client.

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

If you are also requesting the same sort of data over and over you can look in to both server & client side caching. By utilizing caching you can reduce request times and/or bandwidth.

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

#2


1  

As it turns out, the problem is more with the JavaScript engines on the client side than the data I'm working with. I've spent much of the day benchmarking the process and timing various operations.

事实证明,与我正在处理的数据相比,客户端JavaScript引擎的问题更大。我花了一天的大部分时间对流程进行基准测试,并为各种操作计时。

Everything runs quickly in Chrome. Everything runs pretty fast (thought not as fast as Chrome) in Firefox. The real performance laggard is Internet Explorer.

所有东西在Chrome上运行都很快。在Firefox中,一切运行得都非常快(不像Chrome那样快)。真正性能落后的是Internet Explorer。

When I load the entire data set - all 200 rows - Flexigrid attempts to do some post-processing on every cell in the table. As you can see in the screenshot, each row has 29 cells ... so we're looking through a bunch of formatting operations a total of 5800 times.

当我加载整个数据集(全部为200行)时,Flexigrid尝试对表中的每个单元进行一些后处理。正如您在屏幕截图中看到的,每一行有29个单元格……我们要看一堆格式化操作总共5800次。

I was able to pull some of the more expensive operations (i.e. creating jQuery objects) out of the lower-level cell loop so they're only run once per row, but ultimately I'm still running into IE-related performance issues.

我能够从底层的单元格循环中取出一些更昂贵的操作(例如创建jQuery对象),因此它们每一行只运行一次,但是最终我还是会遇到与ip相关的性能问题。

To give you some real-world benchmarks, I set the code to spit out the total time before it hits certain events:

为了给您提供一些真实世界的基准,我设置了代码,以便在遇到某些事件之前指出总时间:

  • populate fires when the browser first sends off the XHR request
  • 当浏览器第一次发送XHR请求时触发填充
  • addData fires after the request has returned and before the JSON object is parsed
  • addData在请求返回后和JSON对象解析之前触发
  • addCellProp fires after the initial parsing of data and iterates through each cell in the table
  • addCellProp在对数据进行初始解析后触发,并在表中的每个单元格中迭代
  • done fires when everything is finsihed
  • 当一切都很清楚时就开火

Processing 20 rows of data (default):

处理20行数据(默认):

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

Processing the full data set (179 rows on this machine):

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

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

The most expensive operation is between addCellProp and done. I've gone through and made the code as efficient as possible, but there's only so much you can do when you're running through that many iterations of a data set, particularly when manipulating the DOM.

最昂贵的操作是在addCellProp和done之间进行。我已经对代码进行了尽可能高效的处理,但是当您运行数据集的多次迭代时,特别是在操作DOM时,您所能做的只有这么多。

I've modified Flexigrid (despite many recommendations not to) to touch the DOM as little as possible and that's actually sped things up quite a bit. When I started this research, IE9 would take between 20 and 30 seconds to hit the done event.

我修改了Flexigrid(尽管有很多建议不这么做)以尽可能少地接触DOM,这实际上加快了速度。当我开始这项研究时,IE9会在20到30秒之间完成。

The unfortunate truth here is that not all platforms are created equal, and IE doesn't seem to be the best engine for working with data within the display in this fashion.

不幸的是,并不是所有的平台都是平等的,IE似乎并不是在这种方式下使用数据的最佳引擎。

A better approach might be to create and manipulate the HTML table on the server side and send the entire thing (markup and all) to the browser when requested for IE users rather than depending on IE to create the markup from a raw JSON object.

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

#3


0  

What can I possibly do to alleviate the client-side processing time issues without moving so much processing to the server that I end up with a data transfer time issue?

我可以做什么来缓解客户端处理时间问题,而不需要将如此多的处理转移到服务器,从而导致数据传输时间问题?

Is the data coming out of a database? If so restrict the data there. This is what the db is good at. I use flexigrid and keep all the paging sorting and filtering there. The db only returns the required data sorted and filtered as requested. All the server has to do is return it and all the client has to do is render it.

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

What are some best practices when it comes to balancing client-side processing with server-side processing?

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

Keep client side light as possible

尽可能保持客户端轻

Is it better to err on the side of the server or the client?

在服务器端或客户端犯错更好吗?

Yes server has much more power

是的,服务器有更多的能量

What are some tools I can use to better optimize these exchanges so that things don't continue to go awry?

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

IE developer tools use the network tab to see what's coming over the wire

IE开发工具使用network选项卡来查看线路上的内容