V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  karott7  ›  全部回复第 5 页 / 共 13 页
回复总数  252
1  2  3  4  5  6  7  8  9  10 ... 13  
2022-11-28 10:44:05 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@opengps '想知道如何在用户不点击刷新或者不重开网页的情况下让用户获取最新版本代码?'
有前提,在用户不点击刷新,‘用户’
2022-11-28 10:07:44 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@opengps 我没有要求无感体验哦
2022-11-28 10:06:39 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@neoblackcap @opengps @dcsuibian @ryougifujino

我觉得大家都把这个功能实现想复杂了,不必用 websocket ,也不搞热更新,也不用其他同事配合,只要前端一个人能就能完成。帖子开头和 #7 楼也把前提说清楚了,这个方案是针对 to b 的,比如自动售货机,肯定有一段空闲时用户不在使用的。
其实有些人已经说到点子上了,自动更新版本肯定得用 js 执行 location.reload(),肯定得增加版本号(但这个版本号不用是 x.y.z 的形式,应为要额外为版本判断写代码);

我昨晚也实验了一下,因为我目前就在做自动收银机的项目,大家看看这个方案咋样:
-- 给 index.html 文件设置 http 缓存响应头 no-store 或者 no-cache ,保证每次拿到的 index.html 文件都是最新的
-- 给 js/css/img 等其他资源设置一个比较长时间的缓存响应头,比如一年。
-- 每次打包都给 index.html 文件中的 html 元素增加当前打包的时间戳,打包后的 <html /> 元素就变成了 <html data-timestamp="..." />, 这个时间戳其实就是版本号,因为我们只需要探测最新版本
-- 我在全局增加一个每隔几分钟获取 index.html 的请求,fetch('/').then(response => const bodyString = response.text()), 拿到 document 字符串,再用正则解析出 data-timestamp 去和 document.documentElement.dataset.timestamp 对比,如果比这个值大,就是最新版代码,然后再检测用户没操作多少秒执行 location.reload(), 这样就更新代码了

再说下 location.reload() 的执行前怎么才能不破坏用户体验
- 如果是自动售卖机,我会给个 3 秒倒计时的弹窗,有文案提示系统检测到版本更新,即将更新,倒计时结束后就 reload
- 如果是后台管理,我会像 vscode 每次更新一样,右下角给个提示,让用户自己觉得是否更新

这个方案我昨天以为能最小代价更新代码,比如我只更新了一个 js 文件,我就希望刷新后除了这个 js 文件其他文件都能走缓存;其实不是,因为打包工具(比如 rollup )不止会给该 js 更新 hash ,所有引入该 js 文件的文件名中的 hash 都会改变,这就导致该 js 的祖先文件都不能走缓存了,现在服务器都是按请求收费的,这样肯定不划算,但目前没办法。

不过如果你把外部库( node_modules )都单独分割出来,这个 js 文件(一般称为 vendor )基本是不变的,所以我觉得即使是在弱网环境下,reload 也不会太慢。

