【问题标题】:severside processing vs client side processing + ajax?服务器处理与客户端处理+ ajax?
【发布时间】:2011-01-03 09:10:45
【问题描述】:

寻找一些一般性的建议和/或想法...

我正在创建我认为更像是一个 Web 应用程序而不是网页的东西,因为我希望它像一个 gmail 应用程序,您可以让页面整天保持打开状态,同时将更新“推送”到页面(对于感兴趣的我正在使用彗星编程技术)。在此之前,我从未创建过如此丰富的 ajax 和 javascript 网页(我现在是 jquery 的忠实粉丝)。正因为如此,当我一次又一次地实现需要服务器需要了解的 UI 中的动态更改的新功能时,我面临着同样的问题:

1) 我是否应该在客户端上使用 javascript 进行所有处理并通过 ajax 尽可能少地回发 要么 2)我应该通过ajax向服务器发布请求,让服务器完成所有处理,然后发回新的html。然后在 ajax 响应中,我用新的 HTML 做了一个简单的分配

我一直倾向于始终遵循#1。我想这个网络应用程序可能会对所有的 ajax 请求变得很健谈。我的想法是尽可能减少请求和响应的大小,并依靠不断改进的 javascript 引擎来完成尽可能多的处理和 UI 更新。我发现使用 jquery 我可以在客户端做很多事情,而我以前无法很容易地做到这一点。我的 javascript 代码实际上比我的服务器端代码更大、更复杂。我还需要执行一些简单的计算,并且我也已将其推送到客户端。

我想我的主要问题是,我们是否应该尽可能地争取客户端处理而不是服务器端处理?我一直觉得服务器处理的越少,可扩展性/性能就越好。让客户端处理器的强大功能完成所有艰苦的工作(如果可能的话)。

想法?

【问题讨论】:

  • 旧的就是新的,新的又是旧的。 :)

标签: javascript ajax performance scalability


【解决方案1】:

在决定是否应该在服务器端或客户端构建由 ajax 请求创建的新 HTML 片段时,有几个考虑因素。需要考虑的一些事项:

  • 性能。您的服务器必须做的工作是您应该关心的。通过在客户端进行更多处理,您可以减少服务器的工作量并加快处理速度。例如,如果服务器可以发送一小部分 JSON 而不是巨大的 HTML 片段,那么让客户端来做会更有效率。在以任一方式发送少量数据的情况下,差异可能可以忽略不计。

  • 可读性。在 JavaScript 中生成标记的缺点是阅读和维护代码要困难得多。在带引号的字符串中嵌入 HTML 很难在文本编辑器中看到,语法着色设置为 JavaScript,并且使编辑更加困难。

  • 数据、表示和行为的分离。就可读性而言,在 JavaScript 中包含 HTML 片段对于代码组织没有多大意义。 HTML 模板应该处理标记,而 JavaScript 应该单独处理应用程序的行为。插入页面的 HTML 片段的内容与您的 JavaScript 代码无关,仅与插入的位置、插入时间和位置有关。

出于我上面提到的可读性和代码组织的原因,在处理 ajax 响应时,我更倾向于从服务器返回 HTML 片段。当然,这完全取决于您的应用程序的工作方式、ajax 响应的处理密集程度以及应用程序获得的流量。如果服务器必须在生成这些响应时做大量工作并导致瓶颈,那么将工作推送给客户端并放弃其他考虑因素可能更重要。

【讨论】:

  • 可读性和分离的优点。我开始担心,因为我的 javascript 看起来很丑陋,带有 html 片段和到处都是转义的引号。开始尽可能多地提取并在另一个常量 js 文件中标记 HTML 片段...
  • 您可以通过使用 XSLT 在客户端将 XML 转换为 HTML 来保持代码的可读性。由于 XSL 文档已被缓存,因此它确实增加了很少的开销。当然,您只能使用 XSL 文档转换 XML。所有主流浏览器(包括 IE6)在客户端都支持 XSLT(尽管不一定通过 javascript 来进行 ajax 响应)。显然有办法解决这个问题,但要注意增加的兼容性测试。
【解决方案2】:

