原文链接
移动互联网的发展迅猛,无论在移动游戏、手机购物、各种O2O的方式,都有各种变革;手设备硬件和系统不断升级和改进对HTML5的支持也越来越好,更多的创意效果在移动设备上得到了支持,更多的创意页面也闪亮的出现在我们眼前~~!
而创意的页面除了设计上的视觉表现外对于前端开发者来说存在更多的挑战,移动端页面开发过程中会碰到各种各样千奇百怪的问题(俗称:BUG或坑)~于是就与大家伙一起分享关于移动端H5前端的知识,希望能给伙伴们带来一些帮助吧!
一、移动前端的性能优化
-
加载优化
加载过程是最为耗时的过程,可能会占到总耗时的80%时间,因此是优化的重点
方法:
- 减少HTTP请求
因为手机浏览器同时响应请求为4个请求(Android支持4个,IOS 5可支持6个),所以要尽量减少页面的请求数,首次加载同时请求数不要超过4个 - 合并CSS、JavaScript合并小图片,使用CSS Sprite(雪碧图)
- 缓存
使用缓存可以减少向服务器的请求数,节省加载时间,所以所有静态资源都要在服务器端设置缓存,并且尽量使用长Cache,缓存一切可缓存的资源,使用长Cache(使用时间戳更新Cache) - 使用外联式引用CSS、JavaScript
- 压缩HTML、CSS、JavaScript
减少资源大小可以加快网页显示速度,所以要对HTML、CSS、JavaScript等进么代码压缩,并在服务器端设置GZIP压缩(例如:多余的空格、换行符和缩进) - 启用GZip
- 无阻塞
写在HTML头部的JavaScript(无异步)和写在HTML标签中的style会阻塞页面的渲染,因此CSS放在页面头部并使用Link方式引入,避免在HTML标签中写内联样式, JavaScript放在页面尾部或使用异步方式加载 - 使用首屏加载
首屏的快速显示,可以大大提升用户对页面速度的感知,因此应尽量针对首屏的快速显示做优化
优化建议:
(1).按需加载
将不影响首屏的资源和当前屏幕资源不用的资源放到用户需要时才加载,可以大大提升重要资源的显示速度和降低总体流量PS:按需加载会导致大量重绘,影响渲染性能
(2).预加载
大型重资源页面可使用增加Loading的方法,资源加载完成后再显示页面;但Loading时间过长,会造成用户流失,建议对用户行为分析;在当前页加载下一页资源,提升速度
(3).压缩图片
图片是最占流量的资源,因此尽量避免使用它,使用时选择最合适的格式(1、WEBP格式优于JPG格式;2、PNG8优于GIF);合适的大小(1、首次加载不大于1014KB;2、不宽于640(基于手机屏幕一般宽度))然后使用智图压缩(http://zhitu.tencent.com),同时在代码中用srcset0来按需显示
PS:过度压缩图片大小影响图片显示效果 - 减少Cookie
COOKIE会影响加载速度,所以静态资源域名不使用Cookie - 避免重定向
重定向会影响加载速度,所以在服务器正确设置避免重定向 - 异步加载第三方资源
第三方资源不可控会影响页面的加载和显示,因此要异步加载第三方资源
-
脚本执行优化
脚本处理不当会阻塞页面加载、渲染,因此在使用时需注意:
- CSS写在头部,JavaScript写在尾部或异步
- 避免图片和iF-rame等的空src
空src会重新加载当前页面,影响速度和效率 - 尽量避免重设图片大小
重设图片大小是指在页面、CSS、JavaScript等中多次重置图片大小,多次重设图片大小会引发图片的多次重绘,影响性能 - 图片尽量避免使用DataURL
DataURL图片没有使用图片的压缩算法文件会变大,并且要解码后再渲染,加载慢耗时长
- CSS优化
- 尽量避免写在HTML标签中写STYLE属性
- 避免CSS 表达式
CSS表达式的执行需跳出CSS树的渲染,因此请避免CSS表达式 - 移除空的CSS规则
空的CSS规则增加了CSS文件的大小,且影响CSS树的执行,所以需移除空的CSS规则 - 正确使用Display的属性
Display属性会影响页面的渲染,因此请合理使用,display:inline-block
后不应再使用width\height\margin\padding
以及float
,
display:inline-block
后不应再使用vertical-align
- 不滥用Float
Float在渲染时计算量比较大,尽量减少使用 - 不滥用WEB字体
WEB字体需要下载,解析,重绘当前页面, 尽量减少使用 - 不声明过多的Font-size
过多的font-size引发CSS树的效率 - 值为0时不需要任何单位
为了浏览器的兼容性和性能,值为0时不要带单位 - 标准化各种浏览器前缀
无前缀应放在最后,CSS动画只用(-webkit-无前缀)两种即可
其它前缀为-webkit-moz-ms-无前缀四种 - 避免让选择符看起来像正规表达式
- 高级选择器执行耗时且不易读懂,避免使用
- JavaScript执行优化
- 减少重绘和回流
- 避免不必要的DOM操作
- 尽量改变Class而不是style,使用classlist代题className
- 避免使用document.write
- 减少drawImage
- 缓存Dom选择与计算
每次Dom选择都要计算,缓存它 - 缓存列表.length
每次.length都要计算,用一个变量保存这个值 - 尽量使用事件代理,避免批量绑定事件
- 尽量使用ID选择器
ID选择器是最快的 - TOUCH事件优化
使用ouchstart\touchend代替click,但应注意touch响应过快,易引发误操作 - 渲染优化
HTML使用Viewpor,Viewport可以加速页面的渲染 - 减少Dom节点
Dom节点太多影响页面的渲染,应尽量减少Dom节点 - 动画优化
尽量使用CSS3动画
合理使用requestAnimationFrame动画代替Timeout
适当使用Canvas动画 5个元素以内使用CSS动画,5个以上使用Canvas动画(IOS8可使用webGL) - 高频事件优化
Touchmove\Scroll事件可导致多次渲染;使用requestAnimationFrame监听帧变化,使得在正确的时间进行渲染;
增加响应变化的时间间隔,减少重绘次数 - CPU加速
CSS中以下属性(CSS3 transitions、css3 3D transforms、Opacity、Canvas、WebGL、video)来触发CPU渲染,请合理使用;过渡使用会引发手机耗电增加
总结:
1、PC优化手段在Mobile侧同样适用
2、在Mobile侧我们提出三秒钟渲染完成首屏指标
3、基于第二点,首屏加载3秒完成或使用Loading
4、基于联通3G网络平均338KB/s(2.71MB/s),所以首屏资源不应超过1014KB
5、Mobile侧因手机配置原因,除加载外渲染速度也是优化重点
6、基于第五点,要合理处理代码减少渲染损耗
7、基于第二、第五点,所有影响首屏加载和渲染的代码应在处理逻辑中后置
8、加载完成后用户交互使用时也需要注意性能
二、排坑技巧
对于前端来说移动端存在更多的挑战,移动端页面开发过程中会碰到各种各样千奇百怪的问题,不同设备、不同操作系统、不同运行环境下都可能造成各种各样的没有碰到过的坑。
首先聊聊4类常见的
- 页面高度渲染错误
在各移动端浏览器中经常会出现这种页面高度100%的渲染错误,页面底端和系统自带的导航重合了,高度的不正确我们需要重置修正它,通过javascript代码重置:
document.documentElement.style.height=window.innerHeight+"px";
- 叠加区高亮
在部分android机型中点击页面某一块区域可能会出现如图所示的黄色框秒闪,这是部分机型系统自身的默认定制样式,给该元素一个CSS样式重置掉:
-webkit-tap-highlight-color:rgba(0,0,0,0);
- 事件无法被触发
在部分android机型的微信环境中会出现事件无法触发、表单无法输入的情况,我们针对需要输入或者触发事件的元素设置样式:
-webkit-transform:translate3d(0,0,0);
不过新版的微信已经直接修复了该问题 - active效果不兼容
在android 4.0版本以下css:active
伪状态效果无法兼容,我们给该元素的touch系列的事件(touchstart/touchend/touchmove)
绑定一个空匿名方法:
element.addeventlistener("touchstart",function(){},false);
- 预加载、自动播放无效
经过简单的测试发现预加载、自动播放的有效性受操作系统、浏览器、版本等的影响,苹果官方规定必须由用户手动触动才会载入音频,那么我们可以捕捉一次用户输入后,让音频加载实现预加载
document.addeventlistener("touchstart,"function(){document.getelementsbytagname("autio"[0].play();document.getelementsbytagname("autio"
[0].pause();})
- 无法同时播放多音频
在android设备中,播放后:音频会打断前音频,而不会同步播放,这个是目前系统自身决定的,我们只有采取优雅降权的方法让android选择不一样风格的音频前后切换播放而不是同时播放,达到与预期接近的音频效果。 -
不支持局部滚动
在android 4.0版本以下在body(html)元素之外的元素 overflow:scroll样式设置滚动条无效
建议两种解决方案:
- 巧用布局直接设置样式滚动条在body(html)上,其他元素“错觉滚动”。
- 利用iscroll、自写js控制translate、scrollTop模拟
除了以上这些坑,还有各种各样的坑,就不一一讲解了~不过解决这些坑自身的心态和执行力很重要;
对于未知的坑的解决问题,这里就分享一些方式骤及技巧:
- DOM隔离定位法
- 不官由大范围到小范围隔离出DOM,从而找出、触发问题的DOM元素
- 样式、JS剔除法
不断剔除一些JS、CSS观察调试检查是否是相关样式引起的问题 - 多运行环境测试法
在多环境测试,排查是否由于特定环境引起 - PC与手机联合调试法
联合PC与手机进行定位,如:通过Mac远程调试iphone/ipad
世上本无路,走的人多了就变成的了路;无穷无尽的坑,走的多了,总结改进次数多了,坑也就越来越平了;