欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript前端靜態(tài)資源預(yù)加載實(shí)現(xiàn)示例

 更新時(shí)間:2022年11月09日 08:41:33   作者:逆光如雪  
這篇文章主要為大家介紹了JavaScript前端靜態(tài)資源預(yù)加載實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

為什么要靜態(tài)資源預(yù)加載?

靜態(tài)資源文件主要指的就是圖片,我們?cè)陧?xiàng)目中用到最多的靜態(tài)資源文件也是圖片。但是圖片作為一種可替換元素,在使用時(shí)有很多的問(wèn)題。

在了解圖片問(wèn)題之前,先看看發(fā)生在我身上的真實(shí)小故事,幫助大家更好的理解。

在一個(gè)陽(yáng)光明媚的清晨,你因?yàn)楦鞣N原因出門(mén)晚了。你一路飛奔找到最近的小藍(lán)車(chē),途中完成wifi切換流量、打開(kāi)支付寶、點(diǎn)擊哈羅等操作??粗M(jìn)入小程序的loading,你知道今天又能擠上地鐵,嘴角不禁微微上揚(yáng)。

在loading消失的最后一秒你也剛好氣喘吁吁的跑到了小藍(lán)車(chē)面前,迫不及待的點(diǎn)擊"掃一掃"三個(gè)大字...

就在你手指將要觸碰到屏幕的那一瞬間,頁(yè)面突然一閃,原來(lái)掃一掃的位置變成了去購(gòu)買(mǎi)。下一秒頁(yè)面不出意外的跳轉(zhuǎn)到了優(yōu)惠活動(dòng)頁(yè),重新開(kāi)始了loading...

待你點(diǎn)擊返回掃開(kāi)小藍(lán),紅綠燈已經(jīng)由黃轉(zhuǎn)紅,今天鐵定是遲到了...

相信每天踩著最后一秒打卡的朋友一定很理解我的心路歷程??????。

封面的動(dòng)圖就是那個(gè)頁(yè)面的變動(dòng)過(guò)程,這個(gè)動(dòng)圖也很好的說(shuō)明了圖片在前端渲染時(shí)出現(xiàn)的問(wèn)題。

圖片在使用時(shí)的問(wèn)題

文件大小要大于文字,在網(wǎng)絡(luò)中傳輸慢。

故事中同一個(gè)接口的去購(gòu)買(mǎi)文字已經(jīng)展示出來(lái),但是banner圖還沒(méi)渲染出來(lái)。

影響用戶體驗(yàn)

故事中打開(kāi)頁(yè)面后原本是banner圖的位置有一大塊空白,這對(duì)于用戶體驗(yàn)來(lái)說(shuō)不夠好。

試想如果一個(gè)頁(yè)面中大大小小的圖片有很多,在加載時(shí)都是這樣的空白會(huì)是什么體驗(yàn)?

或者當(dāng)你點(diǎn)擊了跳轉(zhuǎn)或者打開(kāi)一個(gè)內(nèi)容時(shí),內(nèi)容中的圖片位置總是先顯示空白會(huì)是什么體驗(yàn)?

影響Dom結(jié)構(gòu)

故事中頁(yè)面之所以會(huì)發(fā)生抖動(dòng)和閃爍,是因?yàn)閐om結(jié)構(gòu)發(fā)生了變化。故事中dom結(jié)構(gòu)變化的原因可能是因?yàn)閮?yōu)惠接口返回慢而導(dǎo)致的,但是圖片的加載和渲染也能出現(xiàn)類似的場(chǎng)景。進(jìn)而導(dǎo)致用戶的行為因?yàn)轫?yè)面dom的變動(dòng)而發(fā)生錯(cuò)誤。

圖片會(huì)裂開(kāi)

將圖片作為背景圖片時(shí),加載失敗頂多導(dǎo)致背景空白。但是直接使用image標(biāo)簽如果圖片加載失敗就會(huì)有一個(gè)裂開(kāi)的圖片展示到頁(yè)面上,這種場(chǎng)景相信大家都見(jiàn)到過(guò)。

解決辦法

  • 可以將圖片壓縮到盡可能小,這樣可以大幅提高傳輸和加載的速度;
  • 使用背景圖片代替image標(biāo)簽;
  • 可以嘗試將小圖標(biāo)整合成精靈圖雪碧圖;
  • 針對(duì)dom結(jié)構(gòu)變動(dòng),可以參考哈羅在圖片外層設(shè)置一個(gè)差不多高度的div預(yù)先給圖片留個(gè)位置;

無(wú)法解決的場(chǎng)景

以上的解決方法都適用于所用到的圖片比較小,或者比較少的情況下。當(dāng)圖片本身比較大時(shí)即使經(jīng)過(guò)壓縮還是很大,也不方便做成精靈圖。當(dāng)一個(gè)項(xiàng)目擁有很多圖片,用戶在不同項(xiàng)目的子路由間跳轉(zhuǎn)或者通過(guò)交互觸發(fā)頁(yè)面上大量圖片更新時(shí),上面的方法就不是很適用了。

什么是靜態(tài)資源預(yù)加載?

靜態(tài)資源預(yù)加載的原理是利用瀏覽器的緩存機(jī)制配合img的onload事件,將漫長(zhǎng)的圖片的加載過(guò)程放在真正進(jìn)入頁(yè)面之前,進(jìn)入頁(yè)面后所有用到的圖片都會(huì)直接從內(nèi)存讀取。

也就是說(shuō)要將頁(yè)面的初始化接口在進(jìn)入頁(yè)面之前調(diào)用,從而獲取要加載的圖片鏈接。

靜態(tài)資源預(yù)加載的優(yōu)點(diǎn)和缺點(diǎn)