我目前正在开发一个计算量非常大的应用程序,并且我正在客户端渲染几乎所有的应用程序。我不确切知道您的应用程序将要做什么(更多详细信息会很棒),但我会说您的应用程序可能会做同样的事情。只需确保所有与安全和数据库相关的代码都位于服务器端,因为不这样做会在您的应用程序中打开安全漏洞。以下是我遵循的一些一般准则:

  • 永远不要依赖用户拥有超快的浏览器或计算机。有些人在旧机器上使用 Internet Explorer 7,如果速度对他们来说太慢,您将失去很多潜在客户。 在尽可能多的不同浏览器和机器上进行测试
  • 任何时候您的某些代码可能会暂时降低或冻结浏览器,显示反馈机制(在大多数情况下,一个简单的“正在加载”消息即可)告诉用户某事确实在进行中,而且浏览器不只是随机冻结。
  • 尝试在初始化期间尽可能多地加载缓存所有内容。在我的应用程序中,我正在做一些类似于 Gmail 的事情:显示一个加载栏,加载应用程序需要的所有内容,然后从那里开始为用户提供流畅的体验。是的,他们可能需要等待几秒钟才能加载,但在那之后应该没有问题。
  • 最小化 DOM 操作。 处理原始数字的 JavaScript 性能可能“足够快”,但访问 DOM 仍然很慢。避免创建和销毁元素;如果您目前不需要它们,只需将它们隐藏起来即可。

【讨论】:

  • 感谢您的提示。你不能扩展“缓存一切”评论吗?我没有在客户端使用缓存的经验。您是指可能的插件还是只是简单的全局变量?
  • 我的意思是不要扔掉任何东西。如果你做了一堆计算,不要把结果扔掉;把它们留在记忆中,以备下次使用。我不是在谈论使用插件,只是使用普通变量或其他任何东西,尽管您可以使用 Gears 和大多数浏览器中可用的客户端存储。
  • 我不会使用齿轮。尽管它在开发人员中有些炒作。它不是那么受欢迎。如果您确实需要在请求之间存储某些内容,请考虑使用 cookie 或闪存,因为它具有更高的可用性。
  • @Sergej:检查它并没有什么坏处,是吗?只需检查用户是否安装了它,如果没有,那就好了。我并不是说你应该依赖它,只要有就使用它。
  • @Sergej:我也不会轻视齿轮。虽然插件本身并没有获得太大的吸引力,但在 HTML 5 规范中建议使用相同的功能(沙盒化多进程 javascript、通过清单本地缓存文件和本地 SQL 存储)(iPhone 甚至实现了它,其他我不记得了)。因此,如果您现在通过插件实现它,您可以稍后切换。
【解决方案3】:

我最近遇到了同样的问题,并决定使用浏览器端处理,在 FF 和 IE8 和 IE8 7 模式下一切正常,但后来......我们的客户端,使用 Internet Explorer 7 遇到了问题,应用程序会冻结并会出现一个脚本超时框,我在解决方案中投入了太多工作而无法将其丢弃,所以我最终花了一个小时左右优化脚本并尽可能添加 setTimeout。

我的建议?

  • 如果可能,将非关键计算保留在客户端。
  • 要保持低数据传输,请使用 JSON 并让客户端整理 HTML。
  • 使用最小公分母测试您的脚本。
  • 如果需要,请使用 FireBug 中的分析功能。 推论:使用未压缩(开发)版本的 jQuery。

【讨论】:

  • 很高兴我发布了这个问题。得到了很多好的建议,并得到了我最初想法的确认。我也坚信保持服务器尽可能简单和精简,但正因为如此,它大大增加了客户端代码的复杂性。然而,jquery 已经极大地缓解了这种情况。我也喜欢使用 chrome 的任务管理器。到目前为止,我的 chrome 会话占用了大约 20MB(gmail 为 50),并且在我的迭代计算过程中,cpu 在最重的时候达到了 15。它不应该从这里变得太重,所以我想我还好。
  • dynatrace 有一个优秀的分析器(免费!),专门用于 IE,你可以准确地看到什么花了这么长时间,网络,绘画,脚本时间,它会告诉你哪一行 javascript 挂了/被调用 100,000 次等...我建议您获取一份副本,它在解决任何 IE 性能问题方面对我有很大帮助。 ajax.dynatrace.com
【解决方案4】:

我同意你的看法。尽可能多地推送给用户,但不要太多。如果您的应用程序变慢甚至更严重地使他们的浏览器崩溃,您就会松懈。

