兄弟们, vue 网页有没有办法实现页面首页加载超过 1 秒才显示 loading, 1 秒内就不显示 loading 吗 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
dafuyang
V2EX    Vue.js

兄弟们, vue 网页有没有办法实现页面首页加载超过 1 秒才显示 loading, 1 秒内就不显示 loading 吗

  •  
  •   dafuyang 2022-12-13 23:11:03 +08:00 6035 次点击
    这是一个创建于 1036 天前的主题,其中的信息可能已经有所发展或是发生改变。
    目前我采用的是常规的实现方式,在还 vue 没渲染的时候显示 loading ,挂载渲染后隐藏 loading ,首次效果不错,但是后续浏览器有缓存了,在加载很快的情况下,loading 的显示就会闪一下,感觉不是很爽,有办法实现我标题中的这种需求吗。。
    52 条回复    2023-01-14 00:05:49 +08:00
    lambdaq
        1
    lambdaq  
       2022-12-13 23:15:30 +08:00
    强行假装 1 秒再展示即可。
    dafuyang
        2
    dafuyang  
    OP
       2022-12-13 23:17:48 +08:00
    @lambdaq 这个我也想到了,延迟 1 秒在隐藏,看看其他兄弟有没有好办法,不行的话只能这么改咯。。
    renmu
        3
    renmu  
       2022-12-13 23:25:41 +08:00 via Android
    全屏 loading 的话可以强行多看几秒 loading
    rabbbit
        4
    rabbbit  
       2022-12-13 23:28:14 +08:00
    const timeoutId = setTimeout(() => this.loading = true, 1000)
    try {
    const res = await getResource()
    } catch(err) {
    console.log(err)
    }
    this.loading = false
    clearTimeout(timeoutId)
    horseInBlack
        5
    horseInBlack  
       2022-12-13 23:28:58 +08:00
    骨架屏 / v-cloak
    vace
        6
    vace  
       2022-12-13 23:29:43 +08:00
    如果你的 loading 在实例中的话,可以用 defineAsyncComponent 定义一个入口的异步组件,在 loader 里面加载数据和其他组件,用 delay 控制 loadingComponent 的展示时机。
    SQLException
        7
    SQLException      2022-12-13 23:30:34 +08:00
    记一下平均耗时?超过一定范围才渲染 loading
    anguiao
        8
    anguiao  
       2022-12-13 23:31:25 +08:00
    强行显示 1 秒的 loading 呗,不然还有啥办法呢?毕竟你不能预知要加载多久啊
    dafuyang
        9
    dafuyang  
    OP
       2022-12-13 23:41:54 +08:00
    @SQLException 咋判断时间呢,我题目就是问这个的意思。。
    SQLException
        10
    SQLException  
       2022-12-13 23:43:47 +08:00
    @dafuyang #9 https://juejin.cn/post/6844903569900978189
    参考这个?不是让你算现在这个页面加载多久再决定是否开启 loading
    是让你算前面几个页面的平均值,小于一定值就禁用 loading
    darkengine
        11
    darkengine  
       2022-12-14 00:04:33 +08:00
    在 index.html 的 head 元素里用 js script 脚本设置个 1 秒的 timeout ,到了再显示 loading 。当在 vue 加载出来时判断这个 timeout 在不,如果在的话(加载时间小于 1 秒)取消掉。
    sheeta
        12
    sheeta  
       2022-12-14 00:05:24 +08:00   8
    刚好 1.1 秒加载完成呢,loading 不还是一闪而过吗,所以问题不在这
    lightyisu
        13
    lightyisu  
       2022-12-14 00:53:25 +08:00
    以前好像做过但是没用判断不出来 contentloaded 时间 伪 1S 感觉在浪费时间尽管人感受不出来速度。所以感觉没必要折腾完美。
    yfugibr
        14
    yfugibr  
       2022-12-14 01:16:38 +08:00 via Android   1
    300ms 内没加载完才显示 loading ,如果显示 loading ,至少显示 1s
    MrHyde
        15
    MrHyde  
       2022-12-14 04:17:26 +08:00
    1s 已经够久的了
    huijiewei
        16
    huijiewei  
       2022-12-14 08:08:57 +08:00
    我是强制显示 1 秒的 loading 。。
    gaolingyi
        17
    gaolingyi  
       2022-12-14 08:15:57 +08:00   1
    antd 的 Spin 就是这种设计, 但是我觉得, 直接展示 loading,至少展示 300ms 的逻辑更简单
    ragnaroks
        18
    ragnaroks  
       2022-12-14 08:32:55 +08:00   1
    直接显示加载指示器,给这个组件加上 1 秒的 opacity 从 0 到 100% 的 transtion
    cangcang
        19
    cangcang  
       2022-12-14 09:25:44 +08:00
    让你的 loading 延迟一秒展示
    SmiteChow
        20
    SmiteChow  
       2022-12-14 09:29:06 +08:00
    谁喜欢看 loading 啊,一闪而过代表网速性能好,是正反馈啊。
    makelove
        21
    makelove  
       2022-12-14 09:49:05 +08:00
    我就是这么用的,实现没用 js ,用的是 css animation 就有的延迟动画 1s 功能
    yamedie
        22
    yamedie  
       2022-12-14 09:59:23 +08:00 via Android
    我会选择用 Promise.race ,好处是省得手动 set 和 clear 定时器(也不用去比对 Date.now()),逻辑也更清晰一点儿。

    const sleep = time => new Promise(resolve => setTimeout(resolve, time));

    let isLoading = false;

    const promiseSleep = sleep(1000);

    const promiseAjax = fetch(xxx).then(res => {xxxx 业务逻辑; return true}).finally(() => {isLoading = false});

    Promise.race([promiseSleep, promiseAjax]).then(res => {if (!res) isLoading = true});
    yamedie
        23
    yamedie  
       2022-12-14 10:03:34 +08:00 via Android
    噢,没注意审题,想在 vue 运行时还没加载时就开始计时并显示 loading ,应该在 html 的 head 里尽早加载独立的 script 来控制骨架屏的显隐吧
    justdoit123
        24
    justdoit123  
       2022-12-14 10:10:56 +08:00
    强制至少 loading X 秒的体验会好一点,效果稳定。比如,至少 loading 0.3 秒,如果 0.3 秒后页面还没准备好,那就继续 loading 。
    darknoll
        25
    darknoll  
       2022-12-14 10:15:24 +08:00
    vue 没渲染的时候显示 loading ,是怎么整的?
    kealm
        26
    kealm  
       2022-12-14 10:27:59 +08:00   1
    这个叫 grace time 。一般的处理方式是:1. 增加一个延迟 2. 增加最短展示时间。
    延迟时间内不显示 loading ,如果延迟时间内加载完毕,直接进入。如果延迟时间内没有加载完毕,显示 loading ,时间是 MIN(最短展示时间,实际时间)。
    kealm
        27
    kealm  
       2022-12-14 10:28:24 +08:00
    @kealm MIN => MAX
    dreamn
        28
    dreamn  
       2022-12-14 10:33:22 +08:00
    试试渐变显示 loading ,渐变退出 loading 的方案呢?
    这样视觉上就是不是闪烁效果了.....
    rrZ2C
        29
    rrZ2C  
       2022-12-14 10:41:18 +08:00
    设置至少 loading 1 秒
    flyingghost
        30
    flyingghost  
       2022-12-14 12:20:13 +08:00
    进页展示一个透明 1s 后渐入 100%的动画 loading 。
    4771314
        31
    4771314  
       2022-12-14 15:32:05 +08:00
    这个确定不是 yy 的需求或者老板的需求?
    听起来不怎么靠谱
    YouTing
        32
    YouTing  
       2022-12-14 15:46:52 +08:00
    请求速度快的时候出现 loading ,而较快时不出现。月经问题了,淘宝在用 setTimeout ,缺点是一秒左右的 loading 体验不好,0.9 秒没有 loading ,1.1 秒 loading 一闪而过
    QKgf555H87Fp0cth
        33
    QKgf555H87Fp0cth  
       2022-12-14 15:51:46 +08:00
    都被你们玩花了,该显示就显示,不显示就不要显示。
    jorneyr
        34
    jorneyr  
       2022-12-14 16:21:10 +08:00
    underscore 的 throttle 函数可以处理这个问题。
    296727
        35
    296727  
       2022-12-14 16:22:50 +08:00
    。。。。一个 css 的 transiton 不就可以了,还要这么折腾
    sanmaozhao
        36
    sanmaozhao  
       2022-12-14 16:31:44 +08:00
    这题我做过。
    分析一下题目:
    >> 在还 vue 没渲染的时候显示 loading ,挂载渲染后隐藏 loading
    这一条,把 loading 界面放到 vue 实例挂在的 DOM 元素里面就行了,挂载后组件渲染出来的 DOM 会替换原本的内容

    >> 首页加载超过 1 秒才显示 loading ,1 秒内就不显示 loading
    给上一条的 loading 界面加个 css 样式,透明度为 0 ,所以开始时看不到这个 loading 界面
    然后再加个 css animation ,1s 后把透明度变为 1 ,所以这时就能看到了
    样例代码:
    @keyframes fadeIntLoading {
    from {
    opacity: 0;
    }
    to {
    opacity: 1;
    }
    }

    animation: fadeIntLoading 0.1s linear 1s forwards;
    opacity: 0;
    sanmaozhao
        37
    sanmaozhao  
       2022-12-14 16:33:29 +08:00
    fadeIntLoading 不小心多打了个 t ,不过不影响功能
    loolac
        38
    loolac  
       2022-12-14 16:36:47 +08:00
    loading 添加渐显过渡动画,超过 1s 才全部显示出来,小于 1s 就是没全部显示就渐隐了
    jeffwcx
        39
    jeffwcx  
       2022-12-14 16:39:24 +08:00
    这个一般放到 html 里面做,不放在 vue 里面做
    sanmaozhao
        40
    sanmaozhao  
       2022-12-14 16:53:42 +08:00
    写了个样例,直接就有效果

    https://codepen.io/sanmao/pen/eYKwLRv
    isbase
        41
    isbase  
       2022-12-14 16:59:17 +08:00
    这个看起来和你说的异曲同工,https://baiyun.me/improve-the-user-experience-for-react-apps
    bitkuang8
        42
    bitkuang8  
       2022-12-14 18:10:50 +08:00
    这样行的不...

    ```js
    // 初始 loading 为 false

    let timer = setTimeout(() => {
    loading = true
    }, 1000)

    // 在 App.vue 的 mounted 钩子中
    loading = false // 假设加载资源已经超过 1s ,在挂载完成时取消 loading

    clearInterval(loading) // 假设 1s 内已经挂载完成,取消 loading
    ```
    leonPuck
        43
    leonPuck  
       2022-12-14 18:10:52 +08:00
    如果用了 RxJS , 也可以实现,https://juejin.cn/post/7176943529057321017
    raolight
        44
    raolight  
       2022-12-14 18:20:09 +08:00
    不就普通的延时 Loading 么?

    都是差不多的思路,一般是设置延迟 2~3 秒显示 Loading ,如果期间数据还没加载完,那就继续显示 Loading ;

    如果 2~3 秒内已经加载完了,就取消 Loading
    Ketteiron
        45
    Ketteiron  
       2022-12-14 19:26:40 +08:00
    js 文件本身的加载时间是未知的,所以任何 js 层面的处理都达不到你想要的效果。如果这个误差你能接受,那随便挑一个方法都行。
    grewer
        46
    grewer  
       2022-12-14 19:32:04 +08:00
    关键词: setTimeout
    Actrace
        47
    Actrace  
       2022-12-14 19:43:24 +08:00
    试试用 tmpUI 做真加载进度
    https://github.com/tmplink/tmpUI
    thulof
        48
    thulof  
       2022-12-14 19:47:40 +08:00
    特意登陆来回复你一下:
    把 Loading 写在 HTML 模版中,页面开始加载时 setTimeout 计时一秒开始展示 Loading DOM
    在 Vue 的初始化逻辑中加载完成时 remove 掉 Loading DOM 即可
    gengliangcais
        49
    gengliangcais  
       2022-12-15 11:39:00 +08:00
    /** 秒级响应不再显示 loading 弹窗 */
    const delay = 1000
    let timeoutId = setTimeout(() => {
    if (loading) {
    timeoutId = 0;
    //
    showLoading()
    }
    }, delay);

    // 响应里面
    if(timeoutId==0){
    closeLoading()
    }
    dafuyang
        50
    dafuyang  
    OP
       2022-12-21 21:14:04 +08:00
    @darkengine
    @yfugibr
    @ragnaroks
    @kealm
    @dreamn
    @flyingghost
    @rrZ2C
    @YouTing
    @296727
    @sanmaozhao
    @sanmaozhao
    @raolight
    @grewer
    @thulof
    兄弟们,感谢大家的意见!!!这段时间梯子挂了,上不来。。综合试了一下,js settimeout 或者是动画延迟执行在加上渐变过渡都可以满足俺的需求,再次谢谢各位!!
    lynan
        51
    lynan  
       2022-12-27 18:46:44 +08:00
    @darknoll 把 loading 写在 #app 里,vue 初始化以后会替换 #app 的节点内容
    humbass
        52
    humbass  
       2023-01-14 00:05:49 +08:00
    本质上应该有 4 个状态:

    0 - 未知状态 - 按楼主的意思相当于是白屏,或者显示骨架页内容
    1 - 有缓存数据,准备加载数据
    2 - 没有缓存,显示 loading
    3 - 数据已装载

    1 和 3 合并也可以

    不关 setTimeout 什么事,如果要用到 延时,说明只写了两个状态
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2511 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 15:31 PVG 23:31 LAX 08:31 JFK 11:31
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86