Skip to content

本文由 简悦 SimpRead 转码, 原文地址 mp.weixin.qq.com

图片

那些前端部署后要实时通知用户更新页面的方案,看来看去,总是觉得别扭

之前在浏览一些技术文章时,发现很多分享前端部署完成后,告知用户有更新,需要刷新页面等部署方案。

如何通知用户的文章

有使用轮训的、有使用 websocket 双向推送的、有全局监听 error 事件的,等等。

不但没必要,还增加了很多成本,前端代码和配置文件都要维护一套版本号,来告知用户有更新。前端又无休止的轮询,耗费资源,但大部分时间是不更新的。

我就在想什么场景下,需要告知用户,立即马上赶紧刷新页面,“快快快,赶紧刷新页面,我们更新啦”。如果用户继续停留在当前页操作会怎样?有的博主在讨论中也给出了一些原因:

  1. 前端在发布时,会把之前构建好的静态文件删除掉,然后再部署新的静态文件;

  2. 接口不做向前兼容,每次都是破坏性掉更新;

  3. 政策问题,需要立即马上屏蔽掉;

就现在成熟的前端部署方案(静态资源 contenthash 部署,index.html 不缓存),除了第 2 点需要后端开发同学做兼容外,第 1、3 点都不是啥问题,再快也得需要改代码,而且部署流程也很快,流水线大部分在 5 分钟之内肯定能跑完。而且 html 也是静态资源,完全都可以放到对象存储中。不需要容器或者实体服务器的部署。

针对第 2 点,接口不做向前兼容,是啥小作坊式的开发?现在大流量的网站,每天有百万、千万次的访问量,是上线之后再也不更新了?还是每次都停机维护?这么高流量的网站都能做到无感更新,你的网站就得破坏性更新?只要用户不是第一时间更新,就给用户的脸上甩个 error?如果新功能在原接口上的改动确实很大,无法做到向前兼容。那最好就是启用新的接口地址,原接口的功能和参数保持不变。

有的同学可能不太了解前端增量发布的部署方案,这里简单介绍下。

  1. 构建时,依据文件内容生成带有 hash 的文件名,文件内容产生变动,则生成新的 hash 值;目前大部分的脚手架都已经实现并自带了该功能,开发者无需进行任何改动;

  2. 直接用对象存储服务(如阿里的 OSS,腾讯的 COS 等),部署当前次构建产生的静态资源,不删除之前的静态资源,hash 变动了则为新的文件,hash 不变的文件说明内容没变动,覆盖了也没事儿;

  3. 静态资源使用 CDN,启用强缓存,可有效提高访问速度;

  4. index.html 不启用缓存,每次刷新都获取最新的内容;

构建产物

这种部署方案,既保证了在部署过程中,新旧页面都能正常访问,也能利用 CDN 强缓存的特性,提高用户的访问速度。

有的人可能又会提到,如果前端页面和接口更新的内容正好是用户现在正在操作的,比如正在填写表单(前端页面是旧的,接口已经更新了,新增了几个必填的字段),用户岂不是会失败?这种情况需要在接口先发布时,让新增的字段为非必填,然后前端后发布。这样既保证了之前未填写新字段的数据能保存上,也能保证刚打开新页面用户提交新的字段。

从整体的部署上线流程来看,前后端构建部署的时间本来就不太一样,而且后台服务器有 N 多台,肯定是分批更新的,有的先部署完成,有的后部署完成,一定是存在时间差的。瞬时流量打过来后,有的进入了刚部署完成的机器上,有的进入了之前的机器上。同时,在后台程序部署之前,数据库表和各种脚本是不是得先准备好?这时就已经存在数据和程序不一致的情况了。你们是怎么做到,既能破坏性地更新,服务又能正常运行的?

你不会说你的后台服务器只有一台吧?那还做啥前端实时更新了?每次后台服务在部署时,所有的流量访问全部挂掉,再实时更新还有啥用?

再一个,你弹窗告知用户有新版本,需要刷新页面。用户的表单正填写了一半,是刷新页面还是不刷新?刷新的话,表单数据没了,不刷新,前后端不同步。如果刷新了还能保留表单的内容,又增加了开发的成本。

最后,从技术实现上,也比较麻烦:

  1. 在代码中维护一套新旧版本号对比(各种方案都有),并通知用户更新的代码;

  2. 修改部署流程,将版本号传到代码中;

  3. 单独维护一个最新版本号的配置,用户端从这里拉取最新的版本号进行对比;

这一套下来,才能对比版本号,付出和收益不生正比,得不偿失啊。

再说了,我们不是原生客户端,必须得发版才能更新,web 端比客户端的优势,不就是可以无感更新吗?

一般地,若前端增量发布方案还解决不了的问题,实时动态刷新的部署方案,也依然解决不了。

腾讯新闻构建高性能的 react 同构直出方案

腾讯新闻抢金达人活动 node 同构直出渲染方案的总结

仿 Vue2.x 中的双向数据绑定实现

▼我是来一名小小的前端开发工程师,

长按识别二维码关注,与大家共同学习▼