我的建议是实际测试您的应用程序在打开一整天时的行为。检查没有内存泄漏。在使用应用程序一段时间后检查是否每半秒创建一个 ajax 请求(JS 中的计时器有时会很痛苦)。

除此之外,永远不要使用 javascript 执行用户输入验证。始终在服务器上复制它。

编辑

使用 jquery live binding。在重新绑定生成的内容时,它将为您节省大量时间,并使您的架构更加清晰。遗憾的是,当我使用 jQuery 进行开发时,它还不可用。我们使用了其他具有相同效果的工具。

过去,当使用 ajax 生成一个页面部分依赖于其他部分生成时,我也遇到过问题。生成第一部分第一部分和第二部分第二部分将使您的页面按预期变慢。提前计划好这个。开发一个页面,以便它们在打开时已经包含所有内容。

另外(也适用于简单页面),将一台服务器上的引用文件数量保持在较低水平。将 javascript 和 css 库加入服务器端的一个文件中。将图像保存在单独的主机上,更好的单独主机上(也可以只创建第三级域)。尽管这仅在生产上才值得;这将使开发过程更加困难。

【讨论】:

  • 很棒的是没有使用 JS 计时器。根本没有投票。看看 chrome 的 JS 引擎与其他浏览器相比有多快是很有趣的......事情似乎在 chrome 上立即发生,但你实际上可以在 firefox 中看到有时发生的事情(实际上不是一个坏功能)
【解决方案5】:

当然,这取决于数据,但大多数情况下,如果您可以将其推送到客户端,则可以。让客户端做更多的处理并使用更少的带宽。 (这同样取决于数据,您可能会遇到必须发送更多数据才能在客户端执行此操作的情况。

【讨论】:

  • 在我的情况下,发送的数据将永远不会更多,以便在客户端执行此操作。在大多数情况下,我需要做的就是最多发送几百个字节,然后客户端可以根据这些数据重建必要的 UI 部分。当然,这会使 javascript 变得非常复杂(jquery 使它变得合理),但如果我在服务器端这样做,ajax 响应可能是数千字节..
  • 您可以向客户端推送的内容越多,该站点的响应速度就越快,规模越大。客户端代码确实存在它自己的问题,例如单元测试、安全性等,但如果可能的话,这绝对是要走的路。
【解决方案6】:

一些东西,比如安全检查,应该总是在服务器上完成。如果您的计算需要大量数据并产生较少的数据,也可以将其放在服务器上。

顺便说一句,您知道您可以在服务器端运行 Javascript、渲染模板和访问数据库吗?查看CommonJS 生态系统。

【讨论】:

    【解决方案7】:

    还可能存在跨浏览器支持问题。如果您使用的是跨浏览器、客户端库(例如 JQuery)并且它可以处理您需要的所有处理,那么您可以让库来处理它。根据标记的复杂性,在服务器端生成跨浏览器 HTML 可能会更难(往往需要更多手动操作)。

    【讨论】:

      【解决方案8】:

      这是可能的,但需要大量的初始页面加载 && 大量使用缓存。以gmail为例

      • 在初始页面加载时,它会下载运行所需的大部分 js 文件。最重要的是缓存。
      • 不要过度使用图像和图形。
      • 加载所有需要在初始加载中显示的数据以及随后的可预测用户数据。在 gmail 和最新的 yahoo 邮件中,收件箱不仅填充了单个邮件对话正文,而且在页面加载时提前加载了前几封完整的电子邮件。高响应性的秘诀在于成本(如果带宽低,gmail 会要求加载轻量版。我敢打赌,我们大多数人都经历过)。
      • 遵循KISS原则。意味着保持你的设计简单。
      • 在任何情况下都不要尝试使用 javascript 呈现整个页面,您无法预测所有最终用户使用高配置系统或高带宽系统。

      在服务器和客户端之间分配工作负载是明智之举。

      【讨论】:

        【解决方案9】:

        如果您认为将来可能希望为您的应用程序创建一个 API(与 iPhone 或 android 应用程序通信,让其他网站与您的应用程序集成),您将不得不为所有这些设备复制一堆代码,如果您使用应用程序的基本服务器实现。

        【讨论】:

        • 我知道这篇文章很旧,但是当我搜索时它在谷歌上的排名很高。