客户端逻辑还是服务器端逻辑?

时间:2009-10-04 16:49:21

标签: performance

我已经完成了一些基于网络的项目,我遇到的大多数困难(问题,混淆)都可以在帮助下找到答案。但是我仍然有一个重要的问题,即使在询问了一些有经验的开发人员之后:当使用服务器端代码和客户端脚本(JavaScript)实现功能时,应该首选哪一个?

一个简单的例子:

要呈现动态html页面,我可以在服务器端代码(PHP,python)中格式化页面,并使用Ajax获取格式化页面并直接呈现它(服务器端更多逻辑,客户端更少) )。

我也可以使用Ajax来获取数据(未格式化,JSON)并使用客户端脚本来格式化页面并使用更多处理来呈现它(服务器从数据库或其他源获取数据,并返回它使用JSON或XML的客户端。客户端更多逻辑,服务器更少。

那我怎么决定哪一个更好?哪一个提供更好的性能?为什么?哪一个更方便用户使用?

随着浏览器的JS引擎不断发展,可以在更短的时间内解释JS,所以我更喜欢客户端脚本吗?

另一方面,随着硬件的发展,服务器性能不断提高,服务器端逻辑的成本也会降低,所以我更喜欢服务器端脚本吗?

修改

有了答案,我想简要总结一下。

客户端逻辑的优点:

  1. 更好的用户体验(更快)。
  2. 减少网络带宽(降低成本)。
  3. 提高可扩展性(减少服务器负载)。
  4. 服务器端逻辑优点:

    1. 安全问题。
    2. 更好的可用性和可访问性(移动设备和旧浏览器)。
    3. 更好的搜索引擎优化。
    4. 易于扩展(可以添加更多服务器,但无法使浏览器更快)。
    5. 在面对特定情况时,我们似乎需要平衡这两种方法。但是怎么样?什么是最佳做法?

      除了以下条件外,我将使用客户端逻辑:

      1. 安全关键。
      2. 特殊群组(禁用JavaScript,移动设备等)。

12 个答案:

答案 0 :(得分:22)

在许多情况下,我担心最好的答案是两者

正如Ricebowl所说,永远不要相信客户。但是,如果你信任客户,我觉得这几乎总是一个问题。如果您的申请值得写,那么值得妥善保管。如果有人可以通过编写自己的客户端并传递你不期望的数据来打破它,这是一件坏事。因此,您需要在服务器上进行验证。

不幸的是,如果您验证服务器上的所有内容,通常会使用户的用户体验不佳。他们可能会填写表格,但发现他们输入的许多内容都不正确。这可能适用于“Internet 1.0”,但人们对今天互联网的期望更高。

这可能会让您编写相当多的冗余代码,并将其保存在两个或更多位置(某些定义(如最大长度)也需要在数据层中维护)。对于相当大的应用程序,我倾向于使用代码生成来解决此问题。我个人使用UML建模工具(Sparx系统的Enterprise Architect)来模拟系统的“输入规则”,然后利用部分类(我通常在.NET中工作)来生成验证逻辑。您可以通过以XML格式编写规则并在客户端和服务器层上从该XML文件(输入长度​​,输入掩码等)中获取大量检查来实现类似的功能。

可能不是你想听到的,但如果你想做得对,你需要在两个层面上执行规则。

答案 1 :(得分:13)

我倾向于选择服务器端逻辑。我的理由很简单:

  1. 我不相信客户;这可能是或不是一个真正的问题,但它是习惯性的
  2. 服务器端减少了每个事务的数量(尽管它确实增加了事务数)
  3. 服务器端意味着我可以相当确定正在发生的逻辑(我不必担心客户端浏览器可用的Javascript引擎)
  4. 可能有更多 - 更好的理由,但这些是我现在最重要的原因。如果我想到更多,我会添加它们,或者在我做之前对那些提出它们的那些进行投票。

    <小时/> 编辑,valya注释使用客户端逻辑(使用Ajax / JSON)允许(更容易)创建API。这可能是真的,但我只能半同意(这就是为什么我还没有对这个答案进行投票)。

    我的服务器端逻辑概念是检索数据并组织数据的概念;如果我做对了,逻辑就是'控制器'(MVC中的C)。然后将其传递给“视图”。我倾向于使用控制器来获取数据,然后“视图”处理将其呈现给用户/客户端。所以我没有看到客户端/服务器的区别必然与创建API的论点有关,基本上是:马匹用于课程。 :)

    ...另外,作为一个业余爱好者,我认识到我可能会略微扭曲使用MVC,所以我愿意在这一点上做出纠正。但我仍然将演示文稿与逻辑分开。到目前为止,这种分离是API的优点。

