如何實現圖片預載入和載入進度條

艾碼的日常生活發表於2023-09-24

很久沒有發文了今天水一篇文章,圖片預載入且展示載入的進度條,在現代的Web開發中,最佳化使用者體驗至關重要。一種常見的方法是在頁面載入時預載入圖片,並展示一個載入進度條,讓使用者瞭解載入進度。在本文中,我們將深入探討如何實現這兩個關鍵功能,以提高網站效能和使用者滿意度,首先談一下我的思路:

建立一個函式用於new一個image物件,遍歷需要預載入的圖片陣列,設定圖片的src屬性為傳入的 URL,從而觸發圖片的載入,在每個圖片載入成功後,用陣列長度計算出百分比更新載入進度並將載入的圖片新增到頁面上,其中的我有一個我踩的坑需要注意一下

 

/**
 * 圖片預載入
 */
export function preloadImage(url) {
    console.log(url)
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.src = url;

    img.onload = () => {
      resolve(img);
    };

    img.onerror = (err) => {
      reject(err);
    };
  });
}

建立了一個 preloadImage 函式,它用於載入給定 URL 的影像。該函式返回一個 Promise,使非同步處理圖圖片載入的成功或失敗。

        data() {
            return {
                loadingProgress: 0, // 圖片載入進度
            };
        },
        methods: {
            // 預載入
            async preloadImages() {
                const imageUrls = [
                    require('../../static/index/hone-rainbow.png'),
                    require('../../static/index/hone-bg.png'),
//...你的圖片
                ];
                const totalImages = imageUrls.length;
                let loadedImages = 0;

                for (const imageUrl of imageUrls) {
                    try {
                        await preloadImage(imageUrl);
                        loadedImages++;
                        this.loadingProgress = (loadedImages / totalImages) * 100; // 更新進度
                    } catch (error) {
                        console.error(error);
                    }
                }
                // 判斷是否首次訪問,開啟新手指引
                this.$nextTick(() => {
                    this.access()
                });
            },
                    },

在 preloadImages 函式中,定義一個陣列 imageUrls,其中包含所有需要預載入的 URL。然後,透過遍歷這個陣列,使用 preloadImage 函式來預載入每個影像。在每個影像載入成功後,更新載入進度並將載入的影像新增到頁面上,在頁面中我使用了載入進度條來展示載入進度。進度條的百分比由 this.loadingProgress 控制,它在每個圖片成功載入後被更新。透過監聽 loadingProgress 的變化可以實時更新進度條,還有就是根據需要透過 try-catch 捕獲可能的載入錯誤,在this.$nextTick中進行載入完成後需要進行的操作,確保是在進度條完成後正常執行

    <!-- 預載入頁面 -->
    <view v-if="loadingProgress!==100" class="loading-main">
        <view class="loading-line-progress-box">
            <view class="loading-line-progress">
                <u-line-progress width="100" height="20" :percentage="loadingProgress" activeColor="#f9a431">
                    <text class="loading-u-percentage-slot">{{(loadingProgress || 0).toFixed(2)}}%</text>
                    <image v-if="loadingProgress!==0" class="loading-line-progress-logo"
                        src="@/static/index/line-progress-logo.png" mode=""></image>
                </u-line-progress>
            </view>
        </view>
    </view>
    <!-- 主頁面 -->
    <view v-else class="content-main">
//載入完成後的頁面
    </view>

html的話我這邊使用的是uview的進度條元件,這裡可以根據自己專案的需要進行調整,當圖片載入完畢loadingProgress為一百時進度條頁面消失展示主頁

接下來記錄一下我做這個功能踩的坑

const imageUrls = [
                    '../../static/index/hone-rainbow.png',
                    '../../static/index/hone-bg.png',
                ];

剛開始時我是直接寫圖片的相對路徑,預載入出來的圖片當然就是相對路徑了,可是圖片經過uniapp編譯後不僅路徑進行了改變,且會新增hash字尾防重名,如此一來之前預載入的圖片當進入頁面時肯定是用不了的瀏覽器會重新載入一次圖片,這裡就有兩個方法解決,第一將圖片放伺服器中進行預載入同時可以減少前端打包的體積,第二種就是就是透過require包裹始終獲取圖片的真實路徑,我這邊專案體積並沒有很大所以採用了第二種方法始終獲取圖片的真實路徑,webpack構建工具負責將這些引用路徑解析為真實的檔案路徑,因此可以專注於編寫相對路徑,不必擔心最終的部署路徑。

相關文章