⼩程序开发总结与⼼得(⼆)
专注于JavaScript、⼩程序、⼩游戏,Node.js和Java实时BUG监控。真的是⼀个很好⽤的bug监控费服务,众多⼤佬公司都在使⽤。
2 重点介绍⼏个组件
接下来说说使⽤频率⽐较多,功能强⼤,但⼜有⽐较多坑的⼏个组件
2.1 web-view
web-view的出现,让⼩程序和H5⽹页之前的跳转成为了可能。通过把H5页⾯放置到web-view中,可以让H5页⾯在⼩程序内运⾏。同时在H5页⾯中也可以跳转回⼩程序页⾯。可以说是带来了很⼤的便利,但同时由于web-view的诸多限制,⽤起来也不是很舒服。
1. 需要打开的H5页⾯必须在后台业务页⾯中配置,这其中还有个服务校验。另外H5页⾯必须是https协议,否则⽆法打开
2. web-view中⽆法在页⾯中调起分享,如果需要分享,⽐如跳回⼩程序原⽣页⾯
3. ⼩程序与web-view⾥H5通信问题。⼩程序向web-view传递,不敏感信息可以通过页⾯url传递。如果是敏感信息⽐如⽤户
token等,可以让服务端重定向,⽐如请求服务端⼀个地址,让他把敏感信息写在cookie中,再重定向到我们的H5页⾯。之后H5页⾯就可以通过在cookie中拿这些敏感数据了,或者http-only,发送请求时直接带上。
4. 每次web-view中src值有变化就会重新加载⼀次页⾯。所以个src拼接参数时,需要先赋值给个变量拼接好再⼀次性setData给
web-view的src,防⽌页⾯重复刷新
5. 从客户端
6.
阿根廷为什么叫潘帕斯雄鹰7.2版本开始,navigationStyle: custom对组件⽆效。也就意味着使⽤web-view时,⾃带的导航栏⽆法去掉。
6. 因为导航栏⽆法去掉,这⾥就出现了⼀个巨⼤的坑。实现全屏效果问题。如果想要实现H5页⾯全屏,就是不滑动,全屏显⽰完
所有内容。这时如果你使⽤width:100%;height:100%,你会发现,你页⾯底部可能会缺失⼀段。上图:
因为web-view是默认铺满全屏的,也就是web-view宽⾼和屏幕宽⾼⼀样。然后H5页⾯这是⾼度100%,这是相对web-view的⾼度,也是屏幕⾼度。但是关键问题:web-view⾥H5页⾯是从导航栏下开始渲染的。这就导致了H5页⾯溢出了屏幕,⽆法达到全屏效果。
解决⽅法
这个问题我在前段时间的实际项⽬碰到过,我们要做个H5游戏,要求是全屏,刚开始我也是设置⾼度100%。后来发现底部⼀块不见了。我的解决⽅法⽐较粗暴,如果有更好的解决⽅法,欢迎评论交流。 我的解决⽅法是:通过拼接宽⾼参数在H5页⾯url上,这个宽⾼是在web-view外层计算好的。H5页⾯直接读取url上的宽⾼,动态设置页⾯的宽⾼。页⾯⾼度的计算,根据上图,很显然就是屏幕⾼度减去导航栏⾼度。宽度都是⼀样的,直接是屏幕宽度。
但问题⼜来了,貌似没有途径获取导航栏⾼度。⽽且对于不同机型的⼿机,导航栏⾼度不同。经过了对多个机型导航栏跟屏幕⾼度的⽐较。发现了⼀个规律,导航栏⾼度与屏幕⾼度、屏幕宽⾼⽐有⼀定的关系。所以根据多个机型就计算出了这个⽐例。这解决了95%以上⼿机的适配问题,只有少数机型适配不是很好。到基本实现了全屏效果。具体代码如下:
onLoad (options) {
//同步获取屏幕信息,现在⽤到的是屏幕宽⾼
var res = wx.getSystemInfoSync();
if (res) {
var widHeight = res.screenHeight;
//对于⼤多数⼿机,屏幕⾼度/屏幕宽度 = 1.78。此时导航栏占屏幕⾼度⽐为0.875
var raito = 0.875;
if (res.screenHeight / res.screenWidth > 1.95) {
//对于全屏⼿机,这个占⽐会更⾼些
raito = 0.885;
} else if (res.screenHeight / res.screenWidth > 1.885) {
raito = 0.88;
}
//做兼容处理,只有版本库⾼于6.7.2,有导航栏才去兼容,否则可以直接使⽤⾼度100%。res.statusBarHeight是⼿机顶部状态栏⾼度
//如果版本号⼤于6.7.2,有导航栏
if (utilpareVersion(res.version, "6.7.2") > 0) {
widHeight = und(widHeight * raito) + (res.statusBarHeight || 0);
}
this.setDate({
//将H5页⾯宽⾼拼接在url上,赋值给web-view的src即可加载出H5页⾯
webview_src: util.joinParams(h5_src, {
"height": widHeight,网游之深秋传说
"width": res.screenWidth
})
})
}
}
复制代码
2.2 scroll-view
当我们要实现⼀个区域内滑动效果时,在H5页⾯中我们设置overflow-y: scroll即可。但在⼩程序中,没有该属性。需要⽤到scroll-view标签。具体操作实现我们可以查看⽂件。
锚点定位在前端开发中会经常⽤到,在H5页⾯中,我们会在url后⾯加上#来实现锚点定位效果。但是在⼩程序中这样是不起作⽤的,因为⼩程序内渲染页⾯的容易不是⼀个浏览器,⽆法实时监听Hash值得变化。但是使⽤scroll-view,我们可以实现锚点点位效果。主要是使⽤scroll-into-vie属性具体实现我们直接上代码
scroll-into-view | String | 值应为某⼦元素id(id不能以数字开头)。设置哪个⽅向可滚动,则在哪个⽅向滚动到该元素
wxml⽂件
<!--toView的值动态变化,当toView为luckydraw时,会定位到id为luckydraw的view
需要注意的是,这⾥需要设置⾼度为屏幕⾼度-->
<scroll-view scroll-y scroll-into-view="{{toView}}"
scroll-with-animation = "true" >
<view id="top"></view>
<view id="luckydraw"></view>
<view id="secskill"></view>
<scroll-view>
复制代码
2.3 canvas
画布标签,它是原⽣组件,所以它必须位于屏幕最上边,⽽且是不能隐藏的。所以如果想要使⽤canvas动态⽣成分享照⽚。那你要设置她的宽⾼和屏幕⼀样。要不导出为照⽚时就会失真。因为这个原因,所以⽣成分享照⽚还是有服务端实现吧,照⽚失真太严重了。
3 formid收集
给⽤户发送消息对⼀个⼩程序是⾮常重要的,它可以召唤回⽤户,导量效果⾮常明显。我们可以通过模板消息想⼩程序⽤户发送消息,但前提是我们得获取到openid和formid。⽤户登录我们即可即可获取到⽤户openid。⽽只要⽤户有点击⾏为,我们即可获取到formid。所以说formid是很重要的。我们可以提前收集好formid,在需要的时候给⽤户推送消息。我们可以个每个button都包上form标签,只要有⽤户点击⾏为都可以收集到formid.
<form bindsubmit="formSubmit" report-submit='true'>
<button formType="submit">点击</button>
</form>
复制代码
教师节的作文500字我们实现⼀个formid收集系统,为了尽量减少冗余代码和减少对业务的影响,我们的设计是这样的
1. 在整个页⾯的最外层包裹form标签,不是每个button都包裹⼀个,这样只要是页⾯中formTpye=submit的button有点击都能获取到
formid。
2. formid保存在全局变量数组中,当⼩程序切换到后台是⼀次性发送。
激活iphone43. 对于需要实时发送消息的,不添加值全局数组中,直接保存在页⾯变量中。
wxml⽂件
<!--在整个页⾯的最外层包裹form标签,这样就不同对每个button都包裹⼀个form标签,代码简洁-->
<form bindsubmit="formSubmit" report-submit='true'>
<view>页⾯内容</view>
<view>页⾯内容</view>
<button formType="submit">点击</button>
<view>页⾯内容</view>
<view>两会时间结束时间
<button formType="submit">点击</button>
</view>
</form>
复制代码
page.js⽂件
//每次⽤户有点击,都将formid添加到全局数组中
formSubmit(e) {
//需要实时发送的,不添加
if(e.target.dataset.sendMsg){
formid = e.detail.formId;
return;
}
app.appData.formIdArr.push(e.detail.formId);
}
复制代码
app.js
万和壁挂炉onHide: function () {
//⼩程序切到后台时上传formid
this.submitFormId();
},
复制代码
4 性能优化相关
从⽤户打开⼩程序到⼩程序销毁,我们可以想想有哪些地⽅是可以优化的。⾸先是打开速度。⼩程序打开速度直接影响了⽤户留存。在⼩程序后台,运维中⼼-监控告警下有个加载性能监控数据,我们可以看到⼩程序启动总耗时、下载耗时、⾸次渲染耗等加载相关的数据。⽽这⾥的打开速度其实就是⼩程序的启动总耗时。它包括了代码包下载、⾸次渲染,内环境初始化等步凑。在这⼀步,我们能做的就是如何加快代码包下载速度和减少⾸次渲染时间
在⼩程序呈现给⽤户之后,接下来如何提⾼⽤户体验,增强⼩程序健壮性的问题了。每个程序都有bug。只是我们没发现⽽已,尽管在测试阶段,我们进⾏了详尽的测试。但是在实际⽣产环境,不同的⽤户环境,不同的操作路径,随时会触发⼀些隐藏的bug。这时如果⽤户没有向我们报告,我们是⽆法获知的。所以有必要给我们的⼩程序增加错误信息收集,js脚本错误,意味着整个程序挂掉了,⽆法响应⽤户操作。所以对于运⾏时的脚本错误,我们应该上报。对出现的bug及时修复,增强程序健壮性,提供⽤户体验。
每个程序都有⼤量的前后端数据交互,这是通过http请求进⾏的。因此,还有⼀个错误信息收集就是接⼝错误信息收集。对那些请求状态码⾮2XX、3XX的,或者请求接⼝成功了,但是数据不是我们预
期的,都可以进⾏信息采集。
通过对⼩程序运⾏时脚本和http请求进⾏监控,我们就可以实时了解我们线上⼩程序的运⾏状况,有什么问题可以及时发现,及时修复,极⾼地提⾼了⽤户体验性。
4.1 让⼩程序更快
让⼩程序快,主要因素有两个,代码包下载和⾸屏渲染。 我们来看⼀个数据:
前⾯状态⼩程序代码⼤⼩是650Kb左右,这是下载耗时(虽然跟⽤户⽹络有关,但这个是全部⽤户平均时间)是1.3s左右。但是经过优化,将代码包降低⾄200kb左右时。下载耗时只有0.6s左右。所以说,代码包减少500kb,下载耗时能减少0.5s。这个数据还是⾮常明显和。所以说,在不影响业务逻辑的情况下,我们⼩程序代码包应该尽可能地⼩。那么如何降低代码包⼤⼩呢?以下有⼏点可以参考
1. 因为我们上传代码到服务器时,它会将我们的代码进⾏压缩的,所以⽤户下载的代码包并不是我们开发时的那个⼤⼩。对此,开
发时也没必要删空⾏、删注释这些。在开发⼯具项⽬详情中可以看到上次上传⼤⼩,这个⼤⼩就是⽤户最终使⽤的⼤⼩。如果觉得压缩还不够好,可以通过第三⽅⼯具对我们代码进⾏⼀次压缩再上传,然后对⽐效果,有没有更⼩。这个没有使⽤过。如果有什么好⼯具,欢迎推荐。
2. 将静态资源⽂件防⽌到我们⾃⼰服务器或者cdn上。⼀个⼩程序,最耗空间的往往是图⽚⽂件。所以我们可以抽离出来,图⽚⽂件可
以异步获取,在⼩程序启动以后再去获取。这样,代码包就会⼩很多。
3. 使⽤分包加载。⼩程序提供了分包加载功能。如果你的⼩程序很庞⼤,可以考虑使⽤分包加载功能,先加载必要功能代码。这样就是
可以极⼤降低代码包⼤⼩
接下来是⾸屏渲染,从上图的⼩程序⽣命周期可以看出,从加载⾸页代码带⾸页完成渲染,这段时间就是⽩屏时间,也就是⾸次渲染时间。⽽⼩程序在这段时间内,主要⼯作是:加载⾸页代码、创建View和AppService层、初试数据传输、页⾯渲染。在这四个步骤中,加载⾸页代码,前⾯已经说过;创建View和AppService层,是完成的,跟⽤户⼿机有关,这不是我们可控的。我们能做的就是减少初试数据传输时间和页⾯渲染时间。
1. 我们知道page.js中的data对象在⾸次渲染时会通过数据管道传个视图层进⾏页⾯渲染。所以我们应该控制这个data对象的⼤⼩。对于
与视图渲染⽆关的数据,不要放在data⾥⾯,可以设置个全局变量来保存。
Page({
//与页⾯渲染有关的数据放这⾥
data: {
goods_list:[]
},
//与页⾯渲染⽆关的数据放这⾥
_data: {
timer: null
}
})
复制代码
1. 页⾯渲染速度还跟html的dom结构有关。这⼀点的优化空间算是⾮常少了,就是写⾼质量html代码,减少dom嵌套,让页⾯渲染速度
快⼀丢丢。
4.2 让⼩程序更强
接下来就是给⼩程序增加错误信息收集,包括js脚本错误信息收集和http请求错误信息收集。前段时间,在时间⼯作开发中,为了更好的复⽤和管理,我把这个错误信息收集功能做成了插件。然⽽做成插件并没有想象中的那么美好,下⾯再具说。
脚本错误收集
对于脚本错误收集,这个相对⽐较简单,因为在app.js中提供了监听错误的onError函数
只不过错误信息是包括堆栈等⽐较详细的错误信息,然后当上传时我们并不需要这么信息,第⼀浪费宽带,第⼆看着累⼜⽆⽤。我们需要的信息是:错误类型、错误信息描述、错误位置。
thirdScriptError
aa is not defined;at pages/index/index page test function
ReferenceError: aa is not defined
st (127.0.0.1:62641/appservice/pages/index/index.js:17:3)
at e.<anonymous> (127.0.0.1:62641/appservice/__dev__/WAService.js:16:31500)
at e.a (127.0.0.1:62641/appservice/__dev__/WAService.js:16:26386)
at J (127.0.0.1:62641/appservice/__dev__/WAService.js:16:20800)
at Function.<anonymous> (127.0.0.1:62641/appservice/__dev__/WAService.js:16:22389)
at 127.0.0.1:62641/appservice/__dev__/WAService.js:16:27889
at 127.0.0.1:62641/appservice/__dev__/WAService.js:6:16777
at e.(anonymous function) (127.0.0.1:62641/appservice/__dev__/WAService.js:4:3403)
at e (127.0.0.1:62641/appservice/appservice?t=1543326089806:1080:20291)
isterCallback.t (127.0.0.1:62641/appservice/appservice?t=1543326089806:1080:20476)
复制代码
这是错误信息字符串,接下来我们对它进⾏截取只需要拿我们想要的信息即可。我们发现这个字符串是有规则的。第⼀⾏是错误类型,第⼆⾏是错误详情和发⽣的位置,并且是";"分好分开。所以我们还是很容易就可以拿到我们想要的信息。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论