【问题标题】:HTTP Server push for angular modulesHTTP 服务器推送 Angular 模块
【发布时间】:2018-06-08 03:55:46
【问题描述】:

为了提高性能和减少负载而对 Angular 进行的所有最新和即将进行的更新都让我相信,终于是时候从传统的 aspnet mvc 应用程序更新我们的网站了。

我将网站拆分为模块,包括用于我们的主要目标网页的单独模块 - 这些模块可通过 google 或 facebook 广告访问。我显然想确保这些加载尽可能快。

在我的 JavaScript 启动之前,我过去使用 HTTP 服务器推送来推送页面所需的资源,并且我喜欢在这里做同样的事情。

例如。如果 aspnet 服务器收到对 /producttour 的请求,那么我想推送带有 http 标头的“产品之旅”模块 javascript,以便服务器可以立即开始发送它。这将删除该文件的一次服务器往返行程(这可能是一个相当大的文件)。我可能还想推送我知道到处都需要的文件,例如 vendor.js

是的,我知道这仅适用于第一页 - 之后您将进入 Angular 水疗中心,并且模块将正常加载。

我似乎找不到其他人谈论这让我感到惊讶。

  • 使用 URL 哈希,每次构建时文件名都会更改,所以我不知道如何提前检索它以发送硬编码的文件名。
  • 如果没有 URL 哈希,我可能会意外加载陈旧的代码。

我最好的想法是 Ng 构建到 index.htm 并禁用散列,复制该页面,然后在服务器端手动添加 ?version 并添加标题。

【问题讨论】:

  • 长镜头..您是否正在研究服务器端渲染以获得更快的页面服务? angular universal
  • 可能不会。但我想我应该测试两者。担心这会产生其他问题(但不确定是什么)
  • Angular 6 路由支持延迟加载。这意味着除非你去/producttour,否则它永远不会被加载。这对大多数情况来说还不够吗?
  • @Ozgur 应该是大部分,但我想避免任何闪烁。我想将不得不测试它。我还有很长的路要走,才能证明花太多时间来实现它是合理的,但我想知道以前是否有人做过。我确实看到当前站点中的服务器推送确实提高了一些速度。
  • 让我直说吧;因此,当用户点击您的这个广告时,index.html,然后是主包 + 您拥有的任何供应商,然后这个代表着陆页的单独延迟加载模块正在/应该被下载,您的目标是开始加载所有一旦 index.html 即将发送给客户端,那些 JS 资产,我在这里暖和了吗?

标签: angular asp.net-core


【解决方案1】:

所以这个问题基本上不完全是 Angular 特定的,但它关注的是在 Angular 实际启动之前会发生什么。 问题可以分为两部分:

  1. 如何识别需要哪个文件(哪个延迟加载模块)才能在 Link 标头中发送它?
  2. 一旦文件被识别,如何获取它并将其与应用程序的其余部分连接起来

让我们直接进入 Nr.1.

  • 你的延迟加载模块不一定有那些“丑陋”的哈希名称,你可以使用--named-chunks甚至--output-hashing=none和你的ng build命令。这将生成相当正常的名称,您可以将其用作 ID,而且我很确定 angular-cli 中有一些命名自定义可能是最重要的,但我会留给您。
  • 现在假设您在 应用服务器 上直接拥有该文件,即使它具有缓存破坏哈希值,您也能找到它。为此,需要一个小脚本来找到它、获取名称并使用该名称来发送 Link 标头。

    或者该文件位于 CDN 上,您很可能不希望在文件名中包含缓存破坏哈希,在这种情况下,再次很容易识别它。唯一的问题是缓存,但您可以使用例如Azure caching article 中所示的查询字符串模式来解决它。

Nr.2. 现在您已经获得了文件名,您可以发送链接头了。在发送 index.html 之前,您唯一需要做的另一件事是 您必须在其中包含 <script> 标签和 src=/path/to/the-lazy-module,您可以使用来自点的信息1,所以服务器上还需要一点脚本或模板。

我用“顺序”测试了这种方法,然后是 asyncdefer script 标签,并确保延迟加载的模块首先或最后到达,它似乎没有区别。实际上,延迟加载是从 @angular/router 开始的(当然),最后由 Webpack 的require.ensure 执行,它在<head> 中添加自己的<script> 以获得懒惰的模块,所以我的猜测是它检查这样的 script 是否已经存在。因此,您不必担心订单或它会被加载两次,而是自己测试一下。

这样做的结果是,一旦 index.html 即将发送,你的资源应该立即被推送,并且一旦 Angular 被延迟加载的模块将自动连接到你的应用程序开始寻找他们。

【讨论】:

  • 感谢@dan 并感谢您进行测试。关于手动添加脚本标签的有趣点。我想知道如果您执行或不执行此操作,性能会受到怎样的影响。如果服务器已经在推送它,那么我认为只要在加载模块时 Angular “请求它”,它就会立即可用。
  • 我尝试推送未在 index.html 中声明的公共资产,但我没有设法推送它们。我只设法将那些声明为<script> 的人推送。或者没有它也可以做到吗?我不知道还有什么办法。关于性能,这不是什么大问题,基本上它只是修改发送给客户端的字符串。为了使其更快,可以使用文件名始终相同的 CDN 方法,或者以某种方式配置/编写一个 webpack 插件,该插件采用某些延迟加载的模块名称并将它们作为<script>s 粘贴到 HTML 文档中。
猜你喜欢
  • 2016-02-05
  • 2011-08-17
  • 2017-09-06
  • 2017-04-06
  • 2016-12-27
  • 2017-06-26
  • 1970-01-01
  • 2019-05-24
  • 1970-01-01
相关资源
最近更新 更多