浅谈前端实现页面加载进度条以及 nprogress.js 的实现
以前在 Vue 的項目用了 nprogress 這個插件,一直對于其如何得知加載進度充滿好奇,最近又看到了「前端如何實現頁面加載進度條」這個問題,今天周六恰好一探究竟。以下僅為一家之言,如有異議,歡迎指出。
前端的頁面加載進度條有兩種
首先不得不說,前端的頁面加載進度條其實有兩種,所以你得先搞清楚說的是哪一種。
第一種,進度條顯示的是 前端靜態資源 的加載。比如你打開一個頁面,頁面需要加載 js、css、img 等靜態資源,那么每加載完一個資源(監聽 onload 事件或者類似事件),進度條就向前滾動一下,直到加載完所有,進度條到頭。
實際操作中,如果不做前置靜態資源配置,基本不可能實現,因為你很難在代碼中獲取頁面加載所需要的 js、css、img 資源,假設可以獲取,還需要監聽它們的 onload 事件,即使能實現這個進度條,也是一件 性價比很低 的事情,除非一個情況。
沒錯,這個特殊情況就是 游戲資源的加載。我們在寫游戲的時候,通常需要把靜態資源項目都列出來到配置中,而且,這個資源請求,一般比較耗時,這個時候,我們就需要這樣一個進度條,因為前置條件也已經滿足(資源已經列出),而如果只是寫一個普通的頁面,我們一般不會手動去列出靜態資源。(具體實現我沒有研究過,實際可能更加復雜,詳見 這個回答)
第二種情況,也是我們現在通常說的進度條加載,舉個簡單的例子,GitHub 中就有用到。先打開我的 GitHub 主頁 https://github.com/hanzichi,然后點擊 tab 中的 Stars 標簽,這個時候 url 會變成 https://github.com/hanzichi?tab=stars,進度條開始加載,當頁面內容切換過去的時候,進度條結束。
以上實現,其實就是 pjax 的實現,忽略掉 "p" 的部分,其實就是一個普通的 ajax。當頁面發起 ajax 請求的時候,顯示進度條,ajax 結束的時候,進度條到頭,從而實現整個頁面加載。這種情況,其實通常都會搭檔 SPA 出現。
NProgress
以上第二種情況,業界有個成熟的插件 NProgress。它的 API 非常簡單,NProgress.start() 表示進度條開始,NProgress.done() 表示進度條結束。
如果搭配 pjax,可以這樣用:
$(document).on('pjax:start', function() { NProgress.start(); }); $(document).on('pjax:end', function() { NProgress.done(); });在 Vue 中,可以這樣用:
router.beforeEach((to, from, next) => {NProgress.start()next() })router.afterEach(() => {NProgress.done() // 結束 Progress })甚至,普通的頁面中也可以用,頁面開始的時候 NProgress.start(),window.onload 的回調中運行 NProgress.done()
NProgress.start() 和 NProgress.done() 過程中,進度條會不斷加載,時快時慢,這個速度的控制,依賴的是什么?答案是,進度條的進度其實是假的,進度是 NProgress 自己在代碼中控制的。
我們可以看下 源碼,調用 NProgress.start 后,會持續調用 NProgress.inc 方法,我們看下這個方法實現:
NProgress.inc = function(amount) {var n = NProgress.status;if (!n) {return NProgress.start();} else if(n > 1) {return;} else {if (typeof amount !== 'number') {if (n >= 0 && n < 0.2) { amount = 0.1; }else if (n >= 0.2 && n < 0.5) { amount = 0.04; }else if (n >= 0.5 && n < 0.8) { amount = 0.02; }else if (n >= 0.8 && n < 0.99) { amount = 0.005; }else { amount = 0; }}n = clamp(n + amount, 0, 0.994);return NProgress.set(n);} };代碼中的 amount 就是進度條增量(0 為進度條起始值,1 為進度條終止值),可以從數值上判斷,進度條增長速度是越來越慢。當進度條增長到 99.4% 的時候,就停止了,直到調用 NProgress.done() 方法。
其實,某些場景,想獲取真實進度也是可以的,xhr2 其實是可以獲取進度的,用 ajax 上傳文件就可以持續獲取進度進行展示,本文就不展開討論了。
本文的結論是,絕大多數情況下看到的前端頁面進度條展示,都是假的,只是特效 ...
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的浅谈前端实现页面加载进度条以及 nprogress.js 的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一个“小白”眼中的容器
- 下一篇: HTML_盒子模型