答案 2 :(得分:5)

我通常尽可能地实施合理的客户端。唯一能使我进入服务器端的例外是解决以下问题:

信任问题

任何人都可以调试JavaScript并阅读密码等等。这里很简单。

效果问题

JavaScript引擎正在快速发展,因此这个问题变得越来越少,但我们仍处于IE主导的世界中,因此当您处理大量数据时, 会慢下来。

语言问题

JavaScript是弱类型语言,它会对您的代码做出很多假设。这可能会导致您使用怪异的变通办法,以便在某些浏览器上按照应有的方式工作。我避免像瘟疫这样的事情。


从您的问题来看,听起来您只是想将值加载到表单中。除非上述任何问题,您有3个选择:

纯客户端

缺点是用户的加载时间会加倍(空白表单加载一次,数据加载另一次加载)。但是,对表单的后续更新不需要刷新页面。如果从服务器加载到同一表单中的大量数据,用户会喜欢这样。

纯服务器端

优点是您的页面会加载数据。但是,对数据的后续更新将需要刷新页面的所有/重要部分。

服务器 - 客户端混合

你将拥有两全其美,但是你需要创建两个数据提取点,导致你的代码略微膨胀。

每个选项都需要权衡,因此您必须权衡它们并决定哪一个为您提供最大的好处。

答案 3 :(得分:3)

我没有提到的一个考虑因素是网络带宽。举一个具体的例子,我参与的一个应用程序都是在服务器端完成的,并导致200Mb的网页被发送到客户端(如果没有对一堆应用程序进行重大的主要重新设计,就不可能做得更少);导致2-5分钟的页面加载时间。

当我们通过从服务器发送JSON编码数据并让本地JS生成页面来重新实现它时,主要好处是发送的数据缩小到20Mb,导致:

  • HTTP响应大小:200Mb + =&gt; 20Mb +(带有相应的带宽节省!)

  • 加载页面的时间:2-5分钟=&gt; 20秒(其中10-15个被DB查询占用,经过优化以进一步优化)。

  • IE流程大小:200MB + =&gt; 80MB +

请注意,最后2点主要是由于服务器端必须使用桌面内的糟糕表树实现,而转到客户端则允许我们重新设计视图层以使用更轻量级的页面。但我的主要观点是网络带宽节省。

答案 4 :(得分:2)

我构建了一个RESTful Web应用程序,其中所有 CRUD功能在没有JavaScript的情况下可用,换句话说,所有AJAX效果都是严格的渐进增强

我相信有足够的奉献精神,大多数Web应用程序都可以这样设计,从而侵蚀了许多服务器逻辑与客户端逻辑“差异”,例如安全性,可扩展性,在您的问题中提出,因为在这两种情况下,请求都是路由到同一个控制器,其业务逻辑完全相同,直到最后一英里,为那些XHR返回JSON / XML,而不是整页HTML。

只有在极少数情况下,AJAXified应用程序比静态对应程序更先进,GMail是我脑海中最好的例子,然后需要创建两个版本并将它们完全分开(Kudos to Google!)。 / p>

答案 5 :(得分:1)

我想就这个问题给出两分钱。

我一般都支持服务器端方法,这就是原因。

  • 更多SEO友好。 Google无法执行Javascript,因此所有内容都将对搜索引擎不可见
  • 性能更可控。由于您几乎完全依赖于用户浏览器和计算机来呈现内容,因此用户体验始终随SOA而变化。即使您的服务器运行良好,但使用慢速计算机的用户也会认为您的网站是罪魁祸首。
  • 可以说,服务器端方法更容易维护和读取。

我用两种方法编写了几个系统,根据我的经验,服务器端就是这样。但是,这并不是说我不使用AJAX。我构建的所有现代系统都包含两个组件。

希望这有帮助。

答案 6 :(得分:1)

