页面加载时,进度条/百分比的是靠什么技术获得到底加载了百分比例的

2018-02-22 16:43:57 +08:00
 edison111cry

有些页面加载过程中会显示进度条,或者是一个百分的比例,从 0 到 100 一点点显示。或者是加载一个文件图片,到 100%了显示出来。

就比如说我现在用 ajax 请求一个后台的文件,后台应该是不可能知道前端请求的进度的吧,那么前端是用的啥技术才可以显示加载的百分比呢,想问一下这是哪块的技术,求指导

7655 次点击
所在节点    问与答
24 条回复
knightdf
2018-02-22 16:48:56 +08:00
卡在 99%不就行了:dog:
edison111cry
2018-02-22 16:55:53 +08:00
@knightdf 以前做过一个上传文件的,需要展示上传的百分比数字,当时确实时卡在 99%时再用 ajax 去查询这个文件是否已经存在服务器上了,如果没有隔 3 秒再查,如果已经有了,就结束。

难道大神们都是这么做的?
loading
2018-02-22 16:56:12 +08:00
进度条,只要在动就行了。是算不准的。
不信你搜索 win10 的重启更新进度条,233
hxsf
2018-02-22 16:59:57 +08:00
原理:
http header: Content-Length 表明了响应的总长度。
当前接受到的 / Content-Length = 进度

实现:
xhr 的 progress Event
fetch 的 Response.body 上的 getReader() , render 可以读原始字节流,然后计算当前进度。
edison111cry
2018-02-22 17:02:25 +08:00
@hxsf 多谢,原来是这样。
whypool
2018-02-22 17:08:45 +08:00
document.readyState 可以判断状态,用这个模拟加载百分比
一般会迅速飙到 90%,剩下的 10%递归加一点,直到浏览器抛出 complete,退出递归进度百分比设置为 100%,取消 loading 动画
除非后端返回百分比,否则拿不到真实的加载百分比
whypool
2018-02-22 17:14:58 +08:00
@hxsf 这玩意并不能计算出总体百分比,只能拿到当前文档的大小,然而并发的或者异步的 json,css,js,图片这些资源,得服务器先响应 header 才能叠加计算,单个文件还 ok,多个就蛋疼
learnshare
2018-02-22 17:15:50 +08:00
单个文件如 @hxsf 所讲的方法
网页加载无法实时反映加载进度,因为可能直到最后一个文件加载完毕,才会知道数据总量
RihcardLu
2018-02-22 17:17:25 +08:00
技术的角度都说了,说点用户心里有关的。其实进度条的准确度可能不是那么重要,只要给用户那么个东西,『我正在加载,马上就完成了』,用户就会等待更久的时间(相比于什么提示都没有的页面)。
chairuosen
2018-02-22 17:25:41 +08:00
单说网页加载:

<script src='lib1.js'></script>
<script>setProgressBar(30)</script>
<script src='lib2.js'></script>
<script>setProgressBar(60)</script>
<script src='lib3.js'></script>
<script>setProgressBar(100)</script>
edison111cry
2018-02-22 17:27:00 +08:00
@chairuosen 我擦,这样倒真是个方法。 不错不错,学习了
hxsf
2018-02-22 17:51:03 +08:00
@learnshare #8
1. 链接建立拿到 header -> 更新 total size
2. 拿到内容 -> 更新 current size
如:
1s:189 / 800
3s: 772 / 1723
5s: 2300 / 2300 done!


或者

当前文件进度:123 / 6123B
总进度: 26 / 89 个

因为对于浏览器来说,加载资源可能是多个同时进行的。所以后者不好做。 前者就够了。
learnshare
2018-02-22 18:01:52 +08:00
@hxsf 已下载量和总量都在变化,进度是要倒退的
再说,分析关联文件这种事太复杂,除了浏览器本身,其他的都没必要去做
hxsf
2018-02-22 18:13:10 +08:00
@learnshare #13 进度变小,你可以倒退,也可以等待啊。
有没有必要做,看需求和收益,不是单看复杂不复杂,真有需求,写个 loader 又何妨呢。
LZ 只是问怎么做。我给了答案。
做不做,看 LZ 自己喽。
vuuv
2018-02-22 21:45:40 +08:00
具体进度主要靠人工提供。

最简单的就是达到某一阶段提升一个进度。
例如 0-10-40-70-100

进度条突然暴增体验不佳,然后有了一些改进来优化体验。
例如设定 0-10 一般需要 2s,那么进度条缓慢增加,如果你花 1 秒完成了,就突然从 5 跳到 10,如果迟迟没有收到通知,则会卡在 10。

可惜还是略感不佳,你可以增加额外的判断来动态调整时长。
例如一开始根据加载速度计算初始时长在 1-3 秒波动。如果 0.5 秒完成了,则加快后续的进度增幅。如果 5 秒才完成,则降低后续的进度增幅。
如此依次将前一阶段的进度耗时计入下一周期,这样可能看起来时快时慢,但是可以获得相对平滑的进度提示了。

后面是我的改进思路,实际上我只做到了第二步。
vuuv
2018-02-22 21:51:55 +08:00
我上面主要是针对多种耗时不等的情况的。
任务复杂也可以拆分到多个进度条里提示。然后提示所处阶段。

至于单一任务,上面提到实时计算就挺好的。额外设置定时动画反而不好。

进度条主要是告诉用户等待时间,以便客户决定是否“离开一会儿”,避免干等浪费时间。
vuuv
2018-02-22 22:12:05 +08:00
特别提醒,我最后构思的持续进度条可能存在部分负优化。

按照我的思路,如果设定 0-10 耗时 2s 完成动画,如果迟迟没有回应,则会在 2s 后占用下一进度的区间(向 40 进发),不过增幅逐步缓慢下来。在 0-10 完成后,根据之前的延时降低 10-40 的进度增幅。

如果出现意外导致相应阶段无法完成,这会造成一种它还活着的假象,造成误导。白等浪费时间不说,还会提供错误的进度信息。
nciyuan
2018-02-22 23:05:17 +08:00
原来 Flash 可以,但是现在不行了。
最基本就是数据大小 /总大小
一般用户上传这种知道大小的可以直接给条,像是提交表单,或者动态数据,可以处理完一部分加一点
要是不定的或者别的直接动画
用条的也尽可能不要卡在 99%,因为如果等待时间很长那么到了 99%用户是不想刷新的
还有小的数据网速快的话条还没加载好数据都传完了
Humorce
2018-02-22 23:34:38 +08:00
最牛逼的还是分明一秒处理完,硬要加个 3 秒的进度动画的
azh7138m
2018-02-22 23:40:56 +08:00
@hxsf 老哥,content length 又不是一定会有,gzip 了解一下

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/431701

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX