整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          網頁圖片預加載實現的幾個方法解析

          頁中預加載圖片是提高用戶體驗的一個很好方法。圖片預先加載到瀏覽器中,訪問者便可順利地在你的網站上沖浪,并享受到極快的加載速度。這對圖片畫廊及圖片占據很大比例的網站來說十分有利,它保證了圖片快速加載,特別是一些大型的電商網站就常用!幫助用戶在瀏覽你網站內容時獲得更好的用戶體驗,下面就來說說實現圖片預加載的方法。

          一、使用JavaScript實現預加載

          提供兩種這樣的預加載方法,它們可以很漂亮地工作于所有現代瀏覽器之上。

          只需簡單編輯、加載所需要圖片的路徑與名稱即可,很容易實現:

          該方法尤其適用預加載大量的圖片。畫廊網站使用該技術,預加載圖片數量達50多張的時候。將該腳本應用到登錄頁面,只要用戶輸入登錄帳號,大部分畫廊圖片將被預加載。

          另外一種方法與上面的方法類似,也可以預加載任意數量的圖片。將下面的腳本添加入任何Web頁中,根據程序指令進行編輯即可。

          每加載一個圖片都需要創建一個變量,如“img1 = new Image();”,及圖片源地址聲明,如“img3.src = "../path/to/image-003.gif";”。參考該模式,你可根據需要加載任意多的圖片。

          二、用CSS實現預加載

          單純使用CSS,可容易、高效地預加載圖片,代碼如下:

          #preload-01 { background: url(-01.png) no-repeat -9999px -9999px; }#preload-02 { background: url(-02.png) no-repeat -9999px -9999px; }#preload-03 { background: url(-03.png) no-repeat -9999px -9999px; }

          將這三個ID選擇器應用到HTML元素中,我們便可通過CSS的background屬性將圖片預加載到屏幕外的背景上。只要這些圖片的路徑保持不變,當它們在Web頁面的其他地方被調用時,瀏覽器就會在渲染過程中使用預加載(緩存)的圖片。簡單、高效,不需要任何JavaScript。

          者:麥樂

          來源:恒生LIGHT云社區

          圖像延遲加載

          想要得到更好的性能體驗,只靠資源壓縮與恰當的文件格式選型,是很難滿足期望的。我們還需要針對資源加載過程進行優化。

          什么是延遲加載?

          下圖是京東商城的手機端首頁,當元素沒有滑動到視線內時,圖片src屬性放置了一個很小的圖片,init_src屬性放置了真正的圖片,只要當該元素滑動到視線內部,才會將init_src屬性賦值給src去加載真實的圖片,這就是一個簡單的圖片延遲加載的過程。

          傳統方式延遲加載

          就是事件監聽的方式,通過監聽scroll事件與resize事件,并在事件的回調函數中去判斷,需要進行延遲加載的圖片是否進入視窗區域。

          我們只需要關注三個屬性。

          • class屬性,稍后會在JavaScript中使用類選擇器選取需要延遲加載處理的〈img〉標簽。
          • src屬性,加載前的占位符圖片,可用Base64圖片或低分辨率的圖片。
          • data-src屬性,通過該自定義屬性保存圖片真實的URL外鏈。

          加入頁面中有多張這樣的圖片需要加載。具體的JavaScript實現邏輯如下,在文檔的DOMContentLoaded事件中,添加延遲加載處理邏輯,首先獲取class屬性名為lazy的所有〈img〉標簽,將這些標簽暫存在一個名為lazyImages的數組中,表示需要進行延遲加載但還未加載的圖片集合。當一個圖片被加載后,便將其從lazyImages數組中移除,直到lazyImages數組為空時,表示所有待延遲加載的圖片均已經加載完成,此時便可將頁面滾動事件移除。

          這里使用了getBoundingClientRect()函數獲取元素的相對位置.

                  rectObject = object.getBoundingClientRect();
          

          rectObject.top:元素上邊到視窗上邊的距離;

          rectObject.right:元素右邊到視窗左邊的距離;

          rectObject.bottom:元素下邊到視窗上邊的距離;

          rectObject.left:元素左邊到視窗左邊的距離;

          對于只可上下滾動的頁面,判斷一個圖片元素是否出現在屏幕視窗中的方法其實顯而易見,即當元素上邊緣距屏幕視窗頂部的top值小于整個視窗的高度window.innerHeight時,預加載的事件處理代碼如下:

          document.addEventListener(DOMContentLoaded, function() {
                const imags = [].slice.call(document.querySelector('.lazy'))
                const active = false; // 限制函數被頻繁調動
                function load() {
                  if(active === false) {
                    active = true
                    setTimeout(() => {
                      imags.forEach((img) => {
                        const objPos = img.getBoundingClientRect();
                        if(objPos.top <= window.innerHeight && objPos.bottom >=0 && img.display !== 'done') {
                          img.src = img.dataset.src;
                          img.classList.remove('lazy')
                          imags.filter((i) => (i !== img))
                          if(imags.length === 0) {
                            document.removeEventListener('scroll', load)
                            window.removeEventListener('resize', load)
                            window.removeEventListener('orientationchange', load)
                          }
            
                        }
                      })
                      active = false
                    }, 200)
                  }
          
                }
          
                document.addEventListener('scroll', load)
                window.addEventListener('resize', load)
                window.addEventListener('orientationchange', load)
          
              })
          

          這種方式的有點就是兼容性比較好,缺點是頻繁地進行計算必然會影響性能,代碼也會比較繁瑣。

          實現圖片的延遲加載:Intersection Observer方式

          現代瀏覽器已大多支持了Intersection Observer API,用一句話簡述:每當因頁面滾動或窗口尺寸發生變化,使得目標元素(target)與設備視窗或其他指定元素產生交集時,便會觸發通過Intersection Observer API配置的回調函數,在該回調函數中進行延遲加載的邏輯處理,會比傳統方式顯得更加簡潔而高效。

          簡單來說,目標元素的可見性變化時,就會調用觀察器的回調函數 callback

          callback一般會觸發兩次。一次是目標元素剛剛進入視口(開始可見),另一次是完全離開視口(開始不可見)。

           document.addEventListener(DOMContentLoaded, function() {
                  const imags = [].slice.call(document.querySelector('.lazy'))
                  if(window.IntersectionObserver && window.IntersectionObserverEntry && window.IntersectionObserverEntry.prototype.intersectionRatio) {
                    var lazyImgObserver = new IntersectionObserver((entries, observer) => {
                      entries.forEach((entry)=> {
                        if(entry.isIntersecting) {
                          var lazyImg = entry.target;
                          lazyImg.src = lazyImg.dataset.src;
                          lazyImg.classList.remove('lazy');
                          lazyImgObserver.unobserve(lazyImg)
                        }
                      })
                    })
                    imags.forEach((img) => {
                      lazyImgObserver.observe(img)
                    })
                  }
             
                })
          

          這種方式判斷元素是否出現在視窗中更為簡單直觀,應在實際開發中盡量使用,但其問題是并非所有瀏覽器都能兼容。

          (1)做好盡量完備瀏覽器兼容性檢查,對于兼容Intersection Observer API的瀏覽器,采用這種方式進行處理,而對于不兼容的瀏覽器,則切換回傳統的實現方式進行處理。 (2)使用相應兼容的polyfill插件,在W3C官方GitHub賬號下就有提供。

          實現圖片的延遲加載:CSS類名方式

          這種實現方式通過CSS的background-image屬性來加載圖片,與判斷〈img〉標簽src屬性是否有要請求圖片的URL不同,CSS中圖片加載的行為建立在瀏覽器對文檔分析基礎之上。

            document.addEventListener(DOMContentLoaded, function() {
                  const imags = [].slice.call(document.querySelector('.lazy'))
                  if(window.IntersectionObserver && window.IntersectionObserverEntry && window.IntersectionObserverEntry.prototype.intersectionRatio) {
                    var lazyImgObserver = new IntersectionObserver((entries, observer) => {
                      entries.forEach((entry)=> {
                        if(entry.isIntersecting) {
                          var lazyImg = entry.target;
                          lazyImg.classList.add('visible');
                          lazyImgObserver.unobserve(lazyImg)
                        }
                      })
                    })
                    imags.forEach((img) => {
                      lazyImgObserver.observe(img)
                    })
                  }
             
                })
          

          這種方式限制于需要提前寫好css樣式。

          原生的延遲加載支持

          除了上述通過開發者手動實現延遲加載邏輯的方式,從Chrome 75版本開始,已經可以通過〈img〉和〈iframe〉標簽的loading屬性原生支持延遲加載了,loading屬性包含以下三種取值。

          ● lazy:進行延遲加載。 ● eager:立即加載。 ● auto:瀏覽器自行決定是否進行延遲加載。

          測試:image標簽就是 img

          <!DOCTYPE html>
          <html lang="en">
          <head>
            <meta charset="UTF-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Document</title>
            <!-- <script src="js/file2.js"></script> -->
            <!-- <script src="js/file3.js"></script> -->
            <!-- <link rel="stylesheet" href="css/index.css"> -->
            <style>
              img {
                width: 700px;
                height: 200px;
                display: block;
              }
            </style>
          </head>
          <body>
          
            
            
            <imgage loading="lazy" src='./image/home-1.png' alt="photo" />
            <imgage loading="lazy" src='./image/home-2.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-3.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-4.png' alt="photo" />
            <imgage loading="lazy" src='./image/home-5.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-6.png' alt="photo" />
          
          
            <imgage loading="lazy" src='./image/home-7.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-8.png' alt="photo" />
            
            <imgage loading="lazy" src='./image/home-9.png' alt="photo" />
            <imgage loading="lazy" src='./image/home-10.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-11.png' alt="photo" />
          
          
            <imgage loading="lazy" src='./image/home-12.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-13.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-14.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-15.png' alt="photo" />
          
          
            <imgage loading="lazy" src='./image/home-16.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-17.png' alt="photo" />
            <imgage loading="lazy" src='./image/home-18.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-19.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-20.png' alt="photo" />
          
          
            <imgage loading="lazy" src='./image/home-21.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-22.png' alt="photo" />
            
            <imgage loading="lazy" src='./image/home-23.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-24.png' alt="photo" />
          
          
            <imgage loading="lazy" src='./image/home-25.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-26.png' alt="photo" />
            <imgage loading="lazy" src='./image/home-27.png' alt="photo" />
          
            <imgage loading="lazy" src='./image/home-28.png' alt="photo" />
          
          
            <imgage loading="lazy" src='./image/home-29.png' alt="photo" />
          
          <imgage loading="lazy" src='./image/home-30.png' alt="photo" />
          
          
          
          </body>
          </html>
          

          可以看到,首次加載的個數是13個,首屏一般只能放下4個左右,13個以后的img滾動到視線內部會自動去加載。

          實踐發現有以下幾個特點:

          1. Lazy loading加載數量與屏幕高度有關,高度越小加載數量越少,但并不是線性關系。
          2. Lazy loading加載數量與網速有關,網速越慢,加載數量越多,但并不是線性關系。
          3. Lazy loading加載沒有緩沖,滾動即會觸發新的圖片資源加載。
          4. Lazy loading加載在窗口resize尺寸變化時候也會觸發,例如屏幕高度從小變大的時候。
          5. Lazy loading加載也有可能會先加載后面的圖片資源,例如頁面加載時滾動高度很高的時候。

          與JavaScript有關的幾個行為特征:

          1. 判斷瀏覽器是否支持原生loading,最好使用'loading' in XXX判斷。
          2. 獲取loading屬性值可以直接img.loading;
          3. 原生loading不可寫,不可訪問例如HTMLImageElement.prototype.loading會報錯Illegal invocation。
          4. 如果要使用,注意做兼容性處理。

          兩天被django折磨的快崩潰了。要做一個網頁,結果CSS 和圖片總是加載不出來。官方文檔中教了一部分,上網看樂各種教程都不行,研究了好幾個小時,東拼西湊各個地方學一點,終于弄出來了,趕緊記錄下來。

          django用的靜態文件路徑:STATICFILES_DIRS部署的方式,文件路徑一定要設置好。

          注: python2.7 django1.10.6; 項目mysite,項目下有一個應用myapp

          一、目錄結構:

          整個目錄結構是這樣的:

          | mysite

          | —— manage.py

          | —— mysite

          | —— | —— settings

          | —— | ——…(urls等)

          | —— templates

          | —— myapp

          | —— …(views等)

          | —— | —— templates

          | —— | —— | —— myapp

          | —— | —— | —— | —— home.html

          | —— | —— | —— | —— static

          | —— | —— | —— | —— | —— css

          | —— | —— | —— | —— | —— images

          注意,文件夾結構比較復雜。

          在項目文件夾下有一個templates文件夾,不過這個文件夾暫時沒什么用,可以不用管(我也不知道為什么要有這么個文件夾)。

          應用文件夾結構是這樣的:

          “myapp/templates/myapp/home.html”;

          “myapp/templates/myapp/static/images”;

          “myapp/templates/myapp/static/CSS”;

          二、設置templates和靜態路徑

          • 在settings.py中設置templates路徑

          TEMPLATES = [

          {

          'BACKEND': 'django.template.backends.django.DjangoTemplates',

          'DIRS': [os.path.join(BASE_DIR, 'myapp/templates').replace('\', '/'),

          os.path.join(BASE_DIR, 'templates').replace('\', '/')],

          }

          ]

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 在settings.py文件的最后加上以下內容:

          STATIC_ROOT = os.path.join(BASE_DIR, 'myapp/templates/myapp/static').replace('\', '/')

          STATICFILES_DIRS = (

          ('css', os.path.join(STATIC_ROOT, 'css').replace('\', '/')),

          ('images', os.path.join(STATIC_ROOT, 'images').replace('\', '/')),

          )

          • 1
          • 2
          • 3
          • 4
          • 5

          三、修改urls.py文件

          在urls.py開頭加上一句:

          from django.contrib.staticfiles.urls import staticfiles_urlpatterns

          • 1

          在urls.py的最后加上以下內容:

          #設置靜態文件路徑

          urlpatterns += staticfiles_urlpatterns()

          • 1
          • 2

          四、修改html文件

          home.html文件相關內容如下:

          <!DOCTYPE html>

          <html lang="en">

          <head>

          <link href="/static/css/style.css" rel="stylesheet" type="text/css" />

          <title>Home</title>

          </head>

          <body>

          <a href="https://www.baidu.com/>

          <img src="/static/images/logo.png" alt="logo"/>

          </a>

          </body>

          </html>

          • 1
          • 2
          • 3
          • 4
          • 5
          • 6
          • 7
          • 8
          • 9
          • 10
          • 11
          • 12

          改成自己的圖片名稱,注意圖片和link的前綴:/static/images/ 別寫成 static/images/ ,這樣會無法顯示。

          感覺自己底子真的太差,這幾天一點一點看官方文檔感到非常吃力,很多地方都不懂,想直接看自己需要的部分又不知道該看哪。


          主站蜘蛛池模板: 亚洲一区二区视频在线观看| 日韩精品一区二区午夜成人版 | 国产人妖视频一区二区破除| 超清无码一区二区三区| 丰满人妻一区二区三区免费视频| 国产成人精品一区二区三区无码| 一区二区三区四区免费视频| av无码精品一区二区三区四区| 国产成人一区二区三区在线观看| 国产精品视频分类一区| 精品国产日产一区二区三区 | 合区精品久久久中文字幕一区| 亚洲一区二区三区日本久久九| 亚洲男人的天堂一区二区| 国产一区二区三区精品久久呦| 亚洲av乱码一区二区三区| 国产乱码精品一区二区三区中文| 亚洲国产av一区二区三区| 亚洲国产高清在线一区二区三区| 精品乱码一区内射人妻无码| 怡红院一区二区在线观看| 日本精品视频一区二区| 爱爱帝国亚洲一区二区三区| 国产激情一区二区三区在线观看| 韩国精品一区视频在线播放| 国产成人一区二区在线不卡| 能在线观看的一区二区三区| 无码人妻AⅤ一区二区三区水密桃 无码欧精品亚洲日韩一区夜夜嗨 无码毛片一区二区三区中文字幕 无码毛片一区二区三区视频免费播放 | 国产精品无码一区二区三区电影 | 加勒比无码一区二区三区| 亚洲欧美国产国产综合一区| 亚洲av乱码中文一区二区三区| 天堂一区二区三区精品| 波多野结衣高清一区二区三区| 久久久久人妻精品一区蜜桃| 欧美亚洲精品一区二区| 精品91一区二区三区| 久久精品免费一区二区三区| 在线成人综合色一区| 亚洲AV色香蕉一区二区| 成人毛片一区二区|