關於這件事先說結論,除非網站 Javascript(簡稱 js) 大部分是自己寫的,否則站長能做的改善有限,因為 js 寫得好不好無法由自己控制。因此如何減少 reflow,本篇著重在可以經由修改範本來改善的部分,也就是我們能 "自力救濟" 的部分。
在 Blogger 平台如果硬要打分數的話,以這個系列文來說,能完成「優化網站效能該注意哪些事? (1)最關鍵的考量因素」起碼可拿到 50 分以上,完成「 HTML / Javascript / CSS 最佳化處理」約可拿到 20 分;而本文按照教學設定正確的 css 最多可拿到 5~10 分,如能自行解決 js 可額外拿到 5~15 分,依範本中需要處理的多寡而定。
一、瀏覽器運作原理
1. 瀏覽器如何渲染網頁
要改善 reflow 現象,得從瞭解瀏覽器運作原理下手。這篇「瀏覽器渲染原理」非常值得推薦,簡短又生動地說明了網頁大致的渲染(render)流程。以下用精要的文字歸納 reflow 的定義:
- 當網頁任一個區塊,其尺寸或位置產生變化時,瀏覽器必須重新計算受影響的區塊(尺寸或位置),重新安排區塊位置、重新繪製畫面的整個流程,稱為 reflow(英文字面來看,就是重新流動一次)。
當一個改變造成影響的區塊越多,可想而知瀏覽器的運算會有多累了。如前所述,非程式設計者的我們,無法自行優化 js,不過根據參考文章,我們可以自行優化 CSS 的部分:替所有圖片設定寬、高的參數。
以上為區塊變動時,reflow 行為的示意圖
當 CSS 參數改變、但區塊尺寸沒變動的話,只會進行重繪(repaint),而不會引起 reflow。
由於原文的圖片掛了,以上兩圖取自轉貼原文的網址:http://justjavac.iteye.com/blog/644235
2. 替圖片設定尺寸
當圖片沒有設定尺寸參數時,瀏覽器在下載圖片之前,便無法知道這張圖片到底多大,所以不會為圖片保留座位。你一定有這樣的經驗:
- 逛網頁時,會看到文章中的文字先顯示出來,忽然間一張圖片顯示了出來,把原來的文字從圖片顯示的位置,擠到了下方去。而一篇文章中放了幾張圖片,就可能依序重複發生以上的現象。
以上就是頁面多次發生 reflow 的現象,圖片之後的內容、區塊越多,瀏覽器因為 reflow 所耗費的運算就越龐大。解決的方法現在我們已經知道,事先幫圖片用 CSS 設定好寬、高,那麼瀏覽器會先幫圖片把這個區塊的尺寸保留起來(圖片未顯示前的空白區塊),自然就不會發生 reflow 的無謂運算了。
3. 舉一反三
瞭解原理之後,從圖片的處理我們可聯想到,其他區塊也可用同樣的方式來處理,最大程度地避免 reflow 發生。
- Iframe:許多 Facebook 外掛提供了 Iframe 的形式,例如「讚按鈕」,如果把網頁所有 Iframe 都預先設定好寬、高,這些 Iframe 就不會產生 reflow。
- 外掛工具區塊:很多外掛工具都是用動態產生,或是一開始設定 display: none,產生內容後再取消隱藏,都會導致 reflow 的現象。如能確定尺寸的話,一開始就先把區塊 DIV 設定寬、高,或是隱藏的方式改為 visibility: hidden,都能有效減少 reflow。
4. 瀏覽器運作的原理
這部分算是補充的內容,如果想要做到完美,那麼必須精確瞭解所有瀏覽器運作的原理,才能進行針對性的效能改善。有興趣的讀者可參考這篇值得推薦的濃縮文章「瀏覽器的渲染原理簡介」,其原文來自於「瀏覽器的工作原理:新式網絡瀏覽器幕後揭秘」。
程式設計師可經由以上這兩篇文章,瞭解 js 應該如何操作,來減少 reflow 的產生。
二、圖片添加尺寸參數
接下來進入實作階段,幫圖片加上尺寸的參數算是很簡單,但又不是那麼簡單的任務。首先,要如何得知一張圖片的實際寬、高的像素值呢?
1. 取得圖片的尺寸
最簡單的方法,將圖片另存新檔 → 用看圖軟體查看尺寸。
只不過圖片數量一多,這個方法的操作步驟繁冗,不是最有效率的方式。
2. 利用開發人員工具
如果熟悉瀏覽器的操作,例如「Chrome 開發人員工具」,使用放大鏡功能,游標移到圖片區塊,就能立即得到圖片尺寸。
以 WFU BLOG 網站 logo 為例,使用此工具的放大鏡後,滑鼠移到圖片即顯示尺寸為 100 x 100 px,如下圖紅框:
3. CSS 設定
A. 單張圖片:使用行內 CSS 即可,例如網站 logo 的圖片 html 新增紅色參數如下──
<img style="width: 100px; height: 100px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizW3s3HghEoobUR5juPl6QpOV-zZR5MQDsHGRlCmAcgGUX7jql6Q19E4Lsd8cBRQeUum9Ltx5luiSMFm1A6s3TzgtH3syX2aDjALB5IaClMtIEd56978kbz60PdGJGjelw-Rk9q2SpP5yG/s100/wfublog-logo-8abeb7.png"/>
B. 多張圖片:如果有多張尺寸一樣的圖片,使用行內 CSS 比較沒效率,可在圖片 html 設定 class,這個 class 的 CSS 參數即可套用到多張圖片──
<img class="wfu_logo" src="圖片1.jpg"/>
<img class="wfu_logo" src="圖片2.jpg"/>
<style>
.wfu_logo {
width: 100px;
height: 100px;
}
</style>
以上
三、實作技巧
看完「二、圖片添加尺寸參數」的說明後,當準備開始在自己的網站實作時,讀者應該就會發現問題來了,而且是令人頭大的問題:
- 舊文章的圖片數量是天文數字,處理不完。
- 新文章的圖片一開始可能無法知道尺寸,要得知尺寸、設定尺寸的過程,是一件很麻煩的事!
1. 處理文章中的圖片
舊文章的處理後續再提,如果是新文章中的圖片,Blogger 平台有個簡單快速的方法可以設定。
使用 Blogger 的文章編輯器 → 切換到 HTML 模式 → 上傳圖片 → 對齊方式選「無」, 完畢後大致會出現以下格式的圖片 html 碼:
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR392KnwvvTFN5os0dEgeN208mb5McPJtB3EeNKjHoDBzeAYFzfgylUV5DXdMM8xruoY2HZV1_XqZU7wb_qL79WSHZketB7MfzO4ygx3YCV8YB9dOHN9JTJAC9Cdddv_P0LE4O5DdPpU5m/s1600/chrome-develop-tool-img-size.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR392KnwvvTFN5os0dEgeN208mb5McPJtB3EeNKjHoDBzeAYFzfgylUV5DXdMM8xruoY2HZV1_XqZU7wb_qL79WSHZketB7MfzO4ygx3YCV8YB9dOHN9JTJAC9Cdddv_P0LE4O5DdPpU5m/s400/chrome-develop-tool-img-size.png"/></a>
接著切換到撰寫模式 → 對著上傳的圖片按下去,會出現下圖選項──
請選擇圖片想要顯示的尺寸,盡量不要選對齊方式(html會非常亂、也會有很多麻煩),然後再切回 HTML 模式,奇妙的事發生了,以下是新的圖片 html 碼:
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR392KnwvvTFN5os0dEgeN208mb5McPJtB3EeNKjHoDBzeAYFzfgylUV5DXdMM8xruoY2HZV1_XqZU7wb_qL79WSHZketB7MfzO4ygx3YCV8YB9dOHN9JTJAC9Cdddv_P0LE4O5DdPpU5m/s1600/chrome-develop-tool-img-size.png" imageanchor="1"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgR392KnwvvTFN5os0dEgeN208mb5McPJtB3EeNKjHoDBzeAYFzfgylUV5DXdMM8xruoY2HZV1_XqZU7wb_qL79WSHZketB7MfzO4ygx3YCV8YB9dOHN9JTJAC9Cdddv_P0LE4O5DdPpU5m/s400/chrome-develop-tool-img-size.png" height="238" width="400" /></a>
請見紅字的參數,Blogger 自動幫我們依寬高比例計算、並加上了圖片尺寸,這樣的設計可以說是幫我們節省了不少麻煩。如果有任何圖片想自動設定尺寸,倒是可以藉助 Blogger 文章編輯器的這項功能!
2. 其他區塊的圖片
網站之中、文章區塊以外的圖片,尺寸通常都是固定的,例如網站 logo、社交按鈕、各種小圖示等等,這些都可經由「二、圖片添加尺寸參數」的流程及技巧,來找出圖片尺寸,並加上 CSS 參數。
3. 小工具的圖片
以「相關文章 V2」為例,可以設定固定長、寬的縮圖,所以不會引起 reflow。
而側邊欄的小工具很多都會使用圖片,例如熱門文章、最新文章、最新留言(的頭像)等等,最好也使用固定的縮圖尺寸,方便設定參數。如果懂 js 的話可自行修改程式碼,將來這幾個小工具出更新版時,也會使用固定縮圖尺寸的參數,來減少 reflow 的機會。
四、其他問題
最後剩下舊文章的圖片尺寸,由於數量龐大並不好處理,最好是能藉由 js 自動批次處理來節省操作時間。下一篇的構想將是利用 Lazy Load 來延遲圖片載入的同時,一併加上圖片尺寸的參數,算是一舉兩得,請讀者靜候。
優化網站效能 系列文章:
感謝WFU大大提供好文~
回覆刪除但如果已經寫好blogger內圖片的CSS樣式:
例如 .post img {max-width: 95%; height: auto;} 等
這樣新文章中的處理方法 雖然能解決瀏覽器 reflow 的問題
不過因為套用整體樣式 多少會變形而犧牲掉圖片的畫質了
期待下一篇出現解決方法 :)