V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  karott7  ›  全部回复第 5 页 / 共 13 页
回复总数  259
1  2  3  4  5  6  7  8  9  10 ... 13  
2022-12-01 17:56:27 +08:00
回复了 itechnology 创建的主题 程序员 怎么随时分辨出哪个是预生产环境,哪个是生产环境呢?
这么搞肯定出问题,长期下来有几个人能分得清?不都是固定环境么
2022-11-29 15:24:05 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@janus77 你这么做完全没考虑资源加载速度的问题,万一刚好网络波动呢?万一更新的 js 资源过大呢?还有 load 的时候屏幕会闪烁吧,这体验也不好。
再说我从头到尾都没说一定要实时更新。
2022-11-29 11:00:17 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@star7th 也不能说是假需求,只能说场景有限,自动售货机是一个场景
2022-11-29 10:59:31 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@shengchao 不需要用 service worker ,我就用 fetch('/') 方法每五分钟请求一次,拿到响应头 etag 对比一下,不一样的话就表示版本更新,然后我在适当的时机 location.reload() 就更新版本了
2022-11-28 13:10:37 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@menglizhi2333 我觉得没必要做成 PWA ,按照 #28 的方案,我觉得已经可以完成这个功能了,虽然有点瑕疵,但是对于 js 体积不大的项目来说已经完全够用了
2022-11-28 13:09:24 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@blankmiss 我不懂灰度部署,不过#15 的方案中对比以文件内容生成 hash 值其实更好一点,线上项目也可能遇到回滚。
还有一种方式,fetch('/') 拿到 http etag 响应头,这也是个 hash 值,服务器自动生成,直接对比这个就好了
2022-11-28 11:17:08 +08:00
回复了 karott7 创建的主题 程序员 请问线上 web 项目如何自动更新?
@heishu 抱歉,#10 的话我说错了,不是‘请求’,是请问;
我觉得不用后端参与,越少人参与越好
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 一般用户加载也不慢,我只是觉得和服务器有交互的页面没必要走离线包

先睡了,明天再讨论
1  2  3  4  5  6  7  8  9  10 ... 13  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1148 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 17ms · UTC 18:34 · PVG 02:34 · LAX 10:34 · JFK 13:34
Developed with CodeLauncher
♥ Do have faith in what you're doing.