頁面性能優化-原生JS實現圖片懶載入

来源:https://www.cnblogs.com/peerless1029/archive/2019/04/25/10771695.html
-Advertisement-
Play Games

在項目開發中,我們往往會遇到一個頁面需要載入很多圖片的情況。我們可以一次性載入全部的圖片,但是考慮到用戶有可能只瀏覽部分圖片。所以我們需要對圖片載入進行優化,只載入瀏覽器視窗內的圖片,當用戶滾動時,再載入更多的圖片。這種載入圖片的方式叫做圖片懶載入,又叫做按需載入或圖片的延時載入。這樣做的好處是:1 ...


 

   在項目開發中,我們往往會遇到一個頁面需要載入很多圖片的情況。我們可以一次性載入全部的圖片,但是考慮到用戶有可能只瀏覽部分圖片。所以我們需要對圖片載入進行優化,只載入瀏覽器視窗內的圖片,當用戶滾動時,再載入更多的圖片。這種載入圖片的方式叫做圖片懶載入,又叫做按需載入或圖片的延時載入。這樣做的好處是:1.可以加快頁面首屏渲染的速度;2.節約用戶的流量。

一.實現思路

1.圖片img標簽自定義一個屬性data-src來存放真實的地址。

2.當滾動頁面時,檢查所有的img標簽,判斷是否出現在事業中,如果出現在視野中,繼續進行判斷,看齊是否被載入過了,如果沒有載入,那就進行載入。

判斷圖片元素是否處於瀏覽器視野中的示意圖(手繪):

二.根據思路完成代碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>原生js實現圖片懶載入</title>
  <style>
    *{
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    ul{
      overflow: hidden;
      list-style: none;
    }
    li{
      float: left;
      width: 50%;
      height: 200px;
      padding: 10px;
    }
    li img{
      display: inline-block;
      width: 100%;
      height: 100%;
    }
  </style>
</head>
<body>
<div class="container">
  <ul>
    <li><img src="http://cdn.jirengu.com/book.jirengu.com/img/1.jpg" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/1.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/2.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/3.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/4.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/5.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/6.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/7.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/8.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/9.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/10.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/11.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/12.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/13.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/14.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/15.jpg"></li>
    <li><img src="" alt="" data-src="http://cdn.jirengu.com/book.jirengu.com/img/16.jpg"></li>
  </ul>
</div>
<script>
  // window綁定滾動事件
  window.addEventListener('scroll',function(){
    // 遍歷所有的img標簽
    Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
      let img=li.getElementsByTagName('img')[0];
      // 判斷當前img是否出現在了視野中
      // 判斷當前img是否被載入過了
      if(checkShow(img) && !isLoaded(img)){
        loadImg(img);
      }
    })
  });

  // 判斷img是否出現瀏覽器視野中
  function checkShow(img) {
    let scrollTop=document.documentElement.scrollTop; // 頁面向上滾動的高度
    let windowHeight=window.innerHeight; //瀏覽器自身高度
    let offsetTop=img.offsetTop; //目標標簽相對於document的高度
    return (offsetTop > scrollTop && offsetTop <(windowHeight + scrollTop));
  }

  // 判斷是否已經載入過
  function isLoaded(img) {
    return img.getAttribute('src')===img.getAttribute('data-src');
  }

  // 載入圖片
  function loadImg(img) {
   img.setAttribute('src',img.getAttribute('data-src'));
  }
</script>
</body>
</html>

好了,在瀏覽器中運行一下,第一次進頁面如果不滾動滾輪的話什麼也看不到,所以第一次進頁面需要調用checkShow(),處於視野中的圖片也載入出來。

在代碼最後加上:

// 第一次進頁面載入處於視野中的圖片
 Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
    let img=li.getElementsByTagName('img')[0];
    // 判斷當前img是否出現在了視野中
    // 判斷當前img是否被載入過了
    if(checkShow(img) && !isLoaded(img)){
      loadImg(img);
    }
  })

此時我們發現判斷載入視野中的圖片代碼存在重覆,直接封裝成一個新的方法lazyRenderImg();

// window綁定滾動事件
  window.addEventListener('scroll',function(){
    // 遍歷所有的img標簽
    lazyRenderImg();
  });

