html页面滑动不流畅,解决页面使用overflow:scroll在移动端iOS系统上滑动出现卡顿的问题...

当在iOS设备上使用overflow: scroll属性的html元素时,可能会遇到滑动卡顿的问题。通过添加-webkit-overflow-scrolling: touch;属性可以启用硬件加速,从而改善滑动体验。然而,这可能导致内存消耗增加。本文深入探讨了这个问题,并介绍了如何通过UIWebOverflowScrollView和硬件加速来解决滚动不流畅的问题。

对某个div或模块使用了overflow:

scroll属性,在iOS系统的手机上浏览时,则会出现明显的卡顿现象。但是在android系统的手机上则不会出现该问题。

通过一个早上的爬虫搜索和与前端开发高手的技术探讨得知以下代码可解决这种卡顿的问题:

-webkit-overflow-scrolling:

touch;

据说是因为这行代码启用了硬件加速特性,所以滑动很流畅。但是这个属性也会相对耗费更多内存。在流畅的滑动效果和耗费内存之间,我选择了前者。

后来深入研究了一下该属性。具体深入点如下:

实际上,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这个宏里。

原理说了一大堆,我表示一句也没看明白。不过呢,作为知识的分享者就应该要时时刻刻以最简单明了的说法阐述问题,所以总结以下几点供大家参考:

从SVN log看,在WebKit 108400版本左右才支持,所以iOS

Safari应该是需要5.0。Android则是在4.0以上支持。

从前端开发的角度讲,只需要知道CSS的属性-webkit-overflow-scrolling是真的创建了带有硬件加速的系统级控件,所以效率很高。

从实际开发的角度讲,采用这样的做法相对是耗更多内存的,最好是在产生了非常大面积的overflow时才应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值