【问题标题】:Support defunct javascript post deploy支持已失效的 javascript 发布后部署
【发布时间】:2013-06-21 06:17:07
【问题描述】:

背景:

我有一个单页 JavaScript 网站,每天至少部署一次。它获得了合理的流量,并且用户在其上停留了相当长的时间,直到他们结帐并且 JavaScript 通过 XHR 与后端交互。

问题:

部署后浏览器中加载的 JavaScript 可能不再与后端(本例中为 Rails)兼容。

可能的解决方案:

a) 定期比较资产管道指纹,window.confirm 与重新加载请求是否相同。

b) 与 XHR 请求一起发送 X-JS-fingerprint 标头,如果不兼容则返回 409 Conflict,JavaScript 将触发错误并重新加载 window.confirm。

c) 运行两个后端;一个使用新的 JS 和新的后端代码立即部署 (SERVER-1),另一个仍然支持旧的 JavaScript XHR 请求格式 (SERVER-2)。与 b) 一样,X-JS-fingerprint 标头将被发送,但不是 409,而是向 SERVER-2 发送 307 临时重定向以完成请求。一旦旧会话全部清除,SERVER-2 就会被部署并关闭,直到再次需要它为止。

如果有人以前考虑过这个问题,我很感兴趣。如果您对此主题有任何想法,请告诉我。

【问题讨论】:

    标签: javascript deployment single-page-application


    【解决方案1】:

    我也遇到过这个问题。我的解决方案非常简单,并没有真正尝试为用户避免错误。它类似于您的解决方案a

    我保留了一个版本号,就像指纹一样(所有文件也都有指纹,CSS/JS)。部署过程会自动增加版本号。即使我只是更改了一行 CSS,版本号也会增加。我不区分主要或次要版本更改,这只是语义。

    应用程序会不时 ping 服务器以检查版本。如果版本发生变化,则会出现 “请重新加载页面” 弹出窗口。 (页面顶部的非侵入性小thingie,非常明显且需要点击)。 如果用户不重新加载,您可能会遇到错误,因此如果版本不匹配,我也会禁用错误报告。

    此解决方案仅确保最终人们将切换到新版本,并且在用户切换时您不会收到任何错误。它不会迁移旧会话或防止用户出错。

    我不会做window.confirm。意外的模态对话框非常很烦人。如果您碰巧在输入内容并按下[space-bar][enter],对话框就会消失而您错过了。

    解决方案 b 可能看起来不错,但也有不利的一面。您将能够更早地检测到版本不匹配,但这也可能意味着您的用户会看到更多错误。如果网站的一小部分受到更新的影响,任何 XHR 请求都会失败,即使它不需要失败。这是需要考虑的事情。

    解决方案 c 对用户来说非常好,但可能会使升级变得很糟糕。如果您的数据库模型发生变化怎么办?旧服务器将无法正确处理数据,查询将失败等。


    我喜欢解决方案 a,因为它非常简单,而且如果您经常更新并进行许多小改动,那么每次更新的影响都非常小。

    【讨论】:

    • 您是否监控过重新加载(重新加载的用户与未重新加载的用户)?您是否观察到任何用户的挫败感(显示通知后放弃等)?
    • 我目前没有监控有关此功能的任何内容。我制作的应用程序没有产生任何统计意义的数量。
    【解决方案2】:

    曾经在 google 中创建了一个 diffable 项目,用于类似的用例。 它背后的基本思想是有点类似于你的变体a。唯一的区别是,当客户端检测到服务器更新时,它会自动更新客户端代码库,并且不会加载所有资源,而是加载差异补丁并将它们应用于客户端。这可能听起来有点疯狂,但从性能的角度来看,它实际上是有道理的。

    还有一个后继想法是使用 localStorage 来存储客户端代码库。还请查看https://github.com/plotnikoff/connect-diffable,它是一个 Node 项目,但可能仍然对了解这个想法很有用。

    您可以根据自己的情况更改方法,例如:

    1. 将客户端资产存储在 localStorage 每个版本都有校验和
    2. 不时或经常请求服务器检测是否推出了新版本
    3. 如果有更新版本,请求补丁并将其应用到本地存储中的资产,检查校验和。 (在这里,您可能希望将新版本的校验和与补丁一起发送,以便在应用后进行比较)。

    【讨论】:

    • 我喜欢这种技术,我将研究在当前项目中实现它的难度。谢谢。
    • 经过调查,我发现这里面有些东西。实现并不完全相同,因为我加载的是整个 javascript 而不是增量。这对于过程方法非常有效,但是任何已初始化的对象都原样保留在内存中,在我的情况下几乎是每个对象。尝试重新初始化所有需要的东西是有好处的,状态在 history 和 document.location 中处理。
    猜你喜欢
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    相关资源
    最近更新 更多