好的,本篇的程式正是為了解決以上所有難題,自動幫文章中的圖片預先設定尺寸、並能執行最佳的 Lazy Load 效果。以下大致先說明原理,想直接安裝懶人包請跳至「二、準備動作」。
<< 請注意!本篇文章含會員限定內容 >>
一、新舊版 Lazy Load 及最佳化原理
1. 版本差異
目前「Lazy Load 官網」提供的 js 版本,要正常運作得將圖片的 HTML 碼改為以下格式:
<img class="lazy" data-original="img/example.jpg" width="640" height="480">
原本 img 應該是 src 屬性的位置,必須改為 "data-original" 這樣的屬性,且須手動設定圖片寬、高值。如果每張圖片都這麼搞,沒幾個人有這樣的耐性吧?
這篇「Lazy Load 最佳安裝方式」使用 Lazy Load 舊版的 js,圖片 img 的 HTML 不需做任何變更即可執行延遲載入,因此舊版的 js 比較適合懶人安裝法,本篇的程式碼依舊沿用這個版本。
2. 自動取得圖片寬高
這部分的原理是,利用 jQuery 的 on() 函數來監控 img 的 load 事件,就能取得圖片的寬高值,再設定到原本的 img 上,來避免 reflow 的發生。
3. Lazy Load 擺放位置
如同「舊版 Lazy Load 教學」的說明,網頁不需要全部圖片都 Lazy Load,最需要使用 Lazy Load 的是文章區塊的圖片。因此最佳的執行位置是「文章區塊結尾處」,而非
也因為這一點,要安裝 Lazy Load 得先「找出文章區塊結尾處」這個位置。本篇教學提供 Blogger 的範例,而非 Blogger 平台的使用者,可能需學會操作「Chrome 開發人員工具」這樣的介面,來自行找出文章區塊的位置。
二、安裝準備動作
1. Blogger 平台
安裝過舊版本的話,這部分的動作可不必再做。
在修改範本之前,如果第一次安裝本站工具的讀者,建議先閱讀「備份範本的訣竅」系列文章。
請到後台「範本」→「編輯 HTML」,游標點進範本區塊,搜尋
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js'></script>
<script>//<![CDATA[(function($){$.fn.lazyload=function(options){var settings={threshold:0,failurelimit:0,event:"scroll",effect:"show",container:window};if(options){$.extend(settings,options);}
var elements=this;if("scroll"==settings.event){$(settings.container).bind("scroll",function(event){var counter=0;elements.each(function(){if($.abovethetop(this,settings)||$.leftofbegin(this,settings)){}else if(!$.belowthefold(this,settings)&&!$.rightoffold(this,settings)){$(this).trigger("appear");}else{if(counter++>settings.failurelimit){return false;}}});var temp=$.grep(elements,function(element){return!element.loaded;});elements=$(temp);});}
this.each(function(){var self=this;if(undefined==$(self).attr("original")){$(self).attr("original",$(self).attr("src"));}
if("scroll"!=settings.event||undefined==$(self).attr("src")||settings.placeholder==$(self).attr("src")||($.abovethetop(self,settings)||$.leftofbegin(self,settings)||$.belowthefold(self,settings)||$.rightoffold(self,settings))){if(settings.placeholder){$(self).attr("src",settings.placeholder);}else{$(self).removeAttr("src");}
self.loaded=false;}else{self.loaded=true;}
$(self).one("appear",function(){if(!this.loaded){$("").bind("load",function(){$(self).hide().attr("src",$(self).attr("original"))
[settings.effect](settings.effectspeed);self.loaded=true;}).attr("src",$(self).attr("original"));};});if("scroll"!=settings.event){$(self).bind(settings.event,function(event){if(!self.loaded){$(self).trigger("appear");}});}});$(settings.container).trigger(settings.event);return this;};$.belowthefold=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).height()+$(window).scrollTop();}else{var fold=$(settings.container).offset().top+$(settings.container).height();}
return fold<=$(element).offset().top-settings.threshold;};$.rightoffold=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).width()+$(window).scrollLeft();}else{var fold=$(settings.container).offset().left+$(settings.container).width();}
return fold<=$(element).offset().left-settings.threshold;};$.abovethetop=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).scrollTop();}else{var fold=$(settings.container).offset().top;}
return fold>=$(element).offset().top+settings.threshold+$(element).height();};$.leftofbegin=function(element,settings){if(settings.container===undefined||settings.container===window){var fold=$(window).scrollLeft();}else{var fold=$(settings.container).offset().left;}
return fold>=$(element).offset().left+settings.threshold+$(element).width();};$.extend($.expr[':'],{"below-the-fold":"$.belowthefold(a, {threshold : 0, container: window})","above-the-fold":"!$.belowthefold(a, {threshold : 0, container: window})","right-of-fold":"$.rightoffold(a, {threshold : 0, container: window})","left-of-fold":"!$.rightoffold(a, {threshold : 0, container: window})"});})(jQuery);//]]></script>
第一行綠字的 js 檔連結可參考「引用 jQuery 的注意事項」,檢查範本是否已安裝過 jquery,以免重複安裝。
2. 非 Blogger 平台
說明一樣參考第 1 點,程式碼放在範本中
三、安裝程式碼
1. Blogger 平台
A. 接著在範本中先找到 <b:if cond='data:post.hasJumpLink'> 這個字串,會看到類似下面「繼續閱讀」的程式碼:
<b:if cond='data:post.hasJumpLink'>
<div class='jump-link'>
<a expr:href='data:post.url + "#more"' expr:title='data:post.title'><data:post.jumpText/></a>
</div>
</b:if>
B. 緊接在以上程式碼後面,插入以下程式碼(這裡如安裝過舊版 lazy load,請先刪除舊版程式碼):
以下參數修改請參照以上程式碼行號:
F:預設讓 Lazy Load 抓文章區塊 .post-body 之間的 img 標籤來進行延遲載入,而頁面其他區塊的圖片將沒有 Lazy Load 效果。(如果要設定別的區塊的圖片,那麼 E、F 行的紅色字串得改為該區塊的 class 或 id,且全部程式碼得改放到該區塊的位置之後。)
Y:除了使用藍色字串參數 "fadeIn" 的淡入特效,還可用 "slideDown" 由小圖伸展到大圖的特效,或是使用 "show" 無特效。
2015.1.18 修訂:由於留言回報首頁圖片顯示會不正常,因此 Blogger 平台請將 Y~Z 兩行的內容置換為以下:
effect: "fadeIn"
<b:if cond='data:blog.pageType != "index"'>,
placeholder: "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBSMPFDF3VOU81f1SAdcoAN2plSV0JBPng2yjNoe0iKq-9h1YnSTNXM6s5ttto1_Y5q6JnF8ZJuexVV4JDZki9_dKgWtfYItPx560Gs0nnnwkvvP1awaJoLidRhJcEKdafks2-ywB5rgRP/s0/grey.gif"
</b:if>
存檔後開一篇圖片多的文章即可看效果,或是也可參考 DEMO 網頁:
2. 非 Blogger 平台
A. 請先找出文章區塊的 class 或 id,可利用「Chrome 開發人員工具」這樣的介面。
B. 在後台範本中找到這個區塊的結尾處,於下一行插入「1. Blogger 平台」→ B 點的程式碼,並參照程式碼行號:
E~F:紅色字串得改為文章區塊的 class 或 id。
Y:除了使用藍色字串參數 "fadeIn" 的淡入特效,還可用 "slideDown" 由小圖伸展到大圖的特效,或是使用 "show" 無特效。
四、小結
若曾使用舊版 Lazy Load 安裝程式,由於圖片寬、高事先不知道數值,瀏覽器無法為圖片保留位置,畫面在捲動之間會不斷產生 reflow、版面區塊會不斷擠壓變動,增加瀏覽器無謂的運算量。使用了本篇新版的安裝程式後,相信畫面捲動的時候,可以明顯感受到兩者的差異性,為網頁帶來更好的效能。
五、常見 FAQ
日後若有常見問題,會持續補充在此。
Q1: 留言 #2 提到「進入任意一篇文章後再按導覽列上的"首頁"回到首頁,會出現圖片不見的狀況(重新整理後又正常出現)」?
Ans: 如果 Blogger 首頁會出現異常情形的話,請刪除 Y 行最後面的逗點 "," 以及 Z 行的內容即可。(2014.12.18 補充:由於多位使用者出現此情形,已將原程式碼 Y 行最後面的逗點 "," 以及 Z 行的內容去除 )
優化網站效能 相關文章:
感謝您的分享!晚上來安裝!
回覆刪除Wayne您好:請問一下,我在安裝後,當我進入任意一篇文章後再按導覽列上的"首頁"回到首頁,會出現圖片不見的狀況(重新整理後又正常出現)
刪除問題截圖https://lh4.googleusercontent.com/-M7VyNavCK9k/VJF61xyLF5I/AAAAAAABFMI/M9DDGHBGMSE/w973-h545-no/%E5%9C%96%E7%89%871.jpg
網址:http://www.hairblog.tw/
麻煩您,謝謝
請問是將Z行整行去除嗎?還是Z行的 gif 檔網址去除呢?謝謝您!
刪除已可正常顯示了!感謝你^^
刪除感謝 Wayne~
回覆刪除安裝了新版的 Lazy Load,預留圖片寬高位置,讓我的BLOG更加的流暢 :)
而經過測試後,也一樣出現和樓上相同的問題,但刪除Z行後問題就解決了!
網址:http://taipeilifemap.blogspot.com/
想再請教一個問題。安裝這個版本後,後續寫的新文章是否還需要照您的文章「減少網頁 reflow(回流) 的 CSS 實作技巧﹍優化網站效能(3)」裡面第三項第1點來加上圖片尺寸呢?謝謝
回覆刪除這麼說也是!目前使用後,網頁速度感覺不出來有影響到!感謝解惑^^
刪除謝謝WFU的懶人包,每次都受惠良多~
回覆刪除試用了好幾天,覺得這個真的是很完美的解決方案,
只是我好像遇上了點問題,也似乎只有我一人遇到?
事發擷圖: http://i.imgur.com/FJdytLm.jpg
網址: http://totoasims.blogspot.com/2014/06/lot-display-8thdorm.html#more
有時候有些圖片會呈現成圖中的樣子,
不正常地縮小了(似乎只有使用Firefox才會這樣)
詭異的是重新整理後就回復正常了,
雖然如此,還是想知道原因在哪,讓我對症下藥。
會不會是我哪個步驟做錯了呢?
謝謝WFU的回覆~
刪除其實我是安裝了本篇的Lazyload後,發現blogger本身的燈箱無法有效運作,只會讀取每篇的第一張圖片,才安裝Fancybox的耶!反而是用fancybox才可以正常地使用燈箱,可以在燈箱模式看到文章的圖片。
我暫時拿走了fancybox,似乎還是有同一個問題,
這邊也會試著逐一移除其他js,來推論是不是有某個js跟它打架了,不過這的確需要時間。
謝謝你~
直接開了一個新的部落格來測試,似乎真的是由於圖片太多了……
刪除在新的部落格,放十張圖的時候,在FF的環境也運作正常,但二十張就不行了。
把jquery版本換成2.1.1,問題還是會出現。
只好換回舊版lazyload,謝謝WFU的幫忙~
Wayne您好:剛剛看到我的網頁圖片出現這個問題 https://lh6.googleusercontent.com/-CBG-o4FGhbw/VLi4umgXgMI/AAAAAAABGVY/XErUn3ytkfY/w1000-h563-no/%E5%87%BA%E9%8C%AF1.jpg 這個狀況只在火狐(Chrome正常沒發生過)上出現(F5後又恢復正常),請問一下是跟"自動取得圖片寬高"有關係嗎??謝謝您
回覆刪除已修正!!感謝您!!我再觀察看看!!
刪除不過有點納悶,我的網頁感覺不出有淡入特效耶!這正常嗎??
而且用Chrome檢查,看到Lazy Load的js有錯誤
沒想到只是jquery跟js的順序不同就錯了= =感謝嚕!!已修正!!
刪除改版後的程式碼"Y 行最後面的逗點 "," 以及 Z 行的內容"不用刪除了嗎??
Wayne您好:我照個程式碼安裝後還是出現了如我在#1發問的問題,圖片只出現1x1的白色灰點小圖,麻煩您看一下
刪除已更新!更快了~
回覆刪除我的行動版即使使用「網頁版」,載入也頗快的,就用「網頁版」頂著先。
官方行動範本/自訂,都 ... 太簡潔/無法正常顯示(內文也沒出來),令人一度很困擾。
偏偏行動瀏覽的數量一直遞增,有時候幾乎跟網頁瀏覽各佔一半了。
4. 我的手機是現在來說,很掉漆的紅米一代,
刪除因為連它都跑的了網頁版,所以才想說直接那樣做。
目前啟用行動版的「自訂」了,
隨便一篇文章都是沒有內文、廣告等該有的基本樣式,
隨便一篇傳送門:lasjargon.blogspot.tw/2015/04/mkvtoolnix.html?m=1
首頁基本上也算是空蕩蕩了...,不知道該從哪裡形容了...,
大概就是...跟大家都差很多...這樣。
本來想說等你的行動裝置系列文都完結、吸收了,再來看看有沒有辦法自救。
那就麻煩你提前出手,先幫我把脈一下,荒廢好久又增添你的麻煩了 >"<
又要除蟲了(捕蟲網 check),請給我一大把時間抓蟲去~~
刪除對耶,那三個廣告一直是我的困擾點,頂部那個在 opera 沒法顯示...。
(破破爛爛的語法,成就破破爛爛的 blog,耶~~)
順便先來研究一下「在 Blogger 文章各種位置插入 Adsense 廣告﹍安裝懶人包」,你忙先,讓我的腦細胞先遊盪一下。
結果我看完所有 .js,嘗試遮蔽或移動到</head>,都無果。
刪除最後偷吃步,
索性參照這篇「Blogger 自訂行動版範本實作﹍(2) 文章+側邊欄+頁尾」→「六、文章區塊」→「2. 懶人作法」,將判斷式遮蔽,行動版終於顯示了,雖然目前版面看起來有點小混亂 XD。
Q:我這樣的作法正確嗎?還是我並沒有除到錯?
.js的部份有以下這些:
刪除jquery.min.js|lazyload-min.js
這 2 個基於主觀判斷,位置本來就在</heae>之上,完全沒動到
adsbygoogle.js
一開始的嫌疑犯,在<body...>內被我腦殘的重複了三次,
後來按照「Blogger 文章各種位置插入 Adsense 廣告﹍安裝懶人包」所示的位置刪除、移動與使用,舊有的 code 已經全數刪掉了。
Analytics分析 ga.js|plusone.js
這 2 個完全沒有動到,直接照本宣科搬到乾淨的範本似乎意義不大?
google_top_exp.js
這一個我不知道它是誰 XD,所以也沒移動
相關文章 related-post-140416-min.js|留言分頁 commTab-min-140729.js
這 2 個基於感性的判斷 XD,我也完全沒移動。
留言區塊作者虛線高亮 jquery-latest.js
嘗試移動到</heae>之上,但會影響到 lazyload-min.js 的執行,所以又搬回原位。
這些動作因為行動版內文完全無顯示的時間壓力,只被我粗糙的搜尋出來並直接在原來的範本上做更動,明天會再到弄到測試的部落格範本試試,還好我現在知道了連<script>的標籤也要去掉,多謝 Wayne 大提醒了門外漢。
另外我想問,尚未更動前,我不乾淨範本的判斷式如下:
<b:widget id='Blog1' locked='false' title='網誌文章' type='Blog'>
...
<b:if cond='data:mobile == "false"'>
...
這是正常的嗎?
(ps.請原諒門外漢不知所謂的描述與問題 >"<)
哈哈!門外漢不小心清過頭了。
刪除好的,跳!移動~
用Chrome的F12檢測貴站圖片載入情形
回覆刪除LazyLoad貌似還是會一次下載所有圖片...
只是顯示圖片會慢慢出現...
這樣應該跟LazyLoad有段差距...
版大 你好,我按你的教學在網站加入安裝代碼,但是沒有變化…照樣一次載入圖片
回覆刪除「三、安裝程式碼」的部分要搜尋「 」
回覆刪除但是在「編輯 HTML」中搜尋不到。
似乎沒有成功,把程式碼都放上去後去pagespeed做測速,還是檢驗出建議「延後載入畫面外圖片」。
刪除檢測網址:https://cosmicwack.blogspot.com/2019/04/blog-post_28.html
感覺剛剛提供的資訊不夠充足。再次比對程式後,我發現兩個奇怪的地方。
刪除如果資訊還是不夠,請還需要提供哪方面的資訊才有辦法處理,十分感謝。