webkit在绘制页面时会将结构分为各种层,当层足够大时就会变成很大的平铺层。这样一来webkit在每次页面结构发生变化时不需要都渲染整个页面而是渲染对应层了,这对渲染速度来说相当的重要。webkit会给各种层分配一定大小的“后备存储器”在内存里缓存起来,这就是绘制层的上下文,通过这个上下文就可以很容易的实现各种效果(动画,3D变换等),“后备存储器”内存占用大小不仅依层而定,跟设备和显示方式也是有关的,假设这在普通屏幕下是1:1的,但在Retina屏幕下则是1:2的,并且放大时这个量会成倍增加;一张图片是10X10,普通屏幕分配的就是10X10,Retina初始则是20X20。这也表明Retina是更加消耗内存的。当层很大时,意味着“后备存储器”会消耗更大的内存,为了避免这点,webkit并不会绘制一个很大的层来存储一个很大的页面,比如说平铺层则会拆分成很多的块来绘制,即尽占用尽可能小的内存,只是将可视范围内的那部分渲染出来。这就是为什么我们在大页面滚动时会发现下面的内容慢慢显示,向上滚动时上面的内容还慢慢显示的原因。
以下则是webkit划分为层绘制的场景:
- 页面主容器永远是独立的平铺层
- 绘制密集型元素时,如<video>, <canvas>
- 应用3D transformations的元素,包括translate3d, rotate3d, translateZ
- 内容被加强时,如Filters, masks, reflections, opacity, transitions, animations
- 某些特殊的情况下也会,如position:fixed, -webkit-overflow-scroll:touch
- 任何在已知层上覆盖的内容
webkit是不会将这么大的层整个分配内存绘制渲染的,所以,只要将滚动区域可视范围的列表项元素缓存起来就解决这个问题了。
解决方法:
1
2
3
4
5
6
7
|
<div class = "J-slider"
style= "width:320px;height:600px" >
<div class = "J-scroller"
style= "width:960px;height:600px;>
<div class=" item "></div>
<div class=" item "></div>
<div class=" item"></div>
</div> </div> |
假如以上结构的多图左右移动查看, J-scroller是一块很大的动画移动层,我们对J-scroller设置了 translate3d(x,y,z) 以及transition 动画,
此时iphone查看移动时会有闪屏现象,因为webkit是不会将J-scroller这么大的层整个分配内存绘制渲染。
这时候我们需要将滚动区域可视范围的列表项item元素缓存起来
1
2
3
|
.item{ -webkit-transform: translate3d(0,0,0);
} |
另外:当translate使用2d而非3d的呈现方式时,我们要设置当前动画移动元素的呈现方式为3d,它的所有子元素背面隐藏
1
2
3
4
5
6
|
.J-scroller{ -webkit-transform-style: preserve-3d;
} .J-scroller item{ -webkit-backface-visibility: hidden;
} |
参考链接: http://www.tuicool.com/articles/rYby6v