1.浏览器渲染的图层
网上的说法:选择『Show composited layer borders』以后,就能看到有动画3d变换的元素会被一个黄色的边框圈起来,表示放到了一个新的『复合层(composited layer)』中渲染
个人的体会:控制好渲染的图层,解决了我在开发过程中 如果页面内容过多,ios端css3动画出不来的问题(页面整体下拉拉不动)
(这个兄弟跟我的问题类似)
解决办法:开启3D加速 (css中添加 transform:translateZ(0);
)
原理:webkit在绘制页面时会将结构分为各种层,当层足够大时就会变成很大的平铺层。这各一来webkit在每次页面结构发生变化时不需要都渲染整个页面而是渲染对应层了,这对渲染速度来说相当的重要。webkit会给各种层分配一定大小的“备份存储区”在内存里缓存起来,这就是绘制层的上下文,通过这个上下文就可以很容易的实现各种效果(动画,3D变换等),“备份存储区”内存占用大小不仅依层而定,跟设备和显示方式也是有关的,假设这在普通屏幕下是1:1的,但在Retina屏幕下则是1:2的,并且放大时这个量会成倍增加;一张图片是10X10,普通屏幕分配的就是10X10,Retina初始则是20X20。这也表明Retina是更加消耗内存的。当层很大时,意味着“备份存储区”会消耗更大的内存,为了避免这点,webkit并不会绘制一个很大的层来存储一个很大的页面,比如说平铺层则会拆分成很多的块来绘制,即尽占用尽可能小的内存,只是将可视范围内的那部分渲染出来。这就是为什么我们在大页面滚动时会发现下面的内容慢慢显示,向上滚动时上面的内容还慢慢显示的原因。(抄来的)
还有一个小问题:所有安卓机都有,如果页面上有不停的repaint的地方并且页面是分层渲染的而不是一个整体,当页面上的元素发生transform变化的时候,如果该变化,不是一个连续的变化,页面会有渲染的瑕疵。(这个问题貌似网上没有相关的描述,我不知道是不是我搜索的关键字不对,反正没有搜到)该问题对应的场景是安卓机的列表页上,有倒计时在不停的变化,如果下拉一下页面,页面就会渲染混乱,感觉有什么层隐藏在底部一样,而ios没有这个问题,我尝试了将页面做成一个层渲染,就不存在该问题,但是一个层渲染,ios又会有拉不动的问题,最后,我加了一个this.refs.slipDiv.style.webkitTransition = '-webkit-transform 0.2s ease 0s';
使动画线性变化,这样就解决了渲染瑕疵的问题!
总结:这个和PC上的情况完全不同,因为在PC上,由于其高性能的硬件,加上强劲的显卡,使得页面渲染的性能非常之高。而在手机上完全不同,有限的硬件性能,加上没有显卡这类专门处理显示的硬件,使得所有页面渲染的工作都由CPU来执行。加上CPU本身的执行频率有限,就会造成页面渲染缓慢。3D加速非常的牛逼,以前的只知道可以开启gpu加速(图形处理器 英语:Graphics Processing Unit,缩写:GPU),具体更深层次的,也没理解过。现在知道了,还可以在备份存储区,用上缓存。
相关文档地址:
2.部分安卓机webview没有touchend事件
论坛截图:
我自己亲自用田总小米测试的结果:
给我造成的问题:页面滚动的时候,正常的事件触发顺序为touchstart -> touchmove -> touchend ->scroll ,我的小米测试机有时候不触发touchend事件,而我在touchend中添加了滚动条回复位置的方法,方法没执行会造成页面中滚动条错位。
解决办法:论坛给的方法更像做广告的,给了一个花钱用的框架Sencha Touch
,我也没法实验。暂时没有什么有效的解决办法,事件取不到,只能用别的方法处理。
网上看了一个模拟touchend的方法:他的方法是每隔100ms检测两次的滚动条位置是否相同,如果相同,那么就是滚动结束了,我测试了一下,可以模拟touchend事件,而且我的小米手机,滚动的时候,看上去没有卡顿,但是我总感觉这种方法,太牵强了。
我的变通解决办法:在滚动事件监听的方法里,判断如果是安卓机并且滚动到页面的头部,给滚动区域强制恢复位置,测试完了发现效果还不错
1 | if(Tool.isAndroid() && document.body.scrollTop){ |
总结:这个问题很坑爹,除了小米外还有不少安卓机有这个问题,遇到了要特殊对待。
相关文档地址:
3.React使用总结
感觉各个生命周期还是需要熟练掌握,个人体会就如下几点:
shouldComponentUpdate
需要好好的理解一下。返回false就不需要render,默认是返回true。componentWillReceiveProps
container中有一个组件有props接受,该页面所有的组件都会触发这个方法同一个router(#/smOrderListfinish),工程师端列表已完成页面,如果改变页面后面的参数,比如这样:(#/smOrderListfinish?&col=col2&StartDate=2016-11-01&EndDate=2016-12-01&_k=1qampo)。你猜页面会刷新吗?
答案:不会,那如何在一个页面,通过改变url参数,不改变hash值(也就是路由不跳转,而让页面刷新呢)。我们可以手动的修改state,state变化了,页面也就刷新了
其实这段逻辑不容易写,我们要利用好componentWillReceiveProps
里的默认参数nextProps
,我的实现方法:
上面代码在componentWillReceiveProps
里判断前后的path是否相同,如果不同则对state进行操作,从而达到页面内容变化的目的,我在这个项目里不少地方都用了类似的逻辑,这段逻辑是通用的
总结:还是要以官方的API为准
4.chrome TimeLine
60fps是理想值,30-60fps不会卡顿,不过实际中,肯定会有低于30fps的
相关文档地址:
5.app到后台,js不会执行
ios是这样,安卓部分是这样,这种情况会造成页面上的计时器会不准确,解决办法看下面文档:
相关文档地址: