用 LQIP 讓圖片載入不再跳來跳去

·lqip圖片優化前端uxvue
AI 摘要
AI · GEN

LQIP(Low Quality Image Placeholder)透過在上傳時預先產生 base64 模糊圖與 thumbnail,讓前台在圖片載入的每個階段都有東西可以顯示:進場先顯示 blurDataUrl、thumbnail 載入後替換、點擊開啟 Lightbox 時再從 thumbnail 過渡到原圖。整個過程沒有空白畫面,也不會有版面跳動。

瀏覽有大量圖片的網頁時,應該都遇過這種情況:圖片還沒載入完成,畫面就一直跳動,文字被推來推去,或是圖片從上到下一條一條慢慢出現。這些體驗都不太好,尤其在網速較慢的環境下會更明顯。

LQIP(Low Quality Image Placeholder)是一種常見的圖片載入優化技術,核心概念很簡單:在原始圖片還沒下載完成之前,先用一張極小的低畫質圖片當作佔位,等實際要顯示的圖載入完成後再替換上去。

為什麼需要 LQIP?

如果只是把 <img> 丟上去什麼都不處理,會遇到兩個問題:

  1. 版面跳動(Layout Shift):圖片載入前沒有預留空間,載入後把其他內容擠開,造成 CLS(Cumulative Layout Shift)分數變差
  2. 載入體驗差:圖片從空白到完整顯示的過程中,要嘛是一片空白,要嘛是一條一條慢慢出現,使用者會覺得頁面還在「壞掉」的狀態

LQIP 同時解決了這兩個問題:透過預先知道圖片的寬高比來預留空間,再用一張模糊的縮圖做視覺過渡,整個載入過程會流暢很多。

我的做法

我在自己的照片牆專案 被光保存的瞬間 中實作了這個技術。這個專案會一次顯示大量照片,每張照片又有高解析度的原圖,很適合拿來做這種優化。

整體流程分成三個階段:上傳時預處理照片牆渲染Lightbox 原圖載入

上傳時預處理

在圖片上傳到後端時,我會做三件事:

  1. 記錄原圖的寬高:用來計算 aspect ratio,讓前台在任何圖片載入前就能預留正確的空間
  2. 產生 blurDataUrl:把圖片壓縮成極小尺寸(寬度大概 20~32px),轉成 base64 字串直接存進資料庫
  3. 產生 thumbnail:壓縮成適合在照片牆上瀏覽的中等尺寸縮圖,上傳到儲存空間
// 概念上的處理流程
const metadata = await sharp(imageBuffer).metadata()
const { width, height } = metadata
// 產生 base64 模糊圖
const blurBuffer = await sharp(imageBuffer)
.resize(32)
.blur(1)
.toBuffer()
const blurDataUrl = `data:image/jpeg;base64,${blurBuffer.toString('base64')}`
// 產生 thumbnail
const thumbnailBuffer = await sharp(imageBuffer)
.resize(480)
.toBuffer()
// 儲存:原圖 URL、thumbnail URL、blurDataUrl、寬高

blurDataUrl 是 base64,可以直接跟著 API 回應一起回來,不需要額外的 HTTP 請求。一張 32px 寬的模糊圖通常只有幾百 bytes,對回應大小幾乎沒有影響。

照片牆渲染:blurDataUrl → thumbnail

頁面載入後,每張照片的載入會經過兩個階段:

  1. 立即顯示 blurDataUrl:因為是 base64,不需要任何網路請求,頁面一渲染就能看到模糊的佔位圖,同時 aspect ratio 也已經是正確的
  2. thumbnail 載入完成後替換:瀏覽器在背景下載 thumbnail,下載完成後替換掉模糊圖
