設(shè)計更快的網(wǎng)頁(二):圖片替換
歡迎回到我們?yōu)榱藰?gòu)建更快網(wǎng)頁所寫的系列文章。上一篇文章討論了只通過圖片壓縮實現(xiàn)這個目標(biāo)的方法。這個例子從一開始有 1.2MB 的“瀏覽器脂肪”,然后它減輕到了 488.9KB 的大小。但這還不夠快!那么本文繼續(xù)來給瀏覽器“減肥”。你可能在這個過程中會認(rèn)為我們所做的事情有點(diǎn)瘋狂,但一旦完成,你就會明白為什么要這么做了。
準(zhǔn)備工作
本文再次從對網(wǎng)頁的分析開始。使用 Firefox 內(nèi)置的截圖功能來對整個頁面進(jìn)行截圖。你還需要用 sudo 來安裝 Inkscape:
$ sudo dnf install inkscape
如果你想了解 Inkscape 的用法,F(xiàn)edora 雜志上有幾篇現(xiàn)成的文章。本文僅會介紹一些基本的 SVG 優(yōu)化方法以供 Web 使用。
分析
我們再來用 getfedora.org 的網(wǎng)頁來舉例。
Getfedora 的頁面,對其中的圖片做了標(biāo)記
這次分析以圖形方式完成更好,這也就是它從屏幕截圖開始的原因。上面的截圖標(biāo)記了頁面中的所有圖形元素。Fedora 網(wǎng)站團(tuán)隊已經(jīng)針對兩種情況措施(也有可能是四種,這樣更好)來替換圖像了。社交媒體的圖標(biāo)變成了字體的字形,而語言選擇器變成了 SVG.
我們有幾個可以替換的選擇:
- CSS3
- 字體
- SVG
- HTML5 Canvas
HTML5 Canvas
簡單來說,HTML5 Canvas 是一種 HTML 元素,它允許你借助腳本語言(通常是 JavaScript)在上面繪圖,不過它現(xiàn)在還沒有被廣泛使用。因為它可以使用腳本語言來繪制,所以這個元素也可以用來做動畫。這里有一些使用 HTML Canvas 實現(xiàn)的實例,比如三角形模式、動態(tài)波浪和字體動畫。不過,在這種情況下,似乎這也不是***的選擇。
CSS3
使用層疊式樣式表,你可以繪制圖形,甚至可以讓它們動起來。CSS 常被用來繪制按鈕等元素。然而,使用 CSS 繪制的更復(fù)雜的圖形通常只能在技術(shù)演示頁面中看到。這是因為使用視覺來制作圖形依然要比使用代碼來的更快一些。
字體
另外一種方式是使用字體來裝飾網(wǎng)頁,Fontawesome 在這方面很流行。比如,在這個例子中你可以使用字體來替換“Flavor”和“Spin”的圖標(biāo)。這種方法有一個負(fù)面影響,但解決起來很容易,我們會在本系列的下一部分中來介紹。
SVG
這種圖形格式已經(jīng)存在了很長時間,而且它總是在瀏覽器中被使用。有很長一段時間并非所有瀏覽器都支持它,不過現(xiàn)在這已經(jīng)成為歷史了。所以,本例中圖形替換的***方法是使用 SVG.
為網(wǎng)頁優(yōu)化 SVG
優(yōu)化 SVG 以供互聯(lián)網(wǎng)使用,需要幾個步驟。
SVG 是一種 XML 方言。它用節(jié)點(diǎn)來描述圓形、矩形或文本路徑等組件。每個節(jié)點(diǎn)都是一個 XML 元素。為了保證代碼簡潔,SVG 應(yīng)該包含盡可能少的元素。
我們選用的 SVG 實例是帶有一個咖啡杯的圓形圖標(biāo)。你有三種選項來用 SVG 描述它。
一個圓形元素,上面有一個咖啡杯
<circle
style="opacity:1;fill:#717d82;fill-opacity:1;stroke:none;stroke-width:9.51950836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
id="path36"
cx="68.414307"
cy="130.71523"
r="3.7620001" />
一個圓形路徑,上面有一個咖啡杯
<path
style="opacity:1;fill:#717d82;fill-opacity:1;stroke:none;stroke-width:1.60968435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
d="m 68.414044,126.95318 a 3.7618673,3.7618673 0 0 0 -3.76153,3.76204 3.7618673,3.7618673 0 0 0 3.76153,3.76205 3.7618673,3.7618673 0 0 0 3.76206,-3.76205 3.7618673,3.7618673 0 0 0 -3.76206,-3.76204 z"
id="path20" />
單一路徑
<path
style="opacity:1;fill:#717d82;fill-opacity:1;stroke:none;stroke-width:1.60968435;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
d="m 68.414044,126.95318 a 3.7618673,3.7618673 0 0 0 -3.76153,3.76204 3.7618673,3.7618673 0 0 0 3.76153,3.76205 3.7618673,3.7618673 0 0 0 3.76206,-3.76205 3.7618673,3.7618673 0 0 0 -3.76206,-3.76204 z m -1.21542,0.92656 h 2.40554 c 0.0913,0.21025 0.18256,0.42071 0.27387,0.63097 h 0.47284 v 0.60099 h -0.17984 l -0.1664,1.05989 h 0.24961 l -0.34779,1.96267 -0.21238,-0.003 -0.22326,1.41955 h -2.12492 l -0.22429,-1.41955 -0.22479,0.003 -0.34829,-1.96267 h 0.26304 l -0.16692,-1.05989 h -0.1669 v -0.60099 h 0.44752 c 0.0913,-0.21026 0.18206,-0.42072 0.27336,-0.63097 z m 0.12608,0.19068 c -0.0614,0.14155 -0.12351,0.28323 -0.185,0.42478 h 2.52336 c -0.0614,-0.14155 -0.12248,-0.28323 -0.18397,-0.42478 z m -0.65524,0.63097 v 0.21911 l 0.0594,5.2e-4 h 3.35844 l 0.0724,-5.2e-4 v -0.21911 z m 0.16846,0.41083 0.1669,1.05937 h 2.80603 l 0.16693,-1.05937 -1.57046,0.008 z m -0.061,1.25057 0.27956,1.5782 1.34411,-0.0145 1.34567,0.0145 0.28059,-1.5782 z m 1.62367,1.75441 -1.08519,0.0124 0.19325,1.2299 h 1.79835 l 0.19328,-1.2299 z"
id="path2714"
inkscape:connector-curvature="0" />
你應(yīng)該可以看出,代碼變得越來越復(fù)雜,需要更多的字符來描述它。當(dāng)然,文件中包含更多的字符,就會導(dǎo)致更大的尺寸。
節(jié)點(diǎn)清理
如果你在 Inkscape 中打開了實例 SVG 按下 F2,就會激活一個節(jié)點(diǎn)工具。你應(yīng)該看到這樣的界面:
Inkscape - 激活節(jié)點(diǎn)工具
這個例子中有五個不必要的節(jié)點(diǎn)——就是直線中間的那些。要刪除它們,你可以使用已激活的節(jié)點(diǎn)工具依次選中它們,并按下 Del
鍵。然后,選中這條線的定義節(jié)點(diǎn),并使用工具欄的工具把它們重新做成角。
Inkscape - 將節(jié)點(diǎn)變成角的工具
如果不修復(fù)這些角,我們還有方法可以定義這條曲線,這條曲線會被保存,也就會增加文件體積。你可以手動清理這些節(jié)點(diǎn),因為它無法有效的自動完成?,F(xiàn)在,你已經(jīng)為下一階段做好了準(zhǔn)備。
使用“另存為”功能,并選擇“優(yōu)化的 SVG”。這會彈出一個窗口,你可以在里面選擇移除或保留哪些成分。
Inkscape - “另存為”“優(yōu)化的 SVG”
雖然這個 SVG 實例很小,但它還是從 3.2KB 減小到了 920 字節(jié),不到原有的三分之一。
回到 getfedora 的頁面:頁面主要部分的背景中的灰色沃羅諾伊圖,在經(jīng)過本系列***篇文章中的優(yōu)化處理之后,從原先的 211.12 KB 減小到了 164.1 KB.
頁面中導(dǎo)出的原始 SVG 有 1.9 MB 大小。經(jīng)過這些 SVG 優(yōu)化步驟后,它只有 500.4 KB 了。太大了?好吧,現(xiàn)在的藍(lán)色背景的體積是 564.98 KB。SVG 和 PNG 之間只有很小的差別。
壓縮文件
$ ls -lh
insgesamt 928K
-rw-r--r--. 1 user user 161K 19. Feb 19:44 grey-pattern.png
-rw-rw-r--. 1 user user 160K 18. Feb 12:23 grey-pattern.png.gz
-rw-r--r--. 1 user user 489K 19. Feb 19:43 greyscale-pattern-opti.svg
-rw-rw-r--. 1 user user 112K 19. Feb 19:05 greyscale-pattern-opti.svg.gz
這是我為可視化這個主題所做的一個小測試的輸出。你可能應(yīng)該看到光柵圖形——PNG——已經(jīng)被壓縮,不能再被壓縮了。而 SVG,它是一個 XML 文件正相反。它是文本文件,所以可被壓縮至原來的四分之一不到。因此,現(xiàn)在它的體積要比 PNG 小 50 KB 左右。
現(xiàn)代瀏覽器可以以原生方式處理壓縮文件。所以,許多 Web 服務(wù)器都打開了 mod_deflate (Apache) 和 gzip (Nginx) 模式。這樣我們就可以在傳輸過程中節(jié)省空間。你可以在這兒看看你的服務(wù)器是不是啟用了它。
生產(chǎn)工具
首先,沒有人希望每次都要用 Inkscape 來優(yōu)化 SVG. 你可以在命令行中脫離 GUI 來運(yùn)行 Inkscape,但你找不到選項來將 Inkscape SVG 轉(zhuǎn)換成優(yōu)化的 SVG. 用這種方式只能導(dǎo)出光柵圖像。但是我們替代品:
- SVGO (看起來開發(fā)過程已經(jīng)不活躍了)
- Scour
本例中我們使用 scour
來進(jìn)行優(yōu)化。先來安裝它:
$ sudo dnf install scour
要想自動優(yōu)化 SVG 文件,請運(yùn)行 scour
,就像這樣:
[user@localhost ]$ scour INPUT.svg OUTPUT.svg -p 3 --create-groups --renderer-workaround --strip-xml-prolog --remove-descriptive-elements --enable-comment-stripping --disable-embed-rasters --no-line-breaks --enable-id-stripping --shorten-ids
這就是第二部分的結(jié)尾了。在這部分中你應(yīng)該學(xué)會了如何將光柵圖像替換成 SVG,并對它進(jìn)行優(yōu)化以供使用。