【微信小程序】在BUG中实战了一次wx:if和hidden

大概是20天前,复习基础的复习到了wx:if和hidden(隐藏元素)的区别。今天(被迫)实战了。然后

先上知识点

wx:if 与 hidden 都可以控制微信小程序中元素的显示与否。

区别

wx:if 是遇 true 显示,hidden 是遇 false 显示。

wx:if 在隐藏的时候不渲染,而 hidden 在隐藏时仍然渲染,只是不呈现。

所以如果频繁切换的话,用 wx:if 将会消耗更多资源,因为每次呈现的时候他都会渲染,每次隐藏的时候,他都会销毁。

如果切换并不频繁的话,用 wx:if 相对来说较好些,因为它会避免初始就一下渲染那么多。

是什么问题让我们踩坑

     

   {{item.id}}
  


let that=this;
index_ajax("接口url",'请求方式',data,function(res){
    that.setData({
        data:res.data
    })
console.log(that.data)
})

是不是一切看起来都干干净净自自然然简简单单?我也是这样认为的。但BUG就是BUG,坑就在干干净净的代码里面。

我最初的排查步骤

console.log(that.data)
//正常打印

控制台中appData也正常被赋值,但视图层并没有被正常渲染。其他元素也正常渲染,唯独我想渲染的data不行。于是我开始百度尝试了这样做

that.data.data = res.data
that.setData({
    data:that.data.data
})

依然无效。

开始翻阅文档找找关于 setData 的信息

工作原理

小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境。在架构上,WebView 和 JavascriptCore 都是独立的模块,并不具备数据直接共享的通道。当前,视图层和逻辑层的数据传输,实际上通过两边提供的 evaluateJavascript 所实现。即用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立环境。
而 evaluateJavascript 的执行会受很多方面的影响,数据到达视图层并不是实时的。

常见的 setData 操作错误

  1. 频繁的去 setData
    在我们分析过的一些案例里,部分小程序会非常频繁(毫秒级)的去setData,其导致了两个后果:
    Android 下用户在滑动时会感觉到卡顿,操作反馈延迟严重,因为 JS 线程一直在编译执行渲染,未能及时将用户操作事件传递到逻辑层,逻辑层亦无法及时将操作处理结果及时传递到视图层;
    渲染有出现延时,由于 WebView 的 JS 线程一直处于忙碌状态,逻辑层到页面层的通信耗时上升,视图层收到的数据消息时距离发出时间已经过去了几百毫秒,渲染的结果并不实时;
  2. 每次 setData 都传递大量新数据
    由setData的底层实现可知,我们的数据传输实际是一次 evaluateJavascript 脚本过程,当数据量过大时会增加脚本的编译执行时间,占用 WebView JS 线程,
  3. 后台态页面进行 setData
    当页面进入后台态(用户不可见),不应该继续去进行setData,后台态页面的渲染用户是无法感受的,另外后台态页面去setData也会抢占前台页面的执行。

顺便也涨了一下新的知识。

然后我们发现了新的问题

因为数据是每次请求接口都刷新的,所以尝试点击了其他的数据,存在部分数据被渲染了,但也有数据没有被渲染到。这时我开始怀疑是否是因为数据太大了,setdata还来不及加载,实测一番后发现:“小江同学又想多了”。

大佬出现了

大佬经过5分钟的查看,默默在

     

   {{item.id}}
  

这里增加了

   
 
        {{item.id}}
   

并解释道:这个问题呢,是因为dom渲染的问题。我们在试图层增加一个wx:if 使其进行渲染,如果遇到false 销毁,再进行渲染。

大功告成!

你可能感兴趣的:(【微信小程序】在BUG中实战了一次wx:if和hidden)