<template>
<div
class="image-wrapper"
:style="{ aspectRatio: `${image.width} / ${image.height}` }"
@click="openLightbox(image)"
>
<!-- 底層:blurDataUrl 作為佔位 -->
<img :src="image.blurDataUrl" class="blur-placeholder" />
<!-- 上層:thumbnail 載入完成後顯示 -->
<img
:src="image.thumbnailUrl"
:class="{ loaded: thumbnailLoaded }"
class="thumbnail"
@load="thumbnailLoaded = true"
/>
</div>
</template>
.image-wrapper {
position: relative;
overflow: hidden;
cursor: pointer;
}
.blur-placeholder,
.thumbnail {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
.thumbnail {
opacity: 0;
transition: opacity 0.3s ease;
}
.thumbnail.loaded {
opacity: 1;
}

使用者看到的效果是:頁面一打開,所有照片的位置就已經排好,每張都是模糊但有輪廓的樣子。接著 thumbnail 陸續載入完成,一張一張從模糊變清晰,整個過程很順暢,沒有版面跳動。

Lightbox 原圖載入:thumbnail → 原圖

使用者在照片牆上點擊某張照片後,會打開 Lightbox 來查看原始解析度的大圖。這時候又是一次從小圖到大圖的載入過程,一樣可以套用同樣的策略:

  1. 先顯示 thumbnail:因為 thumbnail 已經在照片牆階段載入過了,瀏覽器有快取,可以瞬間顯示
  2. 原圖載入完成後替換:高解析度原圖下載完成後,替換掉 thumbnail
<!-- Lightbox -->
<div class="lightbox" v-if="currentImage">
<img :src="currentImage.thumbnailUrl" class="lightbox-placeholder" />
<img
:src="currentImage.originalUrl"
:class="{ loaded: originalLoaded }"
class="lightbox-original"
@load="originalLoaded = true"
/>
</div>

因為 Lightbox 中的 thumbnail 已經被快取過,使用者點開後會先看到一張稍微模糊但完整的圖,而不是一片空白等原圖慢慢載入。原圖載入完成後再無縫切換成高解析度版本。

三層載入的完整流程

整理一下使用者實際看到的體驗:

階段 顯示內容 來源 等待時間
頁面載入 模糊佔位圖 blurDataUrl(base64) 無,瞬間顯示
thumbnail 載入完成 清晰縮圖 thumbnail URL 視網速而定
點擊照片,原圖載入完成 高解析度原圖 原圖 URL 視網速與圖片大小而定

每一層都不會出現空白或版面跳動,使用者在任何時刻都能看到「有東西」的畫面。

小結

LQIP 的實作不複雜,核心就是讓每個階段都有東西可以顯示:

  1. 上傳時:記錄寬高、產生 base64 模糊圖(blurDataUrl)、產生 thumbnail
  2. 照片牆:先顯示 blurDataUrl,thumbnail 載入後替換
  3. Lightbox:先顯示已快取的 thumbnail,原圖載入後替換

在圖片量大或原圖解析度高的場景下,這種分層載入的效果會特別明顯。與其讓使用者盯著空白方塊等圖片慢慢冒出來,不如在每個階段都給他一個「夠用」的畫面。

留言

登入後即可留言

以 Google 登入

還沒有留言,成為第一個留言的人吧!

相關文章

用 Slidev 把 Markdown 變成簡報網站

用 Slidev 把 Markdown 變成簡報網站,從建立專案、自訂樣式到部署上線的完整流程與踩坑紀錄。

2026年4月1日·Programming

把模糊想法變成可執行工作:我的 Supekku Workflow 設計

AI Agent 協作的問題不只是 prompt,而是脈絡如何被保存。Supekku Workflow 是我用來把模糊想法整理成可執行工作的方式:先透過對話釐清意圖、範圍與成功標準,再把需要保存的內容轉成 proposal、criteria、reasoning、actions 與 verification。

2026年5月28日·AI

AI 時代的個人知識庫:Obsidian、RAG 與 Agent 該怎麼分工?

Obsidian、RAG 與 AI Agent 常被放在一起討論,但它們其實負責不同任務。本文從個人知識管理的角度,拆解 Obsidian 如何保存筆記、RAG 如何檢索資料、Agent 如何把內容轉成可執行的工作流。

2026年5月1日·Obsidian

如何自訂 Kobo 電子書閱讀器的待機畫面

告別單調的預設書封!只要簡單幾步驟,就能把喜歡的圖片變成 Kobo 閱讀器的待機桌布。本文提供各機型解析度對照表與 Mac/Windows 顯示隱藏資料夾教學,讓你每次合上閱讀器都能看到最愛的風景。

2023年2月19日·Kobo

如何在 Kobo 電子書閱讀器安裝自訂字型

身為 Kobo 使用者,一定要學會的自訂字型小技巧!內建字型看膩了?跟著這份筆記,把帶有手寫筆觸的「芫荽」字型裝進閱讀器裡。簡單、免費且不傷效能,讓你的每一本電子書都像精心排版過的實體書一樣順眼。

2023年2月20日·Kobo