SVG精簡壓縮工具svgo簡介和初體驗
來自: http://www.zhangxinxu.com/wordpress/2016/02/svg-compress-tool-svgo-experience/
一、事情的起因
佛家講求因果關系,種什么因,得什么果,比方說種了顆蘋果樹,就會結蘋果。這里,扯到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</pre>
-
單個文件使用舉例:
$ 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
</ul>
這里出現了一個 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>
恩,有種胖妞變靚妹的即視感:
</div>
喔噢,很酷啊,正是自己想要的,而且貌似還可以通過設置讓值保留2位小數,又可以進一步精簡大小,不過現在這樣已經足夠了!
好的,不錯,這就加入項目的豪華午餐陣營!
恭喜你,svgo, 你得到了評委的一致認可!
四、結束語
好像沒什么好說的。今天居然是29號,2月29號,4年等一回的日子。還記得上屆奧運會似乎就在不久前,時間過得快并不是什么好事,說明每天的都是重復的生活,缺少了值得記憶的東西,不知不覺,像個大人一樣了,做事處事,磨礪掉了一般自由隨性,還剩下的那點務必要堅守,要從未來的角度看待現在的自己!
哦,突然想起來,MD今天,哦,不對是昨天庫里太逆天,最后一個半場絕殺,感動得我眼淚嘩嘩,大寫的服,真是服!
嘛。就這些,晚安~
歡迎交流,歡迎閱讀!
本文為原創文章,會經常更新知識點以及修正一些錯誤,因此轉載(圖片請勿直接外鏈)請保留原出處,方便溯源,避免陳舊錯誤知識的誤導,同時有更好的閱讀體驗。
(本篇完)
</div>