<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                首先要告訴大家的是,截止到上個章節,我們需要大家絞盡腦汁去理解的“硬核”操作基本告一段落了。從本節開始,我們會一起去實現一些必知必會、同時難度不大的常用優化手段。 這部分內容不難,但**很關鍵**。尤其是近期有校招或跳槽需求的同學,還請務必對這部分內容多加留心,說不定下一次的面試題里就有它們的身影。 ## Lazy-Load 初相見 Lazy-Load,翻譯過來是“懶加載”。它是針對圖片加載時機的優化:在一些圖片量比較大的網站(比如電商網站首頁,或者團購網站、小游戲首頁等),如果我們嘗試在用戶打開頁面的時候,就把所有的圖片資源加載完畢,那么很可能會造成白屏、卡頓等現象,因為圖片真的太多了,一口氣處理這么多任務,瀏覽器做不到啊! 但我們再想,用戶真的需要這么多圖片嗎?不對,用戶點開頁面的瞬間,呈現給他的只有屏幕的一部分(我們稱之為首屏)。只要我們可以在頁面打開的時候把首屏的圖片資源加載出來,用戶就會認為頁面是沒問題的。至于下面的圖片,我們完全可以等用戶下拉的瞬間再即時去請求、即時呈現給他。這樣一來,性能的壓力小了,用戶的體驗卻沒有變差——這個延遲加載的過程,就是 Lazy-Load。 現在我們打開掘金首頁: ![](https://user-gold-cdn.xitu.io/2018/10/5/16642f37c7f20143?w=1424&h=1092&f=png&s=251118) 大家留意一欄文章右側可能會出現的圖片,這里咱們給個特寫: ![](https://user-gold-cdn.xitu.io/2018/10/5/16642f57149017c9?w=202&h=662&f=png&s=59534) 大家現在以盡可能快的速度,瘋狂向下拉動頁面。發現什么?是不是發現我們圖示的這個圖片的位置,會出現閃動——有時候我們明明已經拉到目標位置了,文字也呈現完畢了,圖片卻慢半拍才顯示出來。這是因為,掘金首頁也采用了懶加載策略。當我們的頁面并未滾動至包含圖片的 div 元素所在的位置時,它的樣式是這樣的: ![](https://user-gold-cdn.xitu.io/2018/10/5/16642f9403b5f320?w=1312&h=142&f=png&s=62803) 我們把代碼提出來看一下: ``` <div data-v-b2db8566="" data-v-009ea7bb="" data-v-6b46a625="" data-src="https://user-gold-cdn.xitu.io/2018/9/27/16619f449ee24252?imageView2/1/w/120/h/120/q/85/format/webp/interlace/1" class="lazy thumb thumb" style="background-image: none; background-size: cover;"> </div> ``` 我們注意到 style 內聯樣式中,背景圖片設置為了 none。也就是說這個 div 是沒有內容的,它只起到一個**占位**的作用。 這個“占位”的概念,在這個例子里或許體現得不夠直觀。最直觀的應該是淘寶首頁的 HTML Preview 效果: ![](https://user-gold-cdn.xitu.io/2018/10/5/1664307daf51a16e?w=2290&h=972&f=png&s=125909) 我們看到,這個還沒來得及被圖片填充完全的網頁,是用大大小小的空 div 元素來占位的。掘金首頁也是如此。 一旦我們通過滾動使得這個 div 出現在了可見范圍內,那么 div 元素的內容就會發生變化,呈現如下的內容: ![](https://user-gold-cdn.xitu.io/2018/10/5/1664300e3f14b7c9?w=1198&h=252&f=png&s=109226) 我們給 style 一個特寫: ``` style="background-image: url(&quot;https://user-gold-cdn.xitu.io/2018/9/27/16619f449ee24252?imageView2/1/w/120/h/120/q/85/format/webp/interlace/1&quot;); background-size: cover;" ``` 可以看出,style 內聯樣式中的背景圖片屬性從 none 變成了一個在線圖片的 URL。也就是說,出現在可視區域的瞬間,div 元素的內容被即時地修改掉了——它被寫入了有效的圖片 URL,于是圖片才得以呈現。這就是懶加載的實現思路。 ## 一起寫一個 Lazy-Load 吧! 基于上面的實現思路,我們完全可以手動實現一個屬于自己的 Lazy-Load。 (**此處敲黑板劃重點,Lazy-Load 的思路及實現方式為大廠面試常考題,還望諸位同學引起重視**) 首先新建一個空項目,目錄結構如下: ![](https://user-gold-cdn.xitu.io/2018/10/5/1664322fcf90be3e?w=466&h=116&f=png&s=14252) 大家可以往 images 文件夾里塞入各種各樣自己喜歡的圖片。 我們在 index.html 中,為這些圖片預置 img 標簽: ``` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Lazy-Load</title> <style> .img { width: 200px; height:200px; background-color: gray; } .pic { // 必要的img樣式 } </style> </head> <body> <div class="container"> <div class="img"> // 注意我們并沒有為它引入真實的src <img class="pic" alt="加載中" data-src="./images/1.png"> </div> <div class="img"> <img class="pic" alt="加載中" data-src="./images/2.png"> </div> <div class="img"> <img class="pic" alt="加載中" data-src="./images/3.png"> </div> <div class="img"> <img class="pic" alt="加載中" data-src="./images/4.png"> </div> <div class="img"> <img class="pic" alt="加載中" data-src="./images/5.png"> </div> <div class="img"> <img class="pic" alt="加載中" data-src="./images/6.png"> </div> <div class="img"> <img class="pic" alt="加載中" data-src="./images/7.png"> </div> <div class="img"> <img class="pic" alt="加載中" data-src="./images/8.png"> </div> <div class="img"> <img class="pic" alt="加載中" data-src="./images/9.png"> </div> <div class="img"> <img class="pic" alt="加載中" data-src="./images/10.png"> </div> </div> </body> </html> ``` 在懶加載的實現中,有兩個關鍵的數值:一個是**當前可視區域的高度**,另一個是**元素距離可視區域頂部的高度**。 **當前可視區域的高度**, 在和現代瀏覽器及 IE9 以上的瀏覽器中,可以用 window.innerHeight 屬性獲取。在低版本 IE 的標準模式中,可以用 document.documentElement.clientHeight 獲取,這里我們兼容兩種情況: ``` const viewHeight = window.innerHeight || document.documentElement.clientHeight ``` 而**元素距離可視區域頂部的高度**,我們這里選用 getBoundingClientRect() 方法來獲取返回元素的大小及其相對于視口的位置。對此 MDN 給出了非常清晰的解釋: > 該方法的返回值是一個 DOMRect 對象,這個對象是由該元素的 getClientRects() 方法返回的一組矩形的集合, 即:是與該元素相關的 CSS 邊框集合 。 > DOMRect 對象包含了一組用于描述邊框的只讀屬性——left、top、right 和 bottom,單位為像素。除了 width 和 height 外的屬性都是相對于視口的左上角位置而言的。 其中需要引起我們注意的就是 left、top、right 和 bottom,它們對應到元素上是這樣的: ![](https://user-gold-cdn.xitu.io/2018/10/5/1664360c6ceda200?w=500&h=500&f=png&s=25422) 可以看出,top 屬性代表了元素距離可視區域頂部的高度,正好可以為我們所用! Lazy-Load 方法開工啦! ``` <script> // 獲取所有的圖片標簽 const imgs = document.getElementsByTagName('img') // 獲取可視區域的高度 const viewHeight = window.innerHeight || document.documentElement.clientHeight // num用于統計當前顯示到了哪一張圖片,避免每次都從第一張圖片開始檢查是否露出 let num = 0 function lazyload(){ for(let i=num; i<imgs.length; i++) { // 用可視區域高度減去元素頂部距離可視區域頂部的高度 let distance = viewHeight - imgs[i].getBoundingClientRect().top // 如果可視區域高度大于等于元素頂部距離可視區域頂部的高度,說明元素露出 if(distance >= 0 ){ // 給元素寫入真實的src,展示圖片 imgs[i].src = imgs[i].getAttribute('data-src') // 前i張圖片已經加載完畢,下次從第i+1張開始檢查是否露出 num = i + 1 } } } // 監聽Scroll事件 window.addEventListener('scroll', lazyload, false); </script> ``` ## 小結 本節我們實現出了一個最基本的懶加載功能。但是大家要注意一點:這個 scroll 事件,是一個**危險**的事件——它太容易被觸發了。試想,用戶在訪問網頁的時候,是不是可以無限次地去觸發滾動?尤其是一個頁面死活加載不出來的時候,瘋狂調戲鼠標滾輪(或者瀏覽器滾動條)的用戶可不在少數啊! 再回頭看看我們上面寫的代碼。按照我們的邏輯,用戶的每一次滾動都將觸發我們的監聽函數。函數執行是吃性能的,頻繁地響應某個事件將造成大量不必要的頁面計算。因此,我們需要針對那些有可能被頻繁觸發的事件作進一步地優化。這里就引出了我們下一節的兩位主角——throttle 與 debounce。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看