在这个阶段,客户端技术处于领先地位,随着Backbone,Knockout,Spine等许多客户端库的出现,再加上JSrender,胡子等客户端模板,客户端开发变得更加容易。 所以,如果我的要求是去交互式应用程序,我一定会去客户端。 如果你有更多的静态html内容,那么是的去服务器端。 我用两者做了一些实验,我必须说服务器端比客户端更容易实现。 就性能而言。阅读本文,您将了解服务器端性能分数。 http://engineering.twitter.com/2012/05/improving-performance-on-twittercom.html

答案 7 :(得分:1)

我知道这篇文章很老,但我想发表评论。

根据我的经验,最好的方法是使用客户端和服务器端的组合。是的,Angular JS和类似的框架现在很流行,它们使开发重量轻,性能提高和大多数Web服务器工作的Web应用程序变得更加容易。但是,企业应用程序的主要要求是显示报告数据,该数据可以包含一页上的500多条记录。对于返回大量数据列表的页面,用户通常需要的功能可以使这个庞大的列表易于过滤,搜索和执行其他交互功能。因为IE 11及更早版本的IE浏览器是大多数公司的首选浏览器,所以你必须意识到这些浏览器仍然存在使用现代JavaScript,HTML5和CSS3的兼容性问题。通常,要求是使网站或应用程序在所有浏览器上兼容。这需要添加shivs或使用原型,这些原型包含用于创建客户端应用程序的代码,会在浏览器上添加页面加载。

所有这些都会降低性能并导致可怕的IE错误&#34;此页面上的脚本导致Internet Explorer运行缓慢&#34;强制用户选择是否要继续运行脚本...创建糟糕的用户体验。

根据用户在现有应用程序中的偏好,确定应用程序的复杂性以及用户现在和将来想要的内容。如果这是一个简单的站点或具有中小型数据的应用程序,请使用JavaScript Framework。但是,如果他们想要融入可访问性;搜索引擎优化;或者需要显示大量数据,使用服务器端代码来节省数据和客户端代码。在这两种情况下,使用Fiddler或Chrome Developer工具等工具来检查页面加载和响应时间,并使用最佳实践来优化代码。

使用ASP.NET Core开发的Checkout MVC应用程序。

答案 8 :(得分:0)

我认为第二种变体更好。例如,如果你稍后实现类似'皮肤'的东西,你会感谢你自己没有在服务器上格式化html:)

它还保持视图和控制器之间的差异。 Ajax数据通常由控制器生成,所以让它只返回数据,而不是html。

如果您稍后要创建API,则需要在代码中进行少量更改

另外,我认为'Naked'数据比HTML更易于存储。例如,如果您向链接添加一些样式,则需要重新格式化所有html ..或者在js中添加一行。它没有html那么大(以字节为单位)。

但是如果需要很多繁重的脚本来格式化数据,那就不要让用户的浏览器对它进行格式化。

答案 9 :(得分:0)

只要您不需要向客户端发送大量数据以允许其执行工作,客户端就会为您提供更具伸缩性的系统,因为您将负载分配给客户端而不是锤击你的服务器要做的一切。

另一方面,如果您需要处理大量数据以生成少量html以发送给客户端,或者可以进行优化以使用服务器的工作来同时支持多个客户端(例如,流程)数据一次并将生成的html发送给所有客户端),然后可以更有效地利用资源在服务器上进行工作。

答案 10 :(得分:0)

如果你在Ajax中这样做:

您必须考虑针对残障人士的可访问性问题(在Google中搜索网络辅助功能),以及旧浏览器,没有JavaScript的人,机器人(如谷歌机器人)等等。

如果您从未使用过JavaScript,那么您将不得不调情“渐进式增强”并不简单。简而言之,您必须使您的应用程序适用于旧浏览器和那些没有JavaScript(例如某些移动设备)或者禁用它的应用程序。

但如果时间和金钱不是问题,我会选择逐步增强。

但也要考虑“后退按钮”。当我浏览一个100%的AJAX网站时,我讨厌它,这会使你的后退按钮变得毫无用处。

祝你好运!

答案 11 :(得分:0)

2018年答案,存在Node.js

由于Node.js允许您在服务器上部署Javascript逻辑,因此您现在可以在服务器端和客户端重新使用验证。

请确保设置或重组数据,以便您可以重新使用验证而无需更改任何代码。