浅谈移动前端性能优化


其实,Html5相比原生App的开发有不少诱人的方面。css

其一:可快速迭代。 最简单最直接的一个:IOS程序每次上传都须要经过漫长的审核时间,若是赶时间的话这是个问题,并且耐心等待以后未必就能获得一个咱们想要的结果,审核不通也不是不可能。Html5开发完成以后也不用再次上传审核。(若与原生程序有交互变动,此项无效)html

其二:跨平台。Html跨平台的特性早已不是一天两天的事了。IOS开发完成的同时,Android也基本完成。开发效率和成本上相比原生应用确实有较明显的优点。前端

其三:转发率高。如今打开微信朋友圈就能看到各类分享。如:文章分享,产品分享,XX店铺等。经过链接转发能够实现快速分享,提升流量。css3

谈完优点,再说说自身经历。本是一名老老实实的C#程序员,没事就学习各类程序优化(sql为主)的我在几个月前忽然转向移动网页开发。在一个不算小的团队里前端工程师是一枚传统前端工程师。除能完成简单的手机布局外其余一窍不通,因而乎关于JavaScript、前端性能优化等各类重担都落到了我这里。因为前端所完成的仅仅是以html的形式展示出效果图的模样,不多涉及到性能问题。因而漫长的学习之路由此开始了。程序员

究竟什么样的页面是须要优化的页面?

一、页面上下滑动时感受卡顿不流畅或是基本不动;web

二、动画效果卡顿,看上去感受一帧一帧的跳动;sql

简单点说,就是感受卡。也许iphone6不卡可是iphone4上会卡,也许iphone上不卡三星上感受卡、魅族、小米、华为、联想?国内屌丝机各有个的长相各有各的特点,好比魅族的MX,其余手机都很正常的时候它就卡。Html兼容一直都不是一件容易的事。chrome

上述问题该如何破?

解决问题的关键在于找到问题的所在。砍柴还得有装备,工具很重要。之前用chrome,是由于感受这货比较好使(直到放弃多年来一直钟爱的IE)。几个月前才发现这是一个调试工具也很好使的浏览器(简直就是神器)。其实关于html性能问题,不少博客上都有解释重绘这个事。下面主要谈谈如何用chrome鉴别重绘元素。canvas

打开chrome,开启开发者工具(F12)。打开模拟器,并选择须要模拟的设备,在Console中选择Rendering 选中第一条(Show paint rectangles)。若打开开发者工具后没看见下方Console这块能够按下Esc。浏览器

完成上述操做后,请将视线移动到左侧网页上的绿色矩形框上。

ps:一直都很喜欢淘宝的广告,创意从未间断过。

这个绿色框就是浏览器重绘的部分。这个框越大,说明重绘的区域也就越大。重绘并没什么问题,这很正常,不正常的是大面积重绘,好比上图中的时间跳动,若是仅仅是时间那个区域重绘并无什么问题,要是整个页面都一直闪着个绿框框那就完蛋了。为什么大面积重绘会出现性能问题,这个还得从浏览器渲染上谈起。那是一个很长的故事,有兴趣的朋友能够找些资料看看。简单的举例就是,浏览器把html文档解析成网页展示到咱们面前,其中间是一个“漫长”的过程。再载入文档以后须要对html进行分割、读取并计算其样式大小、而后进行图层绘制、合并图层等一系列操做。整个过程其实使用最多的部件是CPU和GPU。

重绘的面积大小和回流(reflows)有关,关于回流其实能够这样理解,当改变一个元素后对其它节点元素产生影响。就如同可石子投入水中引发的波纹同样,波纹所到之处基本都会有所影响。而在Html中子节点的变化会引发祖先的回流,同时也会影响到部分兄弟节点,大部分的回流将致使页面的从新渲染。那么如何下降回流,减少重绘面积呢?淘宝时间不也只更新了一小块么!这里提供两种方法:

一、使用 position 属性的 fixed 值或 absolute 值。

二、建立独立的Layer(层) (为避免和div(层)产生混淆文中尽可能同一使用Layer) 。

继续看淘宝:

第一种方法已经很明显了就再也不赘述。说说第二种方法吧。首先说说在Chrome中如何查看独立的Layer呢。如上图,选择Show composited layer borders后在页面上独立的Layer上回显示一个橘黄色边框。那么又要如何才能创建独立的Layer呢?

