之前在浏览一些技术文章时,发现很多分享前端部署完成后,告知用户有更新,需要刷新页面等部署方案。
有使用轮训的、有使用websocket双向推送的、有全局监听error事件的,等等。
不但没必要,还增加了很多成本,前端代码和配置文件都要维护一套版本号,来告知用户有更新。前端又无休止的轮询,耗费资源,但大部分时间是不更新的。
我就在想什么场景下,需要告知用户,立即马上赶紧刷新页面,“快快快,赶紧刷新页面,我们更新啦”。如果用户继续停留在当前页操作会怎样?有的博主在讨论中也给出了一些原因:
- 前端在发布时,会把之前构建好的静态文件删除掉,然后再部署新的静态文件;
- 接口不做向前兼容,每次都是破坏性掉更新;
- 政策问题,需要立即马上屏蔽掉;
就现在成熟的前端部署方案(静态资源contenthash部署,index.html不缓存),除了第2点需要后端开发同学做兼容外,第1、3点都不是啥问题,再快也得需要改代码,而且部署流程也很快,流水线大部分在5分钟之内肯定能跑完。而且html也是静态资源,完全都可以放到对象存储中。不需要容器或者实体服务器的部署。
针对第2点,接口不做向前兼容,是啥小作坊式的开发?现在大流量的网站,每天有百万、千万次的访问量,是上线之后再也不更新了?还是每次都停机维护?这么高流量的网站都能做到无感更新,你的网站就得破坏性更新?只要用户不是第一时间更新,就给用户的脸上甩个error?如果新功能在原接口上的改动确实很大,无法做到向前兼容。那最好就是启用新的接口地址,原接口的功能和参数保持不变。
有的同学可能不太了解前端增量发布的部署方案,这里简单介绍下。
- 构建时,依据文件内容生成带有hash的文件名,文件内容产生变动,则生成新的hash值;目前大部分的脚手架都已经实现并自带了该功能,开发者无需进行任何改动;
- 直接用对象存储服务(如阿里的OSS,腾讯的COS等),部署当前次构建产生的静态资源,不删除之前的静态资源,hash变动了则为新的文件,hash不变的文件说明内容没变动,覆盖了也没事儿;
- 静态资源使用CDN,启用强缓存,可有效提高访问速度;
- index.html不启用缓存,每次刷新都获取最新的内容;
这种部署方案,既保证了在部署过程中,新旧页面都能正常访问,也能利用CDN强缓存的特性,提高用户的访问速度。
有的人可能又会提到,如果前端页面和接口更新的内容正好是用户现在正在操作的,比如正在填写表单(前端页面是旧的,接口已经更新了,新增了几个必填的字段),用户岂不是会失败?这种情况需要在接口先发布时,让新增的字段为非必填,然后前端后发布。这样既保证了之前未填写新字段的数据能保存上,也能保证刚打开新页面用户提交新的字段。
从整体的部署上线流程来看,前后端构建部署的时间本来就不太一样,而且后台服务器有N多台,肯定是分批更新的,有的先部署完成,有的后部署完成,一定是存在时间差的。瞬时流量打过来后,有的进入了刚部署完成的机器上,有的进入了之前的机器上。同时,在后台程序部署之前,数据库表和各种脚本是不是得先准备好?这时就已经存在数据和程序不一致的情况了。你们是怎么做到,既能破坏性地更新,服务又能正常运行的?
你不会说你的后台服务器只有一台吧?那还做啥前端实时更新了?每次后台服务在部署时,所有的流量访问全部挂掉,再实时更新还有啥用?
再一个,你弹窗告知用户有新版本,需要刷新页面。用户的表单正填写了一半,是刷新页面还是不刷新?刷新的话,表单数据没了,不刷新,前后端不同步。如果刷新了还能保留表单的内容,又增加了开发的成本。
最后,从技术实现上,也比较麻烦:
- 在代码中维护一套新旧版本号对比(各种方案都有),并通知用户更新的代码;
- 修改部署流程,将版本号传到代码中;
- 单独维护一个最新版本号的配置,用户端从这里拉取最新的版本号进行对比;
这一套下来,才能对比版本号,付出和收益不生正比,得不偿失啊。
再说了,我们不是原生客户端,必须得发版才能更新,web端比客户端的优势,不就是无感更新吗?
一般地,若前端增量发布方案还解决不了的问题,实时动态刷新的部署方案,也依然解决不了。