ASP.NET Core Blazor 實作圖片延遲載入
為何要使圖片延遲載入?
🔗基本上最大的原因就是效能問題,若某個頁面有 10 張圖片,使用者其實並沒辦法在操作視窗內(螢幕)一次性的看到所有的圖片,所以在頁面載入時若馬上就載入這 10 張或是更多完整的圖片,不僅使用者需要等待全部載完會非常耗時,甚至更慘的是覺得網頁怎麼卡卡的跑不動而關閉。若圖片是放在 S3 等雲端服務上,那長久累積下來資料的傳輸量花費也是很可觀的!!
實作方法
🔗圖片延遲載入其實有很多種方式,最簡單的當然就是限制圖片的載入數量,每次只載個幾張,若要觀看更多可以往下滑動或是點選載入更多按鈕。但這種方式也只是治標不治本,畢竟每次的載入張數,若太少會讓使用者覺得很麻煩,太多又達不到想要增加效能減少傳輸量的效果。
瀏覽器本身有支援延遲載入,只要透過此語法就能實現。
HTML<img src="image.jpg" loading="lazy">
但在 Blazor 框架,可能是因為所有的物件畫面都有額外一層藉由 JS 去渲染,不確定實際原理,但測試下來是無效的。
目前我選擇的方式是藉由 IntersectionObserver (由 JavaScript 實作的 API 可監測元素在窗口的狀態,也就是元素是否在視窗內),進而判斷是否要載入圖片。
代碼
🔗將此代碼複製至 index.html
的 body
中,這樣網站的每個畫面都能使用延遲載入功能。
JS<!-- lzay loading -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/intersection-observer.min.js"></script>
<script type="text/javascript">
window.lazyLoading = function () {
const observer = new IntersectionObserver((entries, owner) => {
for (let entry of entries) {
if (entry.isIntersecting) {
// 圖片進入畫面再載入真實照片
const img = entry.target;
img.setAttribute('src', img.dataset.src);
img.removeAttribute('data-src');
owner.unobserve(img);
}
}
});
const images = document.querySelectorAll('img.lazy')
for (let image of images) {
observer.observe(image);
}
}
</script>
主要就是藉由 IntersectionObserver
判斷圖片是否已進入視窗內,若進入則移除原本 src
顯示data-src
的內容。
需要有延遲載入圖片的畫面(.rezor
):
HTML@inject IJSRuntime js
<img src="@placeholderImage" data-src="@o.ImageUrl" class="lazy">
src
為圖片未載入時的顯示畫面,可以是一個低解析度的像素圖。
data-src
為實際要顯示的圖檔網址。
@code
的部分為:
C#protected override void OnAfterRender(bool firstRender)
{
if (firstRender)
{
js.InvokeVoidAsync("lazyLoading");
}
}
用來在第一次加載時載入 IntersectionObserver
。
結論
🔗實際瀏覽效果如下:
可以看到當圖片進入視窗時,會由原本預設的低解析度的像素圖,載入實際圖片達到延遲載入的效果。
Alvin
軟體工程師,喜歡金融知識、健康觀念、心理哲學、自助旅遊與系統設計。
相關文章
留言區 (0)
尚無留言