amazon-web-services - 在所有 aws 服务中,为单页应用程序提供 index.html 的最高效方法是什么?

标签 amazon-web-services caching single-page-application amazon-cloudfront

试图找到在 AWS 中为单页应用程序提供 index.html 文件的最高效方式。主要要求是:

  • AWS 服务必须能够从通配符域(例如 *.domain.com)提供文件。 .
  • SPA 宁愿不使用基于哈希的路由,这意味着 https://foo.domain.com/path/to/resource优先于像 https://foo.domain.com/#/path/to/resource 这样的 URL .

  • 直接从 lambda 支持的 API 网关提供文件似乎不可行,因为这种方法不满足自定义通配符域要求。

    我们尝试“失败”以使用由 S3 源支持的 Cloudfront。要将 SPA 与 cloudfront 和 HTML5(非基于哈希)路径路由一起使用,您必须指定 CustomErrorResponses为 http 状态代码提供 index.html 文件 404403 .虽然这可以正确地为 index.html 文件提供服务,但响应总是以 x-cache: Error from cloudfront 结束。标题。这意味着在将 index.html 作为默认错误文档提供之前,cloudfront 需要时间在 S3 源中查找 HTML5 路径。将此与 Cloudfront 使用源响应 Lambda@Edge 函数添加自定义 http header 这一事实相结合,会增加这些非缓存响应的延迟。

    在美国的某些地区,我们看到对该文件的请求需要 500-1000 毫秒。例如,对于在弗吉尼亚州托管的云前分发和在美国中部的查看器,请求似乎从查看器路由到最近的边缘位置(有时更远的西部),然后往返于弗吉尼亚州(托管 S3 源的地方) ,然后最终从边缘位置返回到查看器。

    我们还尝试使用 Lambda@Edge 缓存错误响应正文和 header ,但未成功。

    我们还没有尝试的是:
  • 应用程序负载均衡器指向一个 lambda 函数(有或没有 API 网关)
  • Application Load Balancer 直接指向一个 EC2 实例。

  • 在我们决定尝试这些更昂贵的托管选项之前,请询问社区是否有办法根据我们的要求使 cloudfront 的性能更高。如果不是,我希望 EC2 有可能比 ALB/lambda 性能更高,因为 EC2 不应该遭受冷启动?这是一个准确的假设吗?

    最佳答案

    对此的解决方案是让 Cloudfront 分发版定义除 DefaultCacheBehavior (*) 之外的其他缓存行为。

    使用原始请求 lambda@edge 关联设置默认缓存行为。当源请求关联被调用时,它应该返回一个响应,包括 index.html 文件内容以及任何必需的 header 。此响应将缓存在任何请求的虚拟路径的分发中。 lambda@edge 函数有两种方式获取这些内容:

  • 在函数代码中,为位于 cloudfront URL(例如 dklyksfhsksdgjh.cloudfront.net/index.html)的 index.html 文件调用 http(s) get。该分发将根据您还将设置的不同的非默认缓存行为返回文件。这种方法在第一次请求任何虚拟 html5 路径时提供的性能低于最佳性能,但后续请求将提供来自 Cloudfront 分发缓存的内容。
  • 在函数的构建过程中,将 index.html 文件的内容嵌入到 lambda@edge 函数代码中。这种方法比选项#1 提供更好的性能,因为不需要网络请求来获取文件内容。

  • 另外为路径模式设置另一个缓存行为 /index.html具有原点响应 lambda@edge 关联。当调用源响应关联时,它应该向响应添加任何必需的 header 。

    如果发行版包含其他文件(例如/robots.txt、/favicon.ico、/fonts、/scripts、/styles 等),请设置与这些路径匹配的其他缓存行为。这是必需的,以便在默认缓存行为的原始请求 lambda@edge 关联期间,对这些文件的请求不会返回 index.html 文件。

    通过这种方法,对应用程序根目录(即 www.site.com 或 www.site.com/index.html)的请求将匹配/index.html 缓存行为,从其 S3 源获取文件,添加任何需要的 header 通过原点响应 lambda@edge 关联,并缓存文件。第一个请求应该包含 x-cache: Miss from cloudfront响应头,但后续请求应该返回 x-cache: Hit from cloudfront直到缓存 TTL 到期。

    对其他文件(例如/robots.txt、/scripts/myscript.js 等)的请求将匹配您为分发中的其他文件路径定义的其他缓存行为。

    对虚拟 HTML5 路径的请求(即 www.site.com/path/handled/by/javascript)将匹配默认缓存行为,并且由于原始请求 lambda@edge 关联,返回 index.html 而不检查任何文件在 S3 原点。您仍然需要添加任何必需的 header ,例如为/index.html 缓存行为所做的原始响应 lambda@edge 关联。请求将被缓存,但每个虚拟 HTML5 路径将被单独缓存。例如,对/foo 的请求和对/bar 的请求都将在缓存之前调用 origin-request lambda@edge 关联。

    关于amazon-web-services - 在所有 aws 服务中,为单页应用程序提供 index.html 的最高效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58167544/

    相关文章:

    javascript - 我可以使用菜单或按钮在单页应用程序上切换 react 组件吗?

    amazon-web-services - 将 AWS CLI "sync"结果输出到 txt 文件

    amazon-web-services - AWS CodeBuild 解压缩大小必须小于 350198 字节

    asp.net - SqlCacheDependency在 View 和过程上

    javascript - Kendo UI TreeView 和数据源 : from basic to SPA

    javascript - 当您在 angularjs 中启用 html5 模式时会发生什么?

    amazon-web-services - 将 key 对导入 Amazon AWS - 指纹错误?

    android - AWS s3 TransferListener 未在 Android 中更新

    caching - Shopify 缓存 - 哪些操作导致清除缓存

    php - 使用键模式从 Laravel 4 缓存中删除?