【问题标题】:Why do web applications send HTML over the wire?为什么 Web 应用程序通过网络发送 HTML?
【发布时间】:2011-01-17 01:40:06
【问题描述】:

此问题与 Web 应用程序有关。我的网络应用程序开发经验很少,所以可能会遗漏一些非常明显的点/问题。请指出来。

据我了解,在大多数 Web 应用程序中,Web 服务器通过网络将 HTML 发送到客户端(浏览器)。每次发出 HTTP 请求时都会发生这种情况。我觉得这样很浪费带宽。

1) 既然浏览器可以运行 JavaScript,我们为什么不直接发送一个 JavaScript 程序,它可以生成网页的 HTML 内容(浏览器随后呈现)。

2) 此外,浏览器可能会缓存 JavaScript 程序,下次服务器只需要发送数据。该协议可能涉及浏览器发送它拥有的“程序版本”。

考虑一个相对简单的网站 Hacker News [http://news.ycombinator.com].让我们将数据(30 个帖子 + 它们的元数据)与其呈现分开。假设上面的 1),服务器可以只发送数据(比如 JSON)+ 一个 JavaScript 程序来生成 HTML。这个gist 显示了这个想法。 30 个帖子的数据采用 JSON [http://www.json.org/js.html] 格式。对于这个特定示例,传输的数据被削减为 1/2(数据大小+JavaScript / HTML 大小)。此外,如果浏览器可以执行上述 2),它会将每次访问时传输的数据减少到 1/4(数据大小/HTML 大小)。 [注:此分析未考虑压缩; gzip,deflate 在减小 HTML 的大小方面非常成功。但预防胜于治疗吗?]

我至少看到了以下优点:-
* 对于大多数网页,它将减少通过网络传输的数据大小。
* 强制 Web 应用程序将数据与其演示文稿分开。

缺点可能包括 - 更复杂的浏览器、运行 JavaScript 程序以生成 HTML 的时间(这可能会因数据大小的减少而抵消)。

现在我的问题是 - 为什么不以这种方式开发 Web 应用程序,或者,为什么 Web 应用程序通过网络发送 HTML?当然,Web 服务器(发送 HTML)根本不关心 HTML,那么它为什么要首先生成它,然后通过网络发送呢?

【问题讨论】:

  • 生成HTML的JS不会比HTML大吗?
  • 有很多这样的网络应用程序。
  • 像 GMail 这样的应用程序或多或少完全按照您说的做。通常,一个骨架 HTML 文件将来自服务器,但此后更新是通过客户端代码完成的,该代码解释对异步 HTTP 请求的更多“纯”数据响应。事实上,Stackoverflow 本身就做了很多。
  • 另一方面,像 Hacker News 这样的应用程序应该在服务器上做尽可能多的事情,因为它的目标受众(程序员)往往是少数几个知道你可以转向的人群之一关闭 javascript,有时确实关闭 javascript 2. 知道您可以从普通的旧(非智能手机)手机浏览网页,有时会这样做。 3. 了解文本模式的用户代理,例如 elinks 和 lynx,甚至 wget 和 curl,并且实际上会不时使用它们。一般来说,如果你的网站是纯旧的 HTML,程序员会很感激。
  • 搜索引擎对“程序结构”也不太满意。我相信 REST 风格与使用 Flash 或 Java 或任何其他“可脚本化”语言几乎相同的问题。因此,如果您没有静态的“h1”,那么您的标题就无法从 Google 等轻松找到。

标签: javascript html web-applications


【解决方案1】:

有几个原因,其中一些是历史原因,这绝不是一个完整的列表,而只是我的一些经验:

  1. HTML 早于 JS,许多脚本和库早于 JS
  2. 较旧的浏览器(想想 IE一致 JS
  3. 之前有更多的库和脚本
  4. 如果按照您的建议编写的应用程序构造不正确,那么调试应用程序是一场噩梦(我的工作中有一个,需要 30 分钟才能找到实际生成一段 html 的位置)
  5. 要做正确的事还有很多工作要做 - 为什么不使用模板或静态文档或更简单的东西
  6. 这不是一个真正的问题 - HTML 压缩得非常好
  7. 您的建议已完成 - 它称为 AJAX(好吧,所以 ajax 比这更通用,但你们都知道我的意思)
  8. 它根本不适用于大多数纯文本用户代理,包括大多数搜索引擎使用的那些。如果此页面提供您的大部分内容,通常最好让 Google 轻松解析

【讨论】:

    【解决方案2】:

    为什么会出现这种情况的明显原因是当我们开始发送 HTML 时 JavaScript 还不存在,而 HTML 是对发送纯文本文档的改进。

    我们现在不这样做的原因是:我们避免解决并非真正问题的复杂解决方案。

    平均互联网连接每秒下载近 1M 字节,Web 浏览器非常擅长解析并开始呈现此 HTML,甚至还没有准备好。他们也很擅长在页面上并行下载资源。如果我们想以一些计算周期为代价来节省几个字节,我们会在发送内容之前对其进行 gzip 压缩。问题解决了。

    为了记录,我们在复杂网页中使用 AJAX 执行此操作(请查看 Github 的源代码浏览以了解这有多棒的一个很好的示例)。

    【讨论】:

    • 浏览器可能会很高兴,但我不禁觉得服务器、连接对这种安排太满意了:)。 Web 应用程序中的大多数瓶颈不是都在服务器端吗?
    • 当然,但这与带宽无关。通常在对 CPU 周期的需求增加到需要扩展的程度之后,最大的瓶颈就变成了数据库访问。并发性、立即可用的数据和可伸缩性是更相关的问题。这就是为什么每天都会有 N+1 个新的数据库系统出现(CloudDB、Cassandra 等等等等):P
    【解决方案3】:

    您的建议可以并且已经完成。请记住,网页曾经是静态文档。成熟的基于 Web 的应用程序是一个相对较新的想法。

    我可能还建议它不一定更有效,尤其是当您的网页以 gzip 格式发送时。

    【讨论】:

      【解决方案4】:

      您的建议基本上就是 JavaScript full stack framework like ExtJS 所做的。您无需编写任何 HTML 即可创建丰富的数据密集型应用程序——好吧,仅够引用必要的 .js 库。布局、网格、表单等所需的复杂 DOM 均由框架创建。

      【讨论】:

      • 特别是在移动应用程序中,只发送一个 html 页面然后通过网络发送 json 并呈现客户端变得很普遍。
      【解决方案5】:

      简单的答案是 HTML 较旧。为什么很多编译器都没有完全实现 C99?他们认为 1989 年对他们来说已经足够新了。此外,JavaScript 对人们的浏览器进行的控制比他们看起来想要的要多得多。条件语句和编码数据会带来安全问题,有些人希望从一开始就关闭这罐蠕虫病毒。诚然,HTML 是一种非常低效的标记,但与您从 Internet 下载的图像相比,它的大小微不足道。该网站图标占用的数据与页面本身一样多,而且它只有 16 个像素。

      【讨论】:

      • @Anonymous,您提出了一个非常有效的观点,即大小可能微不足道,但就网站图标而言,它们不是被缓存了吗?为什么我们不能缓存所有的静态数据?
      • 你可以。服务器可以发送一个标头,告诉客户端缓存从网页本身到任何图像或任何东西的任何内容。在您点击刷新按钮、清除缓存或退出浏览器之前,服务器将完全控制缓存。
      • 16*16=256*(32/8)+BMP_HEADER_BYTES = 1KB + 52B 根据 Chrome 开发者工具,这个页面大约 45KB。但是,是的,400x100 图像是另一回事。
      • 是的。嗯,Stack Overflow 是一个更大的网站,里面有所有的菜单和东西,但是,更大的图片才是真正吸引你的地方。
      【解决方案6】:

      Web 应用程序的服务器端代码可能在服务器端执行大量 HTML 模板工作的一个很好的原因是,在许多服务器环境中,捆绑服务器端数据结构(对象图)并不容易轻松交付给客户。可能有一些信息保存在服务器端数据结构中,实际上不应该传递给客户端。因此,为了发送“纯”数据响应,服务器必须在发送 JSON 之前修剪掉敏感数据。这不是一个无法解决的问题,但我不知道有多少服务器框架可以促进解决方案。

      服务器可以直接、不受限制地访问数据库以及使应用程序正常工作的所有其他内容:用户首选项、历史记录、帐户详细信息、系统设置等。构建以客户端为中心的应用程序以用于渲染目的意味着炮制保持所有这些信息完整并在客户端上保持最新的方法。对于很多应用程序来说,这可能并不容易。

      最后,相信浏览器能够提供足够稳定的平台来构建长期存在的“应用程序环境”作为持续更新的网页是最近才有意义的。通过构建一个有时会完全重新加载页面的 Web 应用程序,可以实现很多小的“重新启动”。这是一种廉价而愚蠢的方法,至少可以控制某些类型的内存泄漏。

      【讨论】:

      • 你的观点很好。您认为“纯数据”服务器 + 智能客户端实现了更好的关注点分离(商业逻辑数据与呈现)还是整体更糟,因为现在应用程序的智能被划分了?
      • @na_ka_na 好吧,我不知道我有足够的经验可以说。我确实知道大型应用程序倾向于积累很多不同“维度”的状态信息,我认为以“纯数据”的形式处理它应用程序是一个相当新的挑战,没有很多可靠的普遍接受的框架支持。我确实认为这是一个有趣的想法,我希望看到更多关于这个主题的工作。
      【解决方案7】:

      大多数使用大量 Javascript 的网站实现在 DOM 完全加载之前不会开始执行;那么当页面包装器已下载时,您将获得带有“加载屏幕”的每个页面,但没有任何内容。

      另外,请记住,并非所有用户都启用了 Javascript,也并非所有浏览器都支持高级 Javascript(想想手机)。

      【讨论】:

        【解决方案8】:

        如果我希望我的应用程序在没有 Javascript 的情况下工作,我会在响应中发送 HTML。我会用我的服务器端语言(大部分时间不是 Javascript)编写 HTML 渲染代码,然后可以将其用于两个目的:提供整个 HTML 页面,以及提供 HTML 片段以响应 XHR。

        如果 Javascript 代码仅限于报告 UI 事件和用服务器生成的代码替换 innerHTML,我不必跨语言/框架复制任何应用程序逻辑。这种重复问题是服务器端 Javascript 令人兴奋的原因之一。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-10-15
          • 1970-01-01
          • 2018-01-20
          • 2020-01-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多