在Chrome中建立独立的Layer仅须要符合下述条件之一:


    1. 有3D元素的属性;

    2. video标签并使用加速视频解码;

    3. canvas元素并启用3D;

    4. 插件,好比flash;

    5. CSS动画;

    6. CSS滤镜;

    7. 有一个后代元素是独立的layer;

    8. 元素的相邻元素是独立layer。

看上去挺多挺复杂的,其实最简单、最容易理解、也最容易滥用的是第一条。实现第一条仅须要在元素的样式里加上:transform:translateZ(0);-webkit-transform:translateZ(0);就能够了。咱们将淘宝往下滑动一点,找一个元素试试看。

仍是看淘宝:

当加上css样式后对应的元素上出现了橘黄色边框,事实证实这招是有效的。而在Chrome中这样作能够启用GPU硬件加速。初次看到加速两个字让人以为无比兴奋,仿佛找到了克敌制胜的无敌神招。但是,首先这是在chrome下,其次大量使用真的好吗?

其实就算是在chrome下GPU也未必能排上用场,首先须要肯定你的GPU驱动程序不在chromium的黑名单中。由于某些GPU驱动程序存在错误,可能会影响浏览器稳定,因此会被加入到黑名单里。在chrome地址栏里输入about:gpu能够查看相关的GPU信息。如今再说说GPU加速的事情吧,简单点解释就是经过GPU渲染的Layer,GPU会将图层信息缓存起来,到下次改变的时候就只须要从新渲染修改过的部分。这样当然是快,可是会加大系统RAM和GPU的内存开销。在配置良莠不齐的移动设备上,过多的层不只不能加速,反而会严重影响性能。不少时候咱们在感受到移动网页较卡的时候不防试试减小页面上的Layer试试。

经过Chrome咱们还能够鉴别一些其余影响性能的方面。好比:

上面两幅图,左边一幅是百度.新闻的移动网页版,箭头指向的是这个页面的loading效果(就是一种一直一直转动的感受)。右边是之前最经常使用的一种loading。在效果上两种方式都同样,一直不停的转动。而区别在于右边的loading是一个带有背景图片的div,经过css3使其产生转动效果;而右边则是一张Gif动态图片。虽然效果上同样,但在浏览其中咱们能够看到右边的loading会有一个不停闪动的绿色框(频率至关高)。gif动画会致使浏览器不断的进行绘制、栅格化、合成,整个过程至关影响性能,因此最好干掉它。

简而言之言而简之:

一、减小重绘,减少重绘面积(改良布局,建立独立的Layer),下降重绘频率。

二、合理使用GPU加速,避免过分依赖GPU而致使性能降低。

说完布局,再简单谈谈动画吧。

经常使用的JavaScript动画在移动web上不少时候都显得爱莫能助(不给力啊)。这个缘由不少,JavaScript动画一般是经过定时改变元素样式属性的方式来实现,JavaScript的运行是在一个独立线程里完成的,做为单线程程序,JavaScript会由于某个耗时动做而影响下一帧动画的执行。并且,JavaScript的定时也并无想象中的那么守时,如在setinterval中设置每毫秒输出一个数,当输出到2000次的时候,当真就只须要2秒钟吗?相比之下更加推荐使用CSS3来完成相关动画效果。首先Css由独立线程完成,它和JavaScript的运行并不冲突,其次Css3不少属性不会触发重绘 (固然JavaScript里也能够是改变的css3的属性) 。从流畅度上来说的话Css3基本上完胜JavaScript,并且操做较容易。关于Css3相关知识就再也不赘述。

然而Css3的动画也并无想象中那般完美。

首先,在动画控制上不够灵活,整动画过程不太好监控。

其次,其兼容性不太好。仅移动端而言,位移动画一般使用transform,但在某些浏览器中须要使用-webkit-transform(如微信里的浏览器)。

虽然Css3并不是完美解决方案,但实际使用中大多数时候是彻底能够解决咱们所遇到的问题 (遇到复杂问题再解决吧,事在人为嘛,解决问题也是一种乐趣) 。 且目前的移动应用上并不推荐过于复杂的效果设计。

相关文章
相关标签/搜索