by zhangxinxu from http://www.zhangxinxu.com
本文地址:http://www.zhangxinxu.com/wordpress/?p=5278
一、事情的起因
佛家講求因果關係,種什麼因,得什麼果,比方說種了顆蘋果樹,就會結蘋果。這裏,扯到SVG的精簡壓縮也是有原因的,前年有分享過“PSD小圖標變身SVG Sprites/font-face歷險記”,其中展示了我處理SVG比較重要的一步,就是對設計師PSD源文件中的圖標路徑進行重新處理。在沒有對設計師進行分享培訓之前,有些細節可能就不會注意,例如,圖形喜歡用路徑疊加實現,而不是實實在在地勾勒出來;或者PSD看上去是好的,但是放大個100倍,就會發現,路徑的轉角和邊緣都沒對上。此時如果直接SVG,一是SVG文件大小大,二是最終的圖像可能不是我們想要的。因此,需要在Adobe Illustrator中重新處理下,至少我是使用的這個軟件。
有小夥伴可能會疑問:設計師自己挖的坑就讓他自己去種蘋果樹好了,你佛光普照去幫忙光合作用幹什麼呢?
佛約:我不入地獄輸入地獄。大家都聽過這句話吧,所以,我們再看上面的疑問,怎麼樣,是不是聽之有理,實則差矣!我呸……甩自己一個嘴巴子,“差”它個鬼大頭……
“我不入地獄輸入地獄”這種騙傻子自我安慰的話你也信,偶爾幫幫設計師同事那是可以的,搞搞關係以後有糖吃,雖然新郎不是你;但是,每每都是你來幫設計師修修補補設計失誤,看上去是個好人,實際上,是拉低了整個團隊的效率,你的時間應該用在更大價值的事情上。
當然,並不是要你直接撒手不管,而是直接授之以漁,你要做的事情,是好好地準備一次分享培訓,在例會的時候給各位設計師GGMM科普下,首先SVG前程似錦,大家瞭解下面的技能以後好混飯吃;其次,大家作圖要多多留心,路徑細節,少用錨點;最後,傳授AI處理細節和SVG導出大法。然後,把導出SVG的工作全部交給設計師同事,設計師玩AI很多年了,比你前端半吊子要強很多,效率也會高很多,物盡其用。身爲前端的我們,就要做前端應該做的事情,什麼呢,就是對設計師給我們的初稿SVG進行web化精簡,當然是通過技術手段。
爲何需要精簡呢?因爲,很多矢量編輯器,或者類似AI這樣的矢量軟件,導出來的SVG文件都會有很多其他冗餘信息,舉個例子,下面截圖框框的這些鬼:
雖然icomoon.io這樣的在線平臺自動精簡。
但是,1. 如果我們想要直接使用SVG文件怎麼辦?2. SVG文件需要頻繁改動怎麼辦,每次都上傳一邊再下載很煩的?3. 你保證其他同事其他團隊也樂於使用這些平臺,而不是直接根植於項目中?
考慮到這些點,我們有必要在本地有一個可以方便對SVG進行精簡的工具,最好,AI保存好,直接就出來精簡版。有嗎?有,就是本文要介紹的svgo, 精挑細選,業界比較認可,大家比較喜歡的SVG處理工具。
二、svgo簡介
項目地址:https://github.com/svg/svgo, 目前4000+星星~ 隨着SVG的高歌猛進,以後一定會平穩增加。
svgo是SVG O
ptimizer的簡寫,不過,我似乎更喜歡理解爲SVG, go! 這是一個基於Nodejs的SVG文件優化工具。
爲什麼需要?
因爲SVG文件,尤其從各種變假期導出的SVG,通常包含大量的無用信息,例如編輯器源信息,註釋,因此元素,默認或者非最優值,以及其他一些不會影響渲染結果的可以移除或轉換的內容。
能做什麼?
SVGO基於插件模式構建,基本上所有的優化都是一個分離的插件。
目前有:
- [ cleanupAttrs ] 清除換行,結束符以及重複空格
- [ removeDoctype ] 刪除文檔聲明
- [ removeXMLProcInst ] 刪除XML處理指令
- [ removeComments ] 刪除註釋
- [ removeMetadata ] 刪除
<metadata>
源信息 - [ removeTitle ] 刪除
<title>
標題(默認禁用) - [ removeDesc ] 刪除
<desc>
描述 (默認只有desc
元素無意義的時候) - [ removeUselessDefs ] 刪除
<defs>
元素如果沒有id
- [ removeEditorsNSData ] 刪除編輯器的命名空間,元素和屬性
- [ removeEmptyAttrs ] 刪除空屬性
- [ removeHiddenElems ] 刪除隱藏元素
- [ removeEmptyText ] 刪除隱藏文本元素
- [ removeEmptyContainers ] 刪除空的容器元素
- [ removeViewBox ]如果可以,刪除
viewBox
屬性(默認進行) - [ cleanUpEnableBackground ] 如果可以,刪除
enable-background
屬性 - [ minifyStyles ] 使用CSSO最小化元素的
<style>
內容 - [ convertStyleToAttrs ] 轉換樣式爲屬性值
- [ convertColors ] 轉換顏色(從
rgb()
到#rrggbb
, 從#rrggbb
到#rgb
) - [ convertPathData ] 將路徑數據轉換爲的相對路徑和絕對路徑中簡短的那一個,過濾無用的分隔符,智能四捨五入以及其他很多處理
- [ convertTransform ] 合併多個transforms爲一個, 轉換矩陣爲短命名,以及其他很多處理
- [ removeUnknownsAndDefaults ] 刪除未知的元素內容和屬性,刪除值爲默認值的屬性/li>
- [ removeNonInheritableGroupAttrs ] 刪除不可基礎組的”presentation”屬性
- [ removeUselessStrokeAndFill ] 刪除無用的
stroke
和fill
屬性 - [ removeUnusedNS ] 刪除沒有使用的命名空間聲明
- [ cleanupIDs ] 刪除沒有使用或者壓縮使用的IDs
- [ cleanupNumericValues ] 數值四捨五入提高精度, 刪除默認的’px’單位
- [ moveElemsAttrsToGroup ] 移動元素屬性們到外面包裹的組元素上
- [ moveGroupAttrsToElems ] 移動一些組屬性到內容元素上
- [ collapseGroups ] 合併無用的組
- [ removeRasterImages ] 刪除點陣圖像(默認禁用)
- [ mergePaths ] 合併多個路徑爲一個
- [ convertShapeToPath ] 轉換一些基本圖形爲路徑
- [ sortAttrs ] 元素屬性排序使其像詩歌一樣易讀(默認禁用)
- [ transformsWithOnePath ] 通過裏面一條路徑實現transforms, 真實寬度剪裁, 垂直居中對齊以及SVG縮放拉伸(默認禁用)
- [ removeDimensions ] 如果
viewBox
就是當下尺寸限定,刪除width
/height
屬性(默認禁用) - [ removeAttrs ] 通過正則刪除屬性 (默認禁用)
- [ addClassesToSVGElement ] 添加類名給外面的
<svg>
元素 (默認禁用) - [ removeStyleElement ] 刪除元素的
<style>
(默認禁用)
如何使用?
首先是安裝,連我都駕輕就熟了,如下:
$ [sudo] npm install -g svgo
使用:
svgo [OPTIONS] [ARGS] Options: -h, --help : Help 幫助 -v, --version : Version版本 -i INPUT, --input=INPUT : 輸入的文件, "-" 爲標準輸入 -s STRING, --string=STRING : 輸入SVG數據字符串 -f FOLDER, --folder=FOLDER : 輸入的文件夾,會優化與重寫所有的*.svg文件 -o OUTPUT, --output=OUTPUT : 輸入的文件或文件夾 (默認同輸入), "-" 標準輸出 -p PRECISION, --precision=PRECISION : 設置數字的小數部分,重寫插件參數 --config=CONFIG : 配置文件擴展或替換默認設置 --disable=DISABLE : 根據名字禁用插件 --enable=ENABLE : 根據名字開啓插件 --datauri=DATAURI : 輸入文件以Data URI字符串形式(base64, URI encoded or unencoded) -q, --quiet : 僅輸出錯誤信息,不包括正常狀態消息 --pretty : 讓SVG漂亮的打印 --show-plugins : 顯示可用和存在的插件 Arguments: INPUT : 別名 --input OUTPUT : 別名 --output
單個文件使用舉例:
$ svgo test.svg
或者:
$ svgo test.svg test.min.svg
使用STDIN / STDOUT(標準輸入輸出):
$ cat test.svg | svgo -i - -o - > test.min.svg
文件夾舉例:
$ svgo -f ../path/to/folder/with/svg/files
或者:
$ svgo -f ../path/to/folder/with/svg/files -o ../path/to/folder/with/svg/output
使用字符串:
$ svgo -s '<svg version="1.1">test</svg>' -o test.min.svg
或者甚至是Data URI base64:
$ svgo -s 'data:image/svg+xml;base64,…' -o test.min.svg
SVGZ使用:
從
.svgz
到.svg
:$ gunzip -c test.svgz | svgo -i - -o test.min.svg
從.svg到.svgz:
$ svgo test.svg -o - | gzip -cfq9 > test.svgz
帶操作界面的GUI – svgo-gui
- 作爲web app – SVGOMG
- 作爲Nodejs模塊 – examples
- 作爲Grunt任務 – grunt-svgmin
- 作爲Gulp任務 – gulp-svgmin
- 作爲Mimosa模塊 – mimosa-minify-svg
- 作爲OSX文件夾Action – svgo-osx-folder-action
- 作爲webpack loader – image-webpack-loader
這裏出現了一個svgz
格式的文件,這是什麼鬼呢?實際上是SVG的gzip壓縮文件,Illustrator是可以直接導出的,如下示意:
根據我的測試,Chrome瀏覽器是可以直接打開的,FireFox瀏覽器不行(FireFox 44),直接下載,而IE11瀏覽器是個大白板,一看控制檯,報錯了:
雖然svgz的壓縮比很厲害,是真正意義上的壓縮,但是,實際上,應用價值並不大,因爲類似JS, CSS字符集類型文本文件,可以通過服務器開啓gzip實現傳輸,SVG也在其中,SO, …
三、svgo初體驗
看上去很厲害,我就先自己試用下,看看是不是用來解決自己的需求的。如下代碼截圖:
就是所有SVG精簡到另外一個平級的名爲output的文件夾,於是乎,得到:
從精簡效率來看,很驚人,有50%~60%的精簡率。
拿其中一個SVG代碼(就是svgz示意的鉤鉤)前後對比下吧:
<?xml version="1.0" encoding="utf-8"?> <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="圖層_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="200px" height="200px" viewBox="0 0 200 200" enable-background="new 0 0 200 200" xml:space="preserve"> <path fill="#FFFFFF" d="M147.566,67.575c-3.979-3.24-4.355-3.337-8.9-5.64c-2.043-1.043-5.057,1.646-6.529,3.636L92,117.73 L65.85,83.972c-1.478-1.988-4.205-2.72-6.25-1.782c-4.658,2.408-4.19,2.327-8.168,5.467c-1.817,1.466-1.932,4.082-0.456,6.065 c0,0,28.183,36.5,31.592,40.896c5,6.274,14.09,5.965,18.864,0c3.521-4.498,46.59-61.078,46.59-61.078 C149.499,71.55,149.385,68.937,147.566,67.575z"/> </svg>
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 200 200"><path fill="#FFF" d="M147.566 67.575c-3.98-3.24-4.355-3.337-8.9-5.64-2.043-1.043-5.057 1.646-6.53 3.636L92 117.73 65.85 83.972c-1.478-1.988-4.205-2.72-6.25-1.782-4.658 2.408-4.19 2.327-8.168 5.467-1.817 1.466-1.932 4.082-.456 6.065 0 0 28.183 36.5 31.592 40.896 5 6.274 14.09 5.965 18.864 0 3.52-4.498 46.59-61.078 46.59-61.078 1.477-1.99 1.363-4.603-.456-5.965z"/></svg>
恩,有種胖妞變靚妹的即視感:
喔噢,很酷啊,正是自己想要的,而且貌似還可以通過設置讓值保留2位小數,又可以進一步精簡大小,不過現在這樣已經足夠了!
好的,不錯,這就加入項目的豪華午餐陣營!
恭喜你,svgo, 你得到了評委的一致認可!