一: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这个宏里。
原理说了一大堆,我表示一句也没看明白。不过呢,做为知识的分享者就应该要时时刻刻以最简单明了的说法阐述问题,因此总结如下几点供你们参考:
三:补充内容(待注意)