一:Lying人生感悟(可忽略)html
摩西奶奶曾經說過:世界上,最公平和最不公平的,都是時間。別人偷不走它。而你也留不住它。你擁有它,卻不能改變它。光陰裏的艱難或是快樂,它都一一帶走。身處其中的你我,年輕或是衰老,所能作的,就是充分去享用它,享受每個生命時期,收藏每個年齡段帶給你的感動與美好。前端
是的,這句話我也曾經在某個使人刻骨銘心的夜晚對一我的說過。過去了的事情再說起不免讓人有些懷念。既然走不出來又何須再強求本身走出來。因此讓該來的到來,讓不應走的別走,珍惜所擁有的一切期許是最好的選擇……node
二:回到正題(待細看)android
故事背景:最近的一次開發中,使用到了overflow:scroll 屬性來滑動div。信心滿滿的覺得不會出現任何問題,看來仍是太清高自傲了,因而寫下這篇隨筆特此總結一番。ios
若是你對某個div或模塊使用了overflow: scroll屬性,在iOS系統的手機上瀏覽時,則會出現明顯的卡頓現象。可是在android系統的手機上則不會出現該問題。你們不妨能夠分別使用IOS和Android系統的手機瀏覽如下連接或掃描二維碼後滑動文字區域查看該效果(重點是記住iPhone瀏覽時的效果,方便瀏覽後文):http://geek100.com/demo/os.html.web
表示很奇怪會產生這樣的差別,因而卸下行囊、放下面包、拿出電腦、插上網線、雙擊chrome、在輸入欄中默默地敲上baidu.com...大百度(我更習慣性的稱做爲大敗毒,由於它幾乎構成了我學習、工做、生活的所有)。經過一個早上的爬蟲搜索和與前端開發高手的技術探討得知如下代碼可解決這種卡頓的問題:chrome
-webkit-overflow-scrolling: touch;app
嗯,此次收拾好心情、重拾以前唾手可棄的信心(不是節操哦)、利用PP助手謹小慎微地把文件拖入iPhone手機中、當心翼翼地點開頁面、手指輕輕在屏幕上滑動...哇哦,果真滑動流暢了誒。來吧!朋友!不妨拿出IPhone一塊兒感覺這激動的時刻。連接:http://geek100.com/demo/ost.htmloop
聽說是由於這行代碼啓用了硬件加速特性,因此滑動很流暢。可是這個屬性也會相對耗費更多內存。在流暢的滑動效果和耗費內存之間,我選擇了前者。學習
後來深刻研究了一下該屬性。具體深刻點以下:
實際上,Safari真的用了原生控件來實現,對於有-webkit-overflow-scrolling的網頁,會建立一個UIScrollView,提供子layer給渲染模塊使用。建立時的堆棧以下:
Thread 1, Queue : com.apple.main-thread #0 0x00086723 in -[UIScrollView initWithFrame:] () #1 0x004ec3bd in -[UIWebOverflowScrollView initWithLayer:node:webDocumentView:] () #2 0x001f1769 in -[UIWebDocumentView webView:didCreateOrUpdateScrollingLayer:withContentsLayer:scrollSize:forNode:allowHorizontalScrollbar:allowVerticalScrollbar:] () #3 0x01d571bd in __invoking___ () #4 0x01d570d6 in -[NSInvocation invoke] () #5 0x01d5724a in -[NSInvocation invokeWithTarget:] () #6 0x027fb6a1 in -[_WebSafeForwarder forwardInvocation:] () #7 0x027fb8ab in __44-[_WebSafeAsyncForwarder forwardInvocation:]_block_invoke_0 () #8 0x04ac753f in _dispatch_call_block_and_release () #9 0x04ad9014 in _dispatch_client_callout () #10 0x04ac97d5 in _dispatch_main_queue_callback_4CF () #11 0x01d09af5 in __CFRunLoopRun () #12 0x01d08f44 in CFRunLoopRunSpecific () #13 0x01d08e1b in CFRunLoopRunInMode () #14 0x01cbd7e3 in GSEventRunModal () #15 0x01cbd668 in GSEventRun () #16 0x00032ffc in UIApplicationMain () #17 0x00002ae2 in main at /Users/liuhx/Desktop/UIWebView_Research/WebViewResearch/main.mm:16
實際建立的是UIWebOverflowScrollView,它繼承自UIScrollView,聲明爲:
@class DOMNode, UIWebDocumentView, UIWebOverflowContentView, UIWebOverflowScrollListener; @interface UIWebOverflowScrollView : UIScrollView { UIWebDocumentView *_webDocumentView; UIWebOverflowScrollListener *_scrollListener; UIWebOverflowContentView *_overflowContentView; DOMNode *_node; BOOL _beingRemoved; } @property(nonatomic, getter=isBeingRemoved) BOOL beingRemoved; // @synthesize beingRemoved=_beingRemoved; @property(retain, nonatomic) DOMNode *node; // @synthesize node=_node; @property(retain, nonatomic) UIWebOverflowContentView *overflowContentView; // @synthesize overflowContentView=_overflowContentView; @property(retain, nonatomic) UIWebOverflowScrollListener *scrollListener; // @synthesize scrollListener=_scrollListener; @property(nonatomic) UIWebDocumentView *webDocumentView; // @synthesize webDocumentView=_webDocumentView; - (void)setContentOffset:(struct CGPoint)arg1; - (void)_replaceLayer:(id)arg1; - (void)prepareForRemoval; - (void)fixUpViewAfterInsertion; - (id)superview; - (void)dealloc; - (id)initWithLayer:(id)arg1 node:(id)arg2 webDocumentView:(id)arg3; @end
其還有一個子View做爲ContentView,是給WebCore真正用做渲染overflow型內容的layer的容器。UIWebOverflowContentView的聲明爲:
@interface UIWebOverflowContentView : UIView { } - (void)_setCachedSubviews:(id)arg1; - (void)_replaceLayer:(id)arg1; - (void)fixUpViewAfterInsertion; - (id)superview; - (id)initWithLayer:(id)arg1; @end
再往底層跟,都是CALayer的操做。以上兩個類都是UIKit層的實現,須要WebCore有硬件加速的支持纔有實際意義,相關的邏輯被包含在ACCELERATED_COMPOSITING這個宏裏。
原理說了一大堆,我表示一句也沒看明白。不過呢,做爲知識的分享者就應該要時時刻刻以最簡單明瞭的說法闡述問題,因此總結如下幾點供你們參考:
三:補充內容(待注意)