本文對比的是 UIWebView、WKWebView、flutter_webview_plugin(在iOS中使用的是WKWebView)的加載速度,內(nèi)存使用情況。

創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的豐順網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
測試網(wǎng)頁打開的速度,只需要獲取 WebView 在開始加載網(wǎng)頁和網(wǎng)頁加載完成時(shí)的時(shí)間戳,時(shí)間戳的差即為打開網(wǎng)頁的時(shí)間
為了使差異更明顯,我們選擇較為復(fù)雜的 新浪首頁 進(jìn)行加載的對比,為了減小網(wǎng)絡(luò)對加載速度的影響,我們讓手機(jī)連接同一個(gè)網(wǎng)絡(luò),分別進(jìn)行 10 次測試然后取平均值,另外,我們需要關(guān)閉 WebView 的緩存,防止緩存對加載速度產(chǎn)生影響
下面使筆者進(jìn)行 10 次測試所得到的數(shù)據(jù)
結(jié)果讓我有點(diǎn)驚訝,一直以為 WKWebView 會是個(gè)王者。結(jié)果看,速度上 WKWebView 略慢一點(diǎn),不過總體差異不大(該結(jié)果僅僅是測試新浪的結(jié)果,僅供參考啦)
在這里,筆者又加了一個(gè)測試,嘗試記錄從 viewController 的 viewDidLoad 到 webview 的 didFinish 時(shí)間,測試了新浪的數(shù)據(jù),如下:
UIWebViewA : 4970、3808、3815、4250、3556 avg(4079.8) (加載完所有頁面)
UIWebViewB : 4103、3124、3070、3256、2835 avg(3277.6)(加載sina完畢)
WKWebView : 3672、3032、2892、2912、2739 avg(3049.4)
flutter_webView : 4532、3901、4310、3496、3378 avg(3923.4)
其中可以看到,webView 有兩行,UIWebViewB 的數(shù)據(jù)就是加載 sina 主站的時(shí)間;UIWebViewA 的數(shù)據(jù)是因?yàn)樵诩虞d完 sina 主站之后,新浪又加載了一個(gè) ,所以導(dǎo)致總時(shí)間延長,不過即使按照 UIWebViewB 的數(shù)據(jù)來比較,也是 wkWebView 略勝一籌。
此處可以看出 flutter_webView 使用的是 wkwebView,所以它吃虧的主要原因是 flutter 包了一層。
結(jié)論:
速度(didStart - didFinish) UIWebView flutter_webview WKWebView
速度(viewDidLoad - didFinish)WKWebView UIWebView flutter_webview
這里查看內(nèi)存使用的是 xcode 的 debug session 中的 memory。
首先看之前測試時(shí),連續(xù)打開十次新浪的內(nèi)存情況
接著我們在看一下打開淘寶首頁的內(nèi)存情況
從圖上可以看出,WKWebView 在內(nèi)存方面有很大的優(yōu)勢啊,UIWebView 的內(nèi)存是真的傷啊,然后 debug 看了一下 flutter_webView,他使用的就是原生的 webView 。
他相比較原生 WKWebView 的內(nèi)存開銷稍大一點(diǎn),從測試表現(xiàn)來看,一般大個(gè) 30 MB 左右。
結(jié)論:內(nèi)存 WKWebView flutter_webview UIWebView
可以在 html5test 中對瀏覽器的兼容性進(jìn)行評分,通過測試發(fā)現(xiàn)得分分別如下
因?yàn)?flutter 里使用的就是 WK,所以和原生的 WKWebView 一樣都是 444 分,比 UIWebView 的 437 略勝一籌
結(jié)論:兼容性 WKWebView = flutter_webview UIWebView
UIWebView : 速度相比較 WKWebView 稍快一點(diǎn),但是內(nèi)存是一大硬傷,所以只要條件允許,就不推薦使用了
WKWebView : 速度略慢一點(diǎn),不過差別不大,總體可以接受。是比UIWebView更好的選擇,推薦使用。
flutter_webView_plugin :在iOS中使用的就是原生的WKWebView,所以總體和 native WKWebView 表現(xiàn)差不多。如果是混編項(xiàng)目中,因?yàn)樗话艘粚樱皂撁婕虞d上存在一定的劣勢,所以混編項(xiàng)目中仍然推薦使用 WKWebView。不過如果從多端考慮、以及項(xiàng)目可遷移等,那么使用也未嘗不可,就是維護(hù)成本要增加一些,需要維護(hù)兩套 webView。這個(gè)就需要根據(jù)自己的情況自己取舍了。
Flutter是谷歌公司推出的跨終端的開發(fā)框架,支持Android、iOS和WEB終端。1.0版在2018年12月5日發(fā)布,目前的最新版本是1.5,它采用的開發(fā)語言是Dart,Dart也是谷歌開發(fā)的計(jì)算機(jī)編程語言,語法類似C,是編譯型語言:
hello world例子,打印字符串“Hello World!”:
1、沒有橋接層
React Native、Weex等技術(shù)都是跨終端的框架,然而性能跟原生App存在很大差距。這是由于它們的工作原理決定的:
React Native、Weex等技術(shù)多了一個(gè)橋接層,所以界面渲染會慢一些,由于UI渲染非常頻繁,想要不卡頓,基本上比較難,性能和用戶體驗(yàn)跟原生代碼有差距。而這恰恰是Flutter的優(yōu)勢所在:
Dart可以被編譯成不同平臺的本地代碼,讓Flutter不通過橋接層直接跟平臺通信,自然性能會快一些。
2、編譯執(zhí)行
JavaScript是解釋執(zhí)行的,Dart是編譯執(zhí)行的,性能誰好一目了然。
3、Flutter Engine虛擬機(jī)
Flutter是依靠Flutter Engine虛擬機(jī)在iOS和Android上運(yùn)行的,F(xiàn)lutter Engine使用C/C++編寫,開發(fā)人員通過Flutter框架直接和API在內(nèi)部進(jìn)行交互,所以具有輸入低延遲和UI渲染高幀速率的特點(diǎn)。除了這特點(diǎn)之外,F(xiàn)lutter還提供了自己的小部件,F(xiàn)lutter小部件是使用從React獲取靈感的現(xiàn)代框架構(gòu)建的。 中心思想是您使用小部件構(gòu)建UI。
窗口小部件根據(jù)其當(dāng)前配置和狀態(tài)描述了它們的視圖。 當(dāng)窗口小部件的狀態(tài)發(fā)生更改時(shí),窗口小部件會重建其描述,框架將根據(jù)前面的描述進(jìn)行區(qū)分,以確定底層呈現(xiàn)樹從一個(gè)狀態(tài)轉(zhuǎn)換到下一個(gè)狀態(tài)所需的最小更改。可以直接在OS平臺提供的畫布上進(jìn)行描繪,也就是一些核心類庫直接放到虛擬機(jī)里面,調(diào)用起來更快。
從它的系統(tǒng)結(jié)構(gòu)可以看出,類似安卓的ART(Android Run Time)虛擬機(jī),同樣采用AOT(Ahead of TIme)技術(shù),會在APP安裝時(shí)就編譯成機(jī)器語言,不再解釋執(zhí)行,從而優(yōu)化了APP運(yùn)行的性能。
4、自帶渲染引擎
Flutter使用谷歌自己的Skia渲染引擎,而Android系統(tǒng)自帶Skia引擎,iOS平臺上Flutter也會把Skia引擎打包到APP中,從而實(shí)現(xiàn)了高效渲染。而React Native通過橋接層訪問原生UI,操作頻繁就容易出性能問題。
綜合所述,F(xiàn)lutter 是性能最接近原生代碼 的一種開發(fā)框架,未來也會是構(gòu)建谷歌Fuchsia應(yīng)用的主要方式,前途不可限量,唯一的問題就是需要學(xué)習(xí)一門新的語言:Dart,而有Java或者C#語言基礎(chǔ)的程序員會比較容易學(xué)習(xí)。
Flutter只是 谷歌的移動(dòng) UI 框架,在Android開發(fā)中,你可以理解為 嵌套在activity里面的一個(gè)view即可。
目前有純flutter開發(fā),還有 flutter,原生混合開發(fā) 兩種模式。。
flutter與原生通信主要有三種方式:MethodChannel、EventChannel、BasicMessageChannel,這三種方式均各有適用的場景:MethodChannel用于native與flutter的方法調(diào)用,EventChannel用于native單向的向flutter發(fā)送廣播消息,BasicMessageChannel用于native與flutter之間的消息互發(fā)。
MethodChannel用于雙方之間的方法互調(diào),使用步驟是:
1.創(chuàng)建一個(gè)MethodChannel對象,傳入MethodChannel名稱。
2.使用setMethodHandle對對方調(diào)用自己的方法進(jìn)行監(jiān)聽,通過回調(diào)中的MethodCall對象方法名判斷、獲取方法參數(shù),并且返回調(diào)用結(jié)果。
3.使用invokeMethod來調(diào)用對方的方法,可傳入方法名,方法參數(shù),以及監(jiān)聽對方的回調(diào)結(jié)果。
以下是示例:
需要注意的是,MethodChannel的名稱需要雙方保持一致,否則就不是同一個(gè)MethodChannel了。另外這里的方法調(diào)用并不是像Java里面反射那樣去先找到class示例對象再解析到相應(yīng)的方法,而是將雙方互發(fā)的消息包裝成了MethodCall對象,拿到這個(gè)對象后通過MethodCall里面的方法名去判斷要做什么操作,并不是直接就調(diào)用了自身(native或flutter)相對應(yīng)的方法。具體要做什么操作、調(diào)用什么方法還是得自己去調(diào)用和實(shí)現(xiàn)。
EventChannel適用于native向flutter發(fā)送廣播消息,只是單向的消息發(fā)送,native發(fā),flutter收,返過來flutter并不能向native發(fā)送消息。例如native可將定位數(shù)據(jù)不斷的報(bào)給flutter,或者錄像數(shù)據(jù)等等,所有基于原生能力產(chǎn)生的數(shù)據(jù)都可以通過EventChannel進(jìn)行發(fā)送。
步驟:
1.創(chuàng)建一個(gè)EventChannel對象,傳入EventChannel名稱。
2.flutter端調(diào)用receiveBroadcastStream進(jìn)行廣播消息注冊,傳入arguments參數(shù)即為廣播名稱,此參數(shù)是告訴native端你要接受的廣播類型,判別是什么廣播發(fā)送的數(shù)據(jù)。
2.native調(diào)用setStreamHandler方法進(jìn)行廣播消息監(jiān)聽,onListen回調(diào)里會有一個(gè)arguments參數(shù),這里及為flutter注冊的廣播類型,若flutter端沒有注冊,則native端不會收到這個(gè)回調(diào),也就無法進(jìn)行消息發(fā)送。收到flutter端的廣播注冊后,根據(jù)arguments可判斷廣播類型,然后根據(jù)EventChannel.EventSink來進(jìn)行消息發(fā)送,EventSink.success()即可將消息發(fā)送給flutter端。
3.flutter進(jìn)行廣播注冊會返回一個(gè)streamSubscription類型的對象,該對象可以進(jìn)行消息的停止,native可在onCancel回調(diào)里面收到。
示例如下:
BasicMessageChannel就是比較常用的消息互發(fā),使用步驟如下:
1.創(chuàng)建BasicMessageChannel對象,傳入BasicMessageChannel名稱。還需傳入編解碼方式(可以自己實(shí)現(xiàn)),系統(tǒng)提供了一些列的編解碼方式,后續(xù)會介紹到。
2.使用setMessageHandler方法進(jìn)行消息監(jiān)聽,也可進(jìn)行回復(fù)。
3.使用send方法進(jìn)行消息發(fā)送。
無論哪種方式的消息傳遞,最終都是將自定義數(shù)據(jù)轉(zhuǎn)化為二進(jìn)制數(shù)據(jù)進(jìn)行傳遞,flutter提供的編解碼方式分為MethodCodec和MessageCodec兩種,EventChannel和MethodChannel使用的就是MethodCodec,BasicMessageChannel使用的是MessageCodec。MethodCodec其實(shí)就是在MessageCodec的基礎(chǔ)上將數(shù)據(jù)包裝了一下,使其轉(zhuǎn)化為MethodCall對象方便使用。
MethodCodec源碼:
MethodCodec提供了兩種方式:JSONMethodCodec和StandardMethodCodec,前一種就是JSON和MethodCall對象之間的互轉(zhuǎn),后一種則是根據(jù)傳入的數(shù)據(jù)基本類型(String,Integer等)來進(jìn)行互轉(zhuǎn)。
MessageCodec則提供了四種方式,如下圖,具體就不詳細(xì)講述了,看看名字就知道是怎么回事,可以直接去看源碼。最常用和默認(rèn)的就是StandardMessageCodec方式。
從上面的使用方式可以看出,每一種Channel在創(chuàng)建的時(shí)候都需要傳遞一個(gè)BinaryMessenger,這個(gè)接口可以在FlutterEngine里面拿到,因此需要在FlutterActivity里面實(shí)現(xiàn)configFlutterEngine方法里面重寫這個(gè)方法。FlutterActivity在attach FlutterEngine之后就會調(diào)用這個(gè)configFlutterEngine方法,通過flutterEngine.getPlugins().add(FlutterPlugin)方法可以FlutterPlugin的回調(diào)方法里進(jìn)行數(shù)據(jù)的初始化和銷毀工作。如下圖
這個(gè)回調(diào)方法里的FlutterPluginBinding提供了一些我們可能會用到的對象,如下:
本文標(biāo)題:flutter是原生的簡單介紹
新聞來源:http://chinadenli.net/article2/dsegooc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站建設(shè)、全網(wǎng)營銷推廣、網(wǎng)站排名、網(wǎng)站制作、品牌網(wǎng)站設(shè)計(jì)、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)