H5性能优化⽅案(转)
H5性能优化⽅案
H5性能优化意义
对于⼀个H5的产品,功能⽆疑很重要,但是性能同样是⽤户体验中不可或缺的⼀环。原本H5的渲染性能就不及native的app,如果不把性能优化做起来,将极⼤地影响⽤户使⽤产品的积极性。
⽤户感受
当⽤户能够在1-2秒内打开H5页⾯,看到信息的展⽰,或者能够开始进⾏下⼀步的操作,⽤户会感觉速度还好,可以接受;⽽页⾯如果在2-5秒后才进⼊可⽤的状态,⽤户的耐⼼会逐渐丧失;⽽如果⼀个界⾯超过5秒甚⾄更久才能显⽰出来,这对⽤户来说基本是⽆法忍受的,也许有⼀部分⽤户会退出重新进⼊,但更多的⽤户会直接放弃使⽤。
⼀秒钟法则
移动互联⽹的架构、通讯机制,与有线⽹络有着巨⼤的差异,这也给H5的开发带来了很⼤的挑战。
这是⼀张⼿机端接⼊服务器的流程。
⾸先,⼿机要通过⽆线⽹络协议,从获得⽆线链路分配,才能跟⽹络进⾏通讯。 ⽆线⽹络、控制器这⽅⾯,会给⼿机进⾏信号的分配,已完成⼿机连接和交互。 获得⽆线链路后,会进⾏⽹络附着、加密、鉴权,核⼼⽹络会检查你是不是可以连接在这个⽹络上,是否开通套餐,是不是漫游等。核⼼⽹络有SGSN和GGSN,在这⼀步完成⽆线⽹络协议和有线以太⽹的协议转换。 再下⼀步,核⼼⽹络会给你进⾏APN选择、IP分配、启动计费。 再往下⾯,才是传统⽹络的步骤:DNS查询、响应,建⽴TCP链接,HTTP GET,RTTP RESPONSE 200
OK,HTTP RESPONSE DATA,LAST HTTP RESPONSE DATA,开始UI展现。
可见,通过运营商的⽹络上⽹,情况⽐较复杂,经过的节点太多;运营商的⽹络信号强度变化频繁,连接状态切换快;⽹络延迟⾼、丢包率⾼;⽹络建⽴连接的代价⾼,传输速度快慢不等(从2G到4G,相差很⼤)。
⽽我们优化的⽬标,就是所谓的⼀秒钟法则,即达成以下的标准:
2g⽹络:1秒内完成dns查询、和后台服务器建⽴连接
3g⽹络:1秒内完成⾸字显⽰(⾸字时间)
wifi⽹络:1秒内完成⾸屏显⽰(⾸屏时间)
优化⽅案
资源加载
⾸屏加载
⽤户从点击按钮开始载⼊⽹页,在他的感知中,什么时候是“加载完成”?是⾸屏加载,即在可见的屏幕范围内,内容展现完全,loading进度条消失。因此在H5性能优化中,⼀个很重要的⽬的就是尽可能提升这个“⾸屏加载”的时间,让它满⾜“⼀秒钟法则”。
按需加载
⾸先要明确,按需加载虽然能提升⾸屏加载的速度,但是可能带来更多的界⾯重绘,影响渲染性能,因此要评估具体的业务场景再做决定。
Lazyload
Lazyload,即延迟加载,这并不是⼀个新的技术,在PC时代也是⾮常常⽤的⼀种性能优化⼿段。这个⽅案的原则是让屏幕外,或者不影响整体效果显⽰的图⽚、背景等资源,在界⾯就绪之后再进⾏⽹络加载。
滚屏加载
滚屏加载是⼀种常见的⽆刷新动态加载数据的⽅案,通常⽤在列表形式数据展⽰中。⼀⽅⾯,数据不是通过翻页进⾏加载,这样就避免了再⼀次请求和渲染整个页⾯;另⼀⽅⾯,数据显⽰的数量是受限的,例如第⼀次只请求了10条数据,也就只需要渲染这10条数据,下拉滚屏的时候,再去获得下⾯10条数据。
Media Query(响应式加载)
第三⽅资源异步加载
第三⽅资源有的时候不可控,⽐如说页⾯统计、地图显⽰、分享组件等,这些第三⽅资源使⽤的时候要慎重选择,充分考察它们对于性能的影响,使⽤异步加载的⽅式进⾏,防⽌第三⽅资源的使⽤影响到页⾯本⾝的功能。
Loading进度条
在加载时间较长的时候,务必要让⽤户明确感知到加载完成的提⽰,通常是在加载过程中显⽰Loading的进度条,加载完成的时候隐藏它。从⼼理上,这会让⽤户有⼀种“期盼感”,⽽不⾄于太过枯燥。
对于⼀些重量级的H5应⽤,例如游戏,开始前需要加载很多资源才能让后⾯的游戏过程更为流畅,⼀个带百分⽐进度显⽰的进度条就更加重要。
避免30*/40*/50*的http status
200是⼀个正常的response,我们在浏览器中打开⼀个⽹页(后⾯会讲如何针对移动端进⾏调试),还会看到304,即命中浏览器缓存。这两种状态是正常的http status。
302、301跳转是常见的跳转,尤其前⼀种,在我们进⾏鉴权的时候有时会⽤到,但这个做法要尽可能地优化,⼀个页⾯访问,最多只进⾏⼀次302跳转即可,切忌频繁地跳转。
404、500,我们对⾃⼰开发的代码⽐较注意,⼀般不会发⽣,但是有的时候,加载第三⽅库,尤其是第三⽅库中有⾃⼰load组件的操作,这时,404和500错误可能会在你不知不觉的时候发⽣。例如钉钉的第三⽅微应⽤中,就遇到过dojo的组件加载问题,加载的⼀些⼦组件失败了,但是⼜没有影响页⾯显⽰,这就很容易被忽略。后⾯也会再讲,如何去测试和发现这样的隐患。
Favicon.ico
如果我们没有设置图标ico,则会加载默认的图标:域名⽬录下的favicon.ico。很多开发者没有注意到这⼀点,就会导致这个请求404或者500。
通常,我们在应⽤内部打开⽹页,不会显⽰这个图标出来(除⾮放到浏览器中显⽰⽹页),我们需要保证这个图标存在,尽可能地⼩(⼀般4KB 以下),并且设置⼀个较长的缓存过期时间。
图⽚的使⽤
格式选择
显⽰效果较好的图⽚格式中,有webp、jpg和png24/32这⼏种常见的图⽚格式。⼀般来说,webp的图⽚最⼩,但在iOS或者android4.0以下的系统中可能会有兼容性问题需要解决。
Jpg是我们最常使⽤的⽅案,⼤⼩适中,解码速度快,兼容性问题也基本不存在,是我们在H5的应⽤中使⽤起来性价⽐最⾼的⽅案。
Png24或png32,⼀般来说,显⽰效果肯定会⽐jpg更好,但是实际上⼈眼很难感知出来,所以在H5应⽤中要避免这种格式的⼤图⽚。
像素控制
在H5应⽤中,图⽚的像素要严格控制,⼀般来说不建议宽度超过640px。
⼩图⽚合并
在html⽹页中,如果有多个⼩图⽚需要加载,不妨试试CSS Sprites⽅案,尤其是⼀些基本不变,⼤⼩差不多的操作类型图标。
js控制css3动画触发避免html代码中的⼤⼩重设
在html或者css中,如果有类似width: **px这样的代码,就要注意看⼀看了,如果说图⽚显⽰的效果是宽度100px,⽽下载的图⽚却是200px宽度,那这⼤⼩基本上就是所需要的4倍⾯积了,所以在H5应⽤中,使⽤图⽚的⼀个原则就是需要显⽰成多⼤,就下载多⼤的资源。
避免DataURL
DataURL是⽤Base64的⽅式,将图⽚变成⼀串⽂本编码放⼊代码的⽅式。这种⽅式有好处,因为它可以减少⼀次http交互的请求,对于⼀些体积特别⼩的图⽚,或者是动态⽣成的图⽚可以考虑使⽤。但在H5应⽤中,⼀般情况下,我们都是需要避免DataURL的,因为它的数据体积通常⽐⼆进制图⽚的格式⼤1/3,⽽且它不会被浏览器缓存,每次页⾯刷新都需要重新加载这部分数据。
使⽤图⽚的替代(css3, svg, iconfont)
CSS3和svg可以更好地使⽤GPU进⾏渲染加速,⽽且会避免增加图⽚资源导致的http请求增加。例如⼀些div的圆⾓效果,就完全可以⽤⽤css来实现。
Iconfont,可以认为是⼀种⽮量类型的操作字体。如果页⾯中有较多的操作图标,可以考虑使⽤iconfont来替代图⽚资源。
域名/服务端部署
Gzip
服务端要开启Gzip压缩。
资源缓存,长cache
合理设置资源的过期时间,尤其对⼀些静态的不需要改变的资源,将其缓存过期时间设置得长⼀些。
分域名部署(静态资源域名)
将动态资源和静态资源放置在不同的域名下,例如图⽚,放在⾃⼰特定的域名下。这样的好处是,静态资源请求时,不会带上动态域名中所设置的cookie头信息,从⽽减少http请求的⼤⼩。
减少Cookie
尽量减少Cookie头信息的⼤⼩,因为这部分数据使⽤的是上⾏流量,上⾏带宽更⼩,所以传输速度更
慢,因此要尽量精简其⼤⼩。
CDN加速
部署CDN服务器,或者使⽤第三⽅的CDN加速服务,优化不同地域接⼊⽹站的带宽速度。
代码资源
Javascript, CSS合并
尽量将所有的js和css合并,减少资源请求的次数。
外联使⽤js, css
外联使⽤js和css,这样可以有效地利⽤缓存,避免html页⾯刷新后重新加载这部分代码。
压缩html, js, css
压缩代码,尤其是js和css资源,压缩后的⼤⼩可以降低⾄原来的1/3以下,有效节约流量。
资源的版本更新
库js、css通常不会更新,但是我们的业务js和css可能会有更新,如果命中浏览器缓存,可能会让⼀些新的特性不能及时展现,甚⾄可能导致逻辑上的冲突。
因此对于这些js、css的资源引⼊,最好⽤版本号或者更新时间来作为后缀,这样的话,后缀不变,命中缓存;后缀改变,浏览器⾃动更新最新的代码。
Css位置
CSS要放到html代码的开头的head标签结束前。如果⽹页是动态⽣成的,那么在head代码完成后可以强制输出(例如php的flush()操作),这样的话,浏览器就会更快地解析出来head中的内容,开始下载css⽂件资源。
Js位置
Js放到前,这样的话,js的加载不会影响初始页⾯的渲染。
代码规范
避免空src
图⽚设置为空的src地址,在某些浏览器中可能会导致增加⼀个⽆效的http请求,因此要避免。
避免css表达式
可能会让页⾯多次执⾏计算,造成卡顿等性能问题。
避免空css规则
降低css渲染计算的成本
避免直接设置元素style
直接设置style属性,⼀⽅⾯在html代码中不利于缓存,另⼀⽅⾯也不利于样式的复⽤,因此要避免,通过指定id或者class的⽅式,在css代码块中进⾏样式调整。
服务端接⼝
接⼝合并
如果页⾯需要请求两部分以上的数据接⼝,建议将其合并,否则会增加⼀次http请求。
减少接⼝数据量
有的时候,服务端会把⼀些⽆关紧要的数据返回回来,尤其是类似于更新时间、状态等信息,如果在客户端不影响内容的逻辑展⽰,不妨在接⼝返回的数据中直接去掉这些内容。
缓存
缓存接⼝数据,在⼀些数据新旧敏感性不⾼的场景下很有作⽤,在⾮⾸次加载数据时候优先使⽤上次请求来的缓存数据,可以让页⾯更加快速地渲染出来,⽽不⽤等待⼀个新的http请求结束之后再渲染。这⼀点我们在后⾯还会再次提及。
其他⼀些建议
合理使⽤css
正确使⽤Display属性 Display属性会影响页⾯的渲染,因此请合理使⽤
display:inline后不应该再使⽤width、height、margin、padding以及float
display:inline-block后不应该再使⽤float
display:block后不应该再使⽤vertical-align
display:table-*后不应该再使⽤margin或者float
不滥⽤float
不声明过多的font-size
值为0时不需要单位
标准化各种浏览器前缀
⽆前缀应放在最后
CSS动画只⽤ (-webkit- ⽆前缀)两种即可
其它前缀为 -webkit- -moz- -ms- ⽆前缀 四种,(-o-Opera浏览器改⽤blink内核,所以淘汰)
选择器
避免让选择符看起来像是正则表达式。⾼级选择器不容易读懂,执⾏耗时也长
尽量使⽤ID选择器
尽量使⽤css3动画
资源加载
使⽤srcset
⾸次加载不超过1024KB(或者可以说是越⼩越好)
html和js

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。