成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何讓 Flutter 應用更好地使用 SVG?

開發 開發工具
本文將帶大家了解 SVG 在 Flutter 應用中的性能問題,分享 UC 瀏覽器內核技術團隊在 Flutter 應用中改進 SVG 應用的探索實踐。

SVG 作為一個強大的矢量圖標準格式,在圖片清晰度的表現力上有著位圖無法比擬的優勢。那么是否 SVG 就是絕對的首選了呢?事實可能并非如此。本文將帶大家了解 SVG 在 Flutter 應用中的性能問題,分享 UC 瀏覽器內核技術團隊在 Flutter 應用中改進 SVG 應用的探索實踐。

例說歷史

在計算機的世界里,很多空間優化都隱藏著計算消耗,比如下面這張色彩和形狀豐富的 4k 圖片(其實也可以是 8k,屏幕夠大就可以看到),壓縮后只有 5kB 大小。[[332770]][[332771]]

??

??

 

 

如果這個 5kB 用 PNG 來存儲的圖片,是下圖這個樣子。

??

??

表現力天差地別。

為了達到類似的清晰度,一般操作系統會協助應用打包時在 UI 資源中歸集多個分辨率的圖片。

??

??

32x32

 

??

??

64x64


 

??

??

256x256

 

 

??

??

1024x1024

 

上面這一個圖標,資源包占用超過 120kB,其中最大的一個版本,運行內存占用在 4MB。

這么看來,SVG 圖片應該是絕對首選吧?

并非如此。在給 Flutter 做 SVG 支持分析之前,開發者可能覺得各個移動系統 API 中沒有提供是個很大缺憾。

而經過光柵化代價數據分析后,也能理解了系統對盲目使用 SVG 帶來問題的擔憂。

比如還是上面這個 SVG 圖片,在驍龍 626 的手機上,Flutter 光柵化到 64x64 的區域需要 34ms,一個 SVG 讓應用與 60 幀流暢度徹底無緣。實測 IPhone X 需要 8ms,只能流暢顯示兩個。

另外補充一點,SVG 或者說矢量圖的應用需求是 UI 扁平化趨勢興起后才出現的。在擬物化的時期,拋開光柵化速度不說,矢量圖在顯示寫實風格的圖標時,缺陷是無法容忍的。比如 doggy,用較激進的追蹤矢量化后(右側),已經數碼感十足,存儲占用也遠超 PNG。

??

??

好在,扁平化的矢量圖在工程推進時,也在有意無意回避前面說的問題,大部分都走簡約風。所以只要避開陷阱,SVG 還是在很多場景可以做到表現優秀的。

應用現狀

Flutter 項目主線沒有支持

Flutter 的基礎組件 Skia 代碼中有 SVG 目錄,但別誤會了,Skia 只有序列化至 SVG 的功能,沒有解碼繪制 SVG 的能力。

框架開發計劃目前也沒有支持的打算:https://github.com/flutter/flutter/issues/1831

OS 也沒有支持的意向

這是可以理解的,因為龐大如 Android 和 iOS 也默認不支持:

大家的共識是,全功能的 SVG 支持工作量不小,還有性能隱患(都是拐著彎提到)。

SVG 的鍋,矢量字體方案不用背

前面 SVG 咨詢,在建議解決方案中,都提到用矢量字體解決。矢量字體:

  • 主流 OS 都自帶的支持。
  • 基本只能單色。
  • 不用依賴 xml。
  • 由于單色輸出,很多圖層繪制疊加等等不可控的性能影響要素都被排除。
  • 系統方便做位圖緩存管理(我們開發者工具后續可以再研究)。

雖然在 SVG 投入不少研究,也不得不承認,字體矢量圖輸出是目前很務實高效的方案。

配合工具流程改進 SVG 應用

SVG 作為一個強大的矢量圖標準格式,還是可以找到合適的應用的。比如多彩圖標,方便熱更新,生產工具對此格式的廣泛支持。

讓 SVG 再次偉大

在 OS 和 runtime 都拋棄 SVG 的情況下,flutter_svg 包毅然然扛起大旗,簡單快捷的給 Flutter 提供了 SVG 渲染解碼的能力,顯示出 Flutter/Dart 不俗的擴展潛能。

flutter_svg 的使用非常簡單,提供和 flutter framework 中 image_provider 類似的接口。下面兩段代碼就是分別顯示來自 asset 和網絡的 SVG 圖片:

SvgPicture.asset( 
'assets/adsmall.svg',
placeholderBuilder: (BuildContext context) => Container(
child: const CircularProgressIndicator()),
),

SvgPicture.network(
'https://raw.githubusercontent.com/dnfield/flutter_svg/master/example/assets/deborah_ufw/new-camera.svg',
placeholderBuilder: (BuildContext context) => Container(
child: const CircularProgressIndicator()),
),

用工具避坑

不能對 SVG 的性能隱患坐視不理。

UC 瀏覽器內核技術團隊開發了一個【資源面板】工具,可以方便地連接 Flutter 應用,實時顯示資源分配的內存,對其中的 SVG 圖片,資源面板提供了預覽和獲取光柵化損耗的功能。

??

??

通過記錄和對比 SVG 在實際移動設備上的光柵化損耗,我們可以方便地識別出有隱患的 SVG 文件,將 SVG 的應用安排妥當。

??

??