優(yōu)點(diǎn)

  • 用戶進(jìn)入頁(yè)面后一瞬間就可以看到整個(gè)頁(yè)面而不會(huì)出現(xiàn)白屏;
  • 用戶在切換tab或者是跳轉(zhuǎn)到子路由頁(yè)面時(shí)不會(huì)因?yàn)榧虞d圖片而出現(xiàn)頁(yè)面的卡頓;
  • 不會(huì)出現(xiàn)圖片由空白從上至下一點(diǎn)點(diǎn)的向下渲染的過(guò)程;
  • 不會(huì)出現(xiàn)因?yàn)閳D片沒(méi)及時(shí)加載出來(lái)而導(dǎo)致的dom結(jié)構(gòu)崩亂,造成頁(yè)面閃爍;

缺點(diǎn)

  • 漫長(zhǎng)的圖片加載放到進(jìn)入頁(yè)面之前會(huì)讓用戶的等待時(shí)間變長(zhǎng);
  • 過(guò)長(zhǎng)的等待時(shí)間可能會(huì)導(dǎo)致轉(zhuǎn)化率的下降;

缺點(diǎn)的處理

為了應(yīng)對(duì)這個(gè)缺陷,在做靜態(tài)資源預(yù)加載處理進(jìn)入頁(yè)面之前,我們通常都會(huì)搭配一個(gè)可以顯示進(jìn)度的loading。這樣可以讓用戶實(shí)時(shí)獲取到加載進(jìn)度,而不是無(wú)謂的等待。這樣一定程度上可以增加用戶停留在當(dāng)前頁(yè)面的時(shí)間,從而進(jìn)入到下個(gè)頁(yè)面。

靜態(tài)資源預(yù)加載的實(shí)現(xiàn)

通過(guò)遞歸的方式在每一張圖片onload成功之后開(kāi)始加載下一個(gè)圖片,直到圖片全部都加載完成。

import isFunction from 'lodash/isFunction';
    /**
     * 圖片資源預(yù)加載
     * @param {Array} urlArr 圖片鏈接數(shù)組
     * @param {number} index 當(dāng)前加載的是第幾張圖片
     * @param {function} imgLoadFn 單張圖片加載成功的回調(diào)
     * @param {function} successFn 成功失敗回調(diào)函數(shù)
     * @param {function} errorFn 加載失敗回調(diào)函數(shù)
     */
    imgLoader(urlArr, index, imgLoadFn, successFn, errorFn) {
        if (index === urlArr.length && !urlArr[ index ]) return;
        downloadPic(...arguments);
    }
    //  加載單張圖片
    downloadPic(urlArr, index, imgLoadFn, successFn, errorFn) {
        console.log('開(kāi)始加載第', index, '張圖')
        const img = document.createElement('img');
        img.src = urlArr[ index ];
        img.onload = () => {
            // 這里每一個(gè)圖片加載完成時(shí)傳入的應(yīng)該是index+1,因?yàn)閕ndex是從0開(kāi)始的,而這里表示的是第幾張圖片完成加載的回調(diào),傳入數(shù)組長(zhǎng)度用于計(jì)算百分比
            isFunction(imgLoadFn) && imgLoadFn(index + 1, urlArr.length);
            if (index === urlArr.length - 1) {
                // 加載完最后一張時(shí)調(diào)用全部完成函數(shù)
                successFn(index);
            } else {
               //  否則開(kāi)啟下一張圖片的加載
                index += 1;
                downloadPic(urlArr, index, imgLoadFn, successFn, errorFn);
            }
        };
        img.onError = errorFn ? () => {
            isFunction(errorFn) && errorFn({
                index,
                url: urlArr[ index ]
            })
        } : () => imgLoaderError(index);
    }
    /**
     * 圖片加載失敗
     * @param {number} index 數(shù)組下標(biāo)
     */
    imgLoaderError(index) {
        console.error(`第${ index }張圖片加載失敗`);
    }

靜態(tài)資源預(yù)加載的調(diào)用

// 定義好對(duì)應(yīng)的處理函數(shù)
const imgLoadFn = (current, total) => {
    // 用百分比來(lái)顯示當(dāng)前的加載進(jìn)度顯示在頁(yè)面loading中
    this.percent = parseInt(current / total * 100) + '%';
}
const successFn = () => {
    this.percent = '100%';
    this.showLoading = false;  // 關(guān)閉loading
    console.log('圖片已全部預(yù)加載完成,可以跳轉(zhuǎn)到對(duì)應(yīng)頁(yè)面')
}
const errorFn = () => {
    console.log('加載資源錯(cuò)誤');
}
//  調(diào)用
imgLoader(urlArr, 0, imgLoadFn, successFn, errorFn);

靜態(tài)資源預(yù)加載的應(yīng)用場(chǎng)景

靜態(tài)資源預(yù)加載常用于各種活動(dòng)頁(yè)面,例如雙11、618、818、年度賬單、周年活動(dòng)等。

為了讓用戶在進(jìn)入活動(dòng)頁(yè)之后的交互更流暢,通常會(huì)在進(jìn)入頁(yè)面前使用靜態(tài)資源加載將所需的資源文件都加載到緩存中。

所以,這也是我們?cè)谶M(jìn)入這些頁(yè)面之前經(jīng)??梢钥吹揭粋€(gè)加載進(jìn)度loading的原因。關(guān)于如何實(shí)現(xiàn)一個(gè)帶進(jìn)度的loading,可以看我的這篇文章。

使用svg實(shí)現(xiàn)簡(jiǎn)單帶進(jìn)度的loading

以上就是JavaScript前端靜態(tài)資源預(yù)加載實(shí)現(xiàn)示例的詳細(xì)內(nèi)容,更多關(guān)于JavaScript前端靜態(tài)資源預(yù)加載的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論