JavaScript前端靜態(tài)資源預加載實現(xiàn)示例
為什么要靜態(tài)資源預加載?
靜態(tài)資源文件主要指的就是圖片,我們在項目中用到最多的靜態(tài)資源文件也是圖片。但是圖片作為一種可替換元素,在使用時有很多的問題。
在了解圖片問題之前,先看看發(fā)生在我身上的真實小故事,幫助大家更好的理解。
在一個陽光明媚的清晨,你因為各種原因出門晚了。你一路飛奔找到最近的小藍車,途中完成wifi切換流量、打開支付寶、點擊哈羅等操作。看著進入小程序的loading,你知道今天又能擠上地鐵,嘴角不禁微微上揚。
在loading消失的最后一秒你也剛好氣喘吁吁的跑到了小藍車面前,迫不及待的點擊"掃一掃"三個大字...
就在你手指將要觸碰到屏幕的那一瞬間,頁面突然一閃,原來掃一掃的位置變成了去購買。下一秒頁面不出意外的跳轉到了優(yōu)惠活動頁,重新開始了loading...
待你點擊返回掃開小藍,紅綠燈已經由黃轉紅,今天鐵定是遲到了...
相信每天踩著最后一秒打卡的朋友一定很理解我的心路歷程??????。
封面的動圖就是那個頁面的變動過程,這個動圖也很好的說明了圖片在前端渲染時出現(xiàn)的問題。
圖片在使用時的問題
文件大小要大于文字,在網絡中傳輸慢。
故事中同一個接口的去購買文字已經展示出來,但是banner圖還沒渲染出來。
影響用戶體驗
故事中打開頁面后原本是banner圖的位置有一大塊空白,這對于用戶體驗來說不夠好。
試想如果一個頁面中大大小小的圖片有很多,在加載時都是這樣的空白會是什么體驗?
或者當你點擊了跳轉或者打開一個內容時,內容中的圖片位置總是先顯示空白會是什么體驗?
影響Dom結構
故事中頁面之所以會發(fā)生抖動和閃爍,是因為dom結構發(fā)生了變化。故事中dom結構變化的原因可能是因為優(yōu)惠接口返回慢而導致的,但是圖片的加載和渲染也能出現(xiàn)類似的場景。進而導致用戶的行為因為頁面dom的變動而發(fā)生錯誤。
圖片會裂開
將圖片作為背景圖片時,加載失敗頂多導致背景空白。但是直接使用image標簽如果圖片加載失敗就會有一個裂開的圖片展示到頁面上,這種場景相信大家都見到過。
解決辦法
- 可以將圖片壓縮到盡可能小,這樣可以大幅提高傳輸和加載的速度;
- 使用背景圖片代替image標簽;
- 可以嘗試將小圖標整合成精靈圖雪碧圖;
- 針對dom結構變動,可以參考哈羅在圖片外層設置一個差不多高度的div預先給圖片留個位置;
無法解決的場景
以上的解決方法都適用于所用到的圖片比較小,或者比較少的情況下。當圖片本身比較大時即使經過壓縮還是很大,也不方便做成精靈圖。當一個項目擁有很多圖片,用戶在不同項目的子路由間跳轉或者通過交互觸發(fā)頁面上大量圖片更新時,上面的方法就不是很適用了。
什么是靜態(tài)資源預加載?
靜態(tài)資源預加載的原理是利用瀏覽器的緩存機制配合img的onload事件,將漫長的圖片的加載過程放在真正進入頁面之前,進入頁面后所有用到的圖片都會直接從內存讀取。
也就是說要將頁面的初始化接口在進入頁面之前調用,從而獲取要加載的圖片鏈接。
靜態(tài)資源預加載的優(yōu)點和缺點
優(yōu)點
- 用戶進入頁面后一瞬間就可以看到整個頁面而不會出現(xiàn)白屏;
- 用戶在
切換tab或者是跳轉到子路由頁面時不會因為加載圖片而出現(xiàn)頁面的卡頓; - 不會出現(xiàn)圖片由空白從上至下一點點的向下渲染的過程;
- 不會出現(xiàn)因為圖片沒及時加載出來而導致的dom結構崩亂,造成頁面閃爍;
缺點
- 漫長的圖片加載放到進入頁面之前會讓用戶的等待時間變長;
- 過長的等待時間可能會導致轉化率的下降;
缺點的處理
為了應對這個缺陷,在做靜態(tài)資源預加載處理進入頁面之前,我們通常都會搭配一個可以顯示進度的loading。這樣可以讓用戶實時獲取到加載進度,而不是無謂的等待。這樣一定程度上可以增加用戶停留在當前頁面的時間,從而進入到下個頁面。
靜態(tài)資源預加載的實現(xiàn)
通過遞歸的方式在每一張圖片onload成功之后開始加載下一個圖片,直到圖片全部都加載完成。
import isFunction from 'lodash/isFunction';
/**
* 圖片資源預加載
* @param {Array} urlArr 圖片鏈接數組
* @param {number} index 當前加載的是第幾張圖片
* @param {function} imgLoadFn 單張圖片加載成功的回調
* @param {function} successFn 成功失敗回調函數
* @param {function} errorFn 加載失敗回調函數
*/
imgLoader(urlArr, index, imgLoadFn, successFn, errorFn) {
if (index === urlArr.length && !urlArr[ index ]) return;
downloadPic(...arguments);
}
// 加載單張圖片
downloadPic(urlArr, index, imgLoadFn, successFn, errorFn) {
console.log('開始加載第', index, '張圖')
const img = document.createElement('img');
img.src = urlArr[ index ];
img.onload = () => {
// 這里每一個圖片加載完成時傳入的應該是index+1,因為index是從0開始的,而這里表示的是第幾張圖片完成加載的回調,傳入數組長度用于計算百分比
isFunction(imgLoadFn) && imgLoadFn(index + 1, urlArr.length);
if (index === urlArr.length - 1) {
// 加載完最后一張時調用全部完成函數
successFn(index);
} else {
// 否則開啟下一張圖片的加載
index += 1;
downloadPic(urlArr, index, imgLoadFn, successFn, errorFn);
}
};
img.onError = errorFn ? () => {
isFunction(errorFn) && errorFn({
index,
url: urlArr[ index ]
})
} : () => imgLoaderError(index);
}
/**
* 圖片加載失敗
* @param {number} index 數組下標
*/
imgLoaderError(index) {
console.error(`第${ index }張圖片加載失敗`);
}
靜態(tài)資源預加載的調用
// 定義好對應的處理函數
const imgLoadFn = (current, total) => {
// 用百分比來顯示當前的加載進度顯示在頁面loading中
this.percent = parseInt(current / total * 100) + '%';
}
const successFn = () => {
this.percent = '100%';
this.showLoading = false; // 關閉loading
console.log('圖片已全部預加載完成,可以跳轉到對應頁面')
}
const errorFn = () => {
console.log('加載資源錯誤');
}
// 調用
imgLoader(urlArr, 0, imgLoadFn, successFn, errorFn);
靜態(tài)資源預加載的應用場景
靜態(tài)資源預加載常用于各種活動頁面,例如雙11、618、818、年度賬單、周年活動等。
為了讓用戶在進入活動頁之后的交互更流暢,通常會在進入頁面前使用靜態(tài)資源加載將所需的資源文件都加載到緩存中。
所以,這也是我們在進入這些頁面之前經??梢钥吹揭粋€加載進度loading的原因。關于如何實現(xiàn)一個帶進度的loading,可以看我的這篇文章。
以上就是JavaScript前端靜態(tài)資源預加載實現(xiàn)示例的詳細內容,更多關于JavaScript前端靜態(tài)資源預加載的資料請關注腳本之家其它相關文章!
相關文章
IE中鼠標經過option觸發(fā)mouseout的解決方法
這篇文章主要介紹了IE中鼠標經過option觸發(fā)mouseout的解決方法,分析了IE中鼠標移到option時window.event.toElement返回值為null的原因及解決方法,需要的朋友可以參考下2015-01-01
讓 JavaScript 輕松支持函數重載 (Part 2 - 實現(xiàn))
在上一篇文章里,我們設計了一套能在JavaScript中描述函數重載的方法,這套方法依賴于一個叫做Overload的靜態(tài)類,現(xiàn)在我們就來看看如何實現(xiàn)這個靜態(tài)類。2009-08-08
分別用marquee和div+js實現(xiàn)首尾相連循環(huán)滾動效果,僅3行代碼
這是本人2007年進行的一項研究,當時網絡上沒有什么既精簡又實用的循環(huán)滾動代碼,所以就自己琢磨了段時間,最終找到這個辦法2011-09-09
JS實現(xiàn)定時任務每隔N秒請求后臺setInterval定時和ajax請求問題
這篇文章主要介紹了JS實現(xiàn)定時任務每隔N秒請求后臺setInterval定時和ajax請求 的相關資料,需要的朋友可以參考下2017-10-10
Js和JQuery獲取鼠標指針坐標的實現(xiàn)代碼分享
這篇文章主要介紹了Js和JQuery獲取鼠標指針坐標的實現(xiàn)代碼分享,本文直接給出實現(xiàn)的代碼,需要的朋友可以參考下2015-05-05
JavaScript實現(xiàn)模態(tài)框拖拽效果
這篇文章主要介紹了通過JavaScript實現(xiàn)模態(tài)框拖拽的效果,以及鼠標松開,可以停止拖動模態(tài)框移動等功能,感興趣的小伙伴可以了解一下2021-12-12