function lazyRenderImg(){
 Array.prototype.slice.apply(document.getElementsByTagName('li')).forEach((li)=>{
      let img=li.getElementsByTagName('img')[0];
      // 判斷當前img是否出現在了視野中
      // 判斷當前img是否被載入過了
      if(checkShow(img) && !isLoaded(img)){
        loadImg(img);
      }
    })
  }

  // 第一次進頁面載入處於視野中的圖片
  lazyRenderImg();

 三.性能優化

問題:window.scroll 方法頁面只要一滾動就會觸發裡面的方法,對性能影響很大

解決方法:當頁面停止滾動的時候,再去執行頁面中的方法,類似與函數節流(throttle)

Tips:函數節流:等時間間隔執行函數, 讓一個函數不要執行得太頻繁,減少一些過快的調用來節流。

// window綁定滾動事件
  let timer;
  window.addEventListener('scroll',function(){
console.log('scroll')
// 遍歷所有的img標簽 if(timer){ clearTimeout(timer) } timer=setTimeout(()=>{
console.log('lazyRenderImg...'); lazyRenderImg(); },
300);

通過列印的日誌發現當滾動停止後才執行lazyRenderImg方法的,確實減少了不必要調用lazyRenderImg的次數。

    頁面性能優化之圖片懶載入就寫這麼多了,網頁優化還有很多方法與技巧,前端路漫漫其修遠兮,吾將上下而求索。本文不足之處,請多指正。

 


 

參考資料:

https://www.jianshu.com/p/1b32e16ed0e5

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首先上圖: 實現這個標題欄,我們還需要一個返回的按鈕,這裡也貼出來。筆者直接將這個簡單的標題欄製作成了一個依賴庫,放在到github上,方便下次進行調用。 返回按鈕如下: 在使用這個按鈕的時候需要註意其尺寸的大小一定要小於我們的標題欄。 view_top.xml 新建的topview類: 調用方法: ...
  • 之前出現該錯誤,我用的是這個方法: https://www.cnblogs.com/tangZH/p/10691383.html 然而遺憾的是,這次不管用了,無奈,只好另尋他法,其實會出現這個錯誤就是資源文件出現問題,導致無法被打包。 從具體的錯誤裡面也可以看出,確實是資源文件出了問題 點擊右上角g ...
  • 轉載請標明出處,維權必究:https://www.cnblogs.com/tangZH/p/10770296.html android代碼,兩個版本之間,代碼行數增加了多少,怎麼得出呢? 1.安裝TortoiseSVN,在安裝時需要安裝svn命令行工具。 2、下載StatSVN包,官網:http:/ ...
  • 一、Contacts應用的主界面和聯繫人詳情界面增加頂部菜單添加退出按鈕 通過Hierarchy View 工具可以發現 主界面對應的類為 PeopleActivity 聯繫人詳情界面對應的類為 QuickContactActivity 左上角的退出按鈕其實很簡單,系統actionBar已經幫我們實 ...
  • 平時開發當中會用到很多png圖樣,但是自己又不太會做,因此做好的辦法就是直接在網上下載下來用了,這裡給大家推薦一個比較好用的網站,免費的,有很多好的png可以直接下載下來使用。 在我們瀏覽器當中輸入以上代碼就可以得到巨量可用的png圖片了。 ...
  • RKnanC是一種低成本、低功耗、高效率的數字多媒體晶元,它是基於ARM的低功耗處理器結構和硬體加速器。它是專為攜帶型音頻產品應用,如MP3播放器等。 RKnanC可以支持各種音頻標準的解碼,如MP3/WMA/OGG/標誌/AAC等。由於內置音頻硬體加速器,rknanc可以在非常低的系統中實現音頻解 ...
  • 我們先來看看效果: 這裡我們主要使用了github上的一個開源項目,配置起來比較方便,下麵解釋一下該如何使用:首先是:Gradle文件當中進行配置: 當然如果是老版本的Android Studio則使用: 二.activity 其中的第一個監聽器是switch在選擇的時候,所觸發的事件。第二個監聽器 ...
  • adb的全稱為Android Debug Bridge.是android司機經常用到的工具 . 你能在本篇文章中學到什麼? adb基本指令 Shell AM&PM adb模擬用戶事件 logcat日誌 常用節點 遠程ADB 常用命令集 一. 基本指令 進入指定設備 adb -s serialNumb ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...