通過實際 Rasterization Cost 的對比可以看到,簡約風格的圖標,時間消耗到 16.66ms 來說在驍龍 626 上也還是可以接受的。

實現原理

flutter_svg

flutter_svg 是一個 dart package,提供解析來自 network、asset、memory 等 SVG 的能力。

由于解析結果并不是 ui.Image 這樣的位圖,所以 flutter_svg 并沒有和 ImageCache 協作,而是自己實現了一套 PictureCache , PictureCache 中緩存的是 ui.Picture ,這個類實際是 skia 引擎的 SkPicture Wrapper,二進制方式記錄具體的 SVG 繪制指令。

ui.Picture 類占用的內存不會很大,緩存基本上是為了避免反復 parse xml。

比如 SvgPicture.asset 的構造接口如下:

SvgPicture.asset( 
String assetName, {
Key key,
this.matchTextDirection = false,
AssetBundle bundle,
String package,
this.width,
this.height,
this.fit = BoxFit.contain,
this.alignment = Alignment.center,
this.allowDrawingOutsideViewBox = false,
this.placeholderBuilder,
Color color,
BlendMode colorBlendMode = BlendMode.srcIn,
this.semanticsLabel,
this.excludeFromSemantics = false,
}) : pictureProvider = ExactAssetPicture(
allowDrawingOutsideViewBox == true
? svgStringDecoderOutsideViewBox
: svgStringDecoder,
assetName,
bundle: bundle,
package: package,
colorFilter: _getColorFilter(color, colorBlendMode)),
super(key: key);

SvgPicture 的 _picture,由 pictureProvider 的 stream 通知更新:

void _resolveImage() { 
final PictureStream newStream = widget.pictureProvider
.resolve(createLocalPictureConfiguration(context));
assert(newStream != null);
_updateSourceStream(newStream);
}

pictureProvider 的 stream 由 來自 pictureCache 的 completer 填充 ui.Picture 。

// in PictureProvider<T>.resolve 
stream.setCompleter(
_cache.putIfAbsent(
key,
() => load(key, onError: onError),
),
);

Debug 和 Profile 模式下,通過添加配合代碼,開發者工具可以在 PictureCache 中查詢所有現存的 SvgPicture 。

光柵化時間獲取

光柵化的發起接口是 ui.Picutre.toImage 方法,具體的計時在 rasterizer 線程。

??

??

??

??

補充說明

Android VectorDrawable

Android 提供了一套 VectorDrawable 方案,是一個簡化版的 SVG , 格式和特性不完全兼容,提供轉換工具。從文檔來看,確實是擔心過度復雜的 SVG 影響性能。參考文檔:https://developer.android.com/studio/write/vector-asset-studio

單獨 SVG 位圖緩存優化

目前 Flutter 用的是一次性光柵化輸出每幀的模式,和 chromium 的 cc 按區域構建位圖再合成不同,如果在光柵化輸出時標記 SVG 的 Picture,緩存這部分位圖可以提升幀數,代價當然是內存損耗。

這個功能目前純用 Dart 無法方便實現,因為在 dart.ui 線程中,RenderPicture 無法預見具體的光柵化分辨率。

 

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2018-10-11 09:40:53

前端JavaScript編程語言

2021-02-25 22:17:19

開發技術編程

2019-03-22 14:20:26

管理多云云計算

2013-05-02 14:39:11

iOS開發iOS應用崩潰解決

2015-02-26 09:19:00

2022-09-12 23:53:53

JavaScript條件判斷開發

2020-11-24 12:07:57

阿里云serverless容器

2012-02-08 16:19:09

ibmdw

2012-02-14 12:50:13

ibmdw

2015-08-21 10:38:26

DaaS

2015-11-18 09:56:24

數據中心監控

2014-10-29 09:55:58

程序員代碼

2021-01-28 14:53:19

PHP編碼開發

2011-07-19 09:22:20

活動目錄

2022-05-06 15:58:44

物聯網社區物聯網應用

2015-03-12 15:00:00

編程12條自問更好地編程

2017-10-12 15:20:57

數據中心遷移數據云端

2022-05-05 16:49:12

物聯網社區應急

2012-12-20 09:46:42

應用虛擬化

2023-11-09 11:48:41

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日日夜夜天天综合 | 国产一二区在线 | 日韩欧美在线播放 | 国产精品久久久久久吹潮 | 91免费在线看 | 国内精品视频在线观看 | 欧美日韩国产精品一区 | 玖玖国产精品视频 | 日日操操 | 网站国产 | 一区二区在线视频 | 婷婷福利 | 色黄爽| 国产免费高清 | 91色在线视频 | 激情综合五月天 | 亚洲一区二区日韩 | 亚洲1区 | 午夜一级大片 | 亚洲第一在线 | 亚洲一区二区久久 | 国产精品久久久久久福利一牛影视 | 亚洲 欧美 激情 另类 校园 | 国产激情网 | 国产精品久久久久久久免费大片 | 久久精品手机视频 | 国产69精品久久99不卡免费版 | 亚洲人成一区二区三区性色 | 一级a性色生活片久久毛片波多野 | 国产精品国产三级国产aⅴ原创 | 在线观看视频福利 | 一区二区成人 | 天天射夜夜操 | 国产99热精品 | av性色 | 国产乱xxav| 欧美在线| 国产人成精品一区二区三 | 欧美久久一区二区 | 欧美国产亚洲一区二区 | 色男人的天堂 |