不知道大家咋看?
2022-11-27 22:19:32 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@blankmiss 我想过,其实不会,因为有 http 缓存配合,更新版本一般只更新几个文件,没更新的文件会走缓存。我不会也不想存任何文件在 storage 里;再说网络不好,那请求也走不通,那得不好页面也没事。
你的方案和我想的一样,轮训,然后等用户没操作了就主动刷新浏览器。但我想知道你是如何去知道有版本更新的?
2022-11-27 22:15:36 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@dcsuibian 请求怎么做版本判断?
2022-11-27 22:08:14 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@kaneg 这个方案的场景当然不是针对 toC 的,是针对后台管理以及自动售卖机等项目的,毕竟每次发布都通知别人刷新浏览器不太方便。
比如盒马的自动售卖机,一个城市有十几二十台机器,如果能做到自动更新,有两个好处:1. 不用担心白天用户使用的时候发布代码后用户还在使用老版本 2. 不用通知工作人员重启应用
2022-11-27 21:41:21 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@Puteulanus 应该要重载,我想不出怎么在不重载的情况下更新某个 js 或者 css 文件
2022-11-27 21:23:13 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@neoblackcap 请问线上代码怎么做热更新?
2022-11-27 21:21:04 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@neoblackcap 不至于用上 websocket 吧,这成本也太高了。
2022-11-25 22:12:32 +08:00
回复了 karott7 创建的主题 程序员 做 App + H5 混合应用的请进,想听听看看
@woxihejinghao 离线包加载完成后肯定行啊,重要的是人力成本;你说的更新这些,http 缓存机制都有,除去 cache-control 相关的相应头还有 Last-Modified ,etag
2022-11-25 22:08:11 +08:00
回复了 karott7 创建的主题 程序员 做 App + H5 混合应用的请进,想听听看看
@kamilic 感谢提供方案,等我有空也研究下 service worker
2022-11-25 22:05:24 +08:00
回复了 karott7 创建的主题 程序员 做 App + H5 混合应用的请进,想听听看看
今天工作忙,所以只能晚上来回复了;也感谢楼上几位朋友的分享,我也有一些新的收获。

--------------
先说下我为什么不太能接受离线包方案
1. 正常情况下 SPA 应用多数页面都是要和服务端交互的,你有页面不能走通接口有啥意义
2. 离线包我公司要前端 /后端 /客户端三人合作,前端还有控制版本,人力成本高;至于离线包增量更新,这不是重新实现 http 缓存方案吗?放着现有的 http 缓存机制不用,自己花时间去做,不浪费时间?站在开发者角度,我觉得不够有效率
3. 站在用户角度,你能接受你手机的 app 下载在 H5 更新后就直接下载一个可能几兆的离线包,甚至很多页面你都不会访问。

我如何解决部分白屏时间的 (我用 react ):
1. H5 加载流程是这样:webview 启动( A )-> 请求 index.html 并解析( B ) -> 请求主要模块和首页资源( C ) -> 进入首页( D );
可能造成页面白屏的阶段是 A 、B 、C ,A 阶段到 B 阶段( dom 和 css 解析完成之前)需要客户端处理(加个 loading ?),B 阶段 ( dom 和 css 解析完成之后)就会展示 <div id="root"></div>,这里开始到 C 阶段又是一段比较久的白屏,因为主要模块一般比较大(几十到两三百 kb );
- A 阶段我就不说了,不是前端能处理的
- B 阶段到 D 阶段之前是可以处理的,其实 <div id="root"></div> 可以改为 <div id="root"><span class="loading" /></div> 的,dom 和 css 解析完到 react 模块加载完成是就会展示这个 loading 样式(用 style 会比 svg 动画好);然后主要模块体积也要小,引入外部模块也要考虑模块体积。打包后的首屏体积一般 500kb 以下,控制到 100kb 也不是没可能
- D 阶段进入首页之后就用 import 方法预加载其他页面或者模块资源。( service worker 我没研究,就不说了

2. 说说 http 缓存
- 服务器会默认给 html 、css 、js 、img 等资源设置一个 3600s 的缓存有效期。假设你什么都不做,你更新内容发布上线,会有页面没更新的情况,因为 html 这个文件是有缓存期的;需要对这个入口文件设置 no-cache (感谢 @lisongeee 提醒协商缓存) 或者 no-store 缓存响应头,就能保证每次进来都是最新的;其他资源都设置一年缓存过期时间,这样对用户体验就很好了,只要用户访问过该资源,设备就会缓存资源到本地,二次进入就是秒开。

我觉得对于 SPA 应用,即使是弱网环境,客户端在获取 html 之前设置 loading 展示 + 前端加载主要模块设置 loading + http 缓存

------
@kop1989smurf 你说的首屏广告这都属于特殊情况,还有类似笔记应用等多数页面不用和服务端交互的我觉得用离线包没问题,但是用户上面的解决白屏的方法+控制首屏资源体积+http 缓存真的适用于大多数场景。

或许 app 加载后可以在后台开个 webview 预加载 H5 首页,之后再访问 H5 主要模块不就走缓存了么?
2022-11-25 00:14:23 +08:00
回复了 karott7 创建的主题 程序员 做 App + H5 混合应用的请进,想听听看看
@kop1989smurf
1. 首先不是来争论哪个方案绝对胜利的,我只是表达 http 缓存方案大多数情况下完全满足需求,像首屏广告这样没有请求的静态资源走离线包提前获取很合理。

2. 没说首次加载不重要,对于 spa 应用,页面都是懒加载,首屏资源体积如果控制得好,几百 kb 一般用户加载也不慢,我只是觉得和服务器有交互的页面没必要走离线包

先睡了,明天再讨论
2022-11-24 23:58:44 +08:00
回复了 karott7 创建的主题 程序员 做 App + H5 混合应用的请进,想听听看看
@Bijiabo 其实也没有确切的定义,我会在进入首页后用 setTimeout(preload, 500) 去加载其他页面资源,比如使用 import ,vite 会给你生成 <link rel="modulepreload" src="" />
2022-11-24 23:40:38 +08:00
回复了 karott7 创建的主题 程序员 做 App + H5 混合应用的请进,想听听看看
@july1995 我是全局设置一个元素和一个状态,请求后的数据如果要看,就打印成 json 放在当前页面后面
2022-11-24 23:39:08 +08:00
回复了 karott7 创建的主题 程序员 做 App + H5 混合应用的请进,想听听看看
@kop1989smurf
1. 先说 app 需要新的静态 html 广告的问题,我觉得这个属于特殊场景,我也不是做客户端的,不过启动广告一般都是用 cdn 提速加载吧,靠默认的加载肯定不满足需求,另外这中广告如果是图片的话走缓存的话也就第一次加载慢点,后面都是缓存
2. 说下 http 缓存机制不可控在哪?请举例
2022-11-24 23:35:21 +08:00
回复了 karott7 创建的主题 程序员 做 App + H5 混合应用的请进,想听听看看
@stardust21 你这个想法其实就是 http cache 的逻辑,http 缓存都是存在你的手机或者浏览器本地,https://stackoverflow.com/questions/61824427/where-is-the-storage-location-of-the-browsers-http-cache-disk-or-memory
2022-11-24 22:41:01 +08:00
回复了 karott7 创建的主题 程序员 做 App + H5 混合应用的请进,想听听看看
@RightHand @StarainX @stefanieewu @wu67
我公司做的 app 是面向手机低端用户,他们手机不太好,网络也差,所以就经常首次加载白屏,我那时候技术不行,不会用 http 缓存以及解决首屏加载时白屏问题,所以当时就选择了离线包方案。
- 离线包方案也还行,进入 app 首页就全量加载所有 H5 资源,用户网络不好也能加载页面。缺点是随着 H5 项目增大,我觉得每次全量加载浪费带宽流量,当然也可以做增量,但这不是重新实现 http 缓存么;你要真说用户网络很差提前加载页面,但现在页面都要请求,有页面没请求响应不也一样么
- 使用 http 缓存我觉得应该是很好的方案,index.html 设置 no-store ,css/js/image 等其他资源设置比较长的有效期,用户按需加载,我觉得对于绝大多数情况表现都好;对于某些场景,可以在页面空闲时间预加载其他页面资源

就是跟同事就这两个方案意见不一,来看看大家怎么选的
2022-11-19 23:46:21 +08:00
回复了 Angela2022 创建的主题 程序员 [javacript 的 this 指向问题, 高手请进]
一楼答案正确且简洁
看官网就好了,然后上网找人要个项目源码看看,再自己试着实现某个网站的几个页面
1  2  3  4  5  6  7  8  9  10 ... 13  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3559 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 23ms · UTC 10:37 · PVG 18:37 · LAX 02:37 · JFK 05:37
Developed with CodeLauncher
♥ Do have faith in what you're doing.