├── images ├── 1-way.png ├── 3-mp-data.png ├── 3-qrcode.png ├── 5-init-1.jpeg ├── 4-vConsole-1.jpeg ├── 4-vConsole-2.jpeg ├── 4-vConsole-3.jpeg ├── 4-vConsole-4.jpeg ├── 3-onload-report.png ├── 3-onshow-report.png └── 3-wechat-success.jpg ├── docs ├── 2-multiple-promise-block.md ├── 1-qrcode-history.md ├── 3-pv-error.md ├── 5-mini-program-import.md └── 4-vConsole.md └── README.md /images/1-way.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/1-way.png -------------------------------------------------------------------------------- /images/3-mp-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/3-mp-data.png -------------------------------------------------------------------------------- /images/3-qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/3-qrcode.png -------------------------------------------------------------------------------- /images/5-init-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/5-init-1.jpeg -------------------------------------------------------------------------------- /images/4-vConsole-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/4-vConsole-1.jpeg -------------------------------------------------------------------------------- /images/4-vConsole-2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/4-vConsole-2.jpeg -------------------------------------------------------------------------------- /images/4-vConsole-3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/4-vConsole-3.jpeg -------------------------------------------------------------------------------- /images/4-vConsole-4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/4-vConsole-4.jpeg -------------------------------------------------------------------------------- /images/3-onload-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/3-onload-report.png -------------------------------------------------------------------------------- /images/3-onshow-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/3-onshow-report.png -------------------------------------------------------------------------------- /images/3-wechat-success.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/find-xcx-bugs/xcx-bug-list/HEAD/images/3-wechat-success.jpg -------------------------------------------------------------------------------- /docs/2-multiple-promise-block.md: -------------------------------------------------------------------------------- 1 | # 小程序内多重调用原生promise,无返回,无报错,代码卡住 2 | 3 | ## 作者: [蒋欢](https://github.com/Dragon-Rider) 4 | 5 | ### 问题: 6 | 在部分IOS机型上,小程序内使用原生promise实现异步,在嵌套四层后,Promise的resolve和reject均无返回。 7 | 8 | ### 环境: 9 | 用户机型:iPhone 7 10 | 系统版本:IOS 10.3.3 11 | 微信版本:6.5.21 12 | `部分ios用户可以稳定复现。` 13 | 14 | ### 原因: 15 | 微信侧表示IOS 10下小程序使用的是原生的promise,[页面由 WKWebView 来渲染的](https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/details.html)。因此网页也会有同样的问题,但我们还未在H5下得到验证。 16 | 之前微信曾修复过IOS 8 下类似[问题记录](https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/uplog.html)。 17 | 18 | ### 解决方案: 19 | 换成第三方库[pinkie.js](https://github.com/floatdrop/pinkie/blob/master/index.js),实现promise,用户问题得到解决。 20 | 21 | ### 风险: 22 | 目前还没有遇到任何兼容性问题上报,但pinkie里手动实现的promise比系统原生promise要慢一点。 如果进行异步操作并全局赋值时,要注意异步返回生效的时机。 23 | 24 | -------------------------------------------------------------------------------- /docs/1-qrcode-history.md: -------------------------------------------------------------------------------- 1 | # 小程序扫普通二维码调起小程序bug:码地址传递错误,传为历史地址 2 | 3 | ## 作者: [陈小二](https://github.com/chenyaoswu) 4 | 5 | ### 问题: 6 | 用户扫码二维码A,小程序onload中传递q参数为二维码地址B,且该二维码地址为用户历史使用二维码地址。 7 | 8 | ### 原因: 9 | 微信侧扫码启动参数错乱。 10 | 11 | 用户使用微信“扫一扫”扫描二维码A,微信通过系统事件启动小程序,用户使用完之后,将小程序退到后台,一段时间后小程序被系统回收。 12 | 用户再次扫描二维码B,微信仍然通过系统事件启动小程序,但是实际上,系统先发出A二维码的启动事件,再发出B二维码的启动事件, 13 | 导致小程序启动参数错乱。理论上,用户第二次扫码的时候,系统不应该连续发出两次事件。 14 | 15 | ### 解决方案: 16 | 方案一(覆盖7-8成用户): 17 | 18 | 微信侧目前上线了热修复方案,纠正该问题,保证通过系统事件启动时传递正确的码地址。但目前该方案仅能覆盖最近两个版本,即6.5.20以后的,覆盖人群不会很高,活跃用户的七八成。所以仍然存在该bug. 19 | 20 | 方案2 (解决剩下的2-3成用户): 21 | 22 | 目前扫码启动小程序的场景,微信会将原始URL通过参数的方式传给小程序,key为"q"。 23 | 后台改动上线后,会多出一个key为"scancode_time"的UNIX时间戳参数,是用户扫码的时间。 24 | 用户扫码时间和执行onlaod的时间相对比如果在30s以内,可以认为传递给我们的码地址是30s以内刚扫过的码,可以认为传递的非历史地址。从这个逻辑出发,做了以下校验: 25 | 26 | ![传错码地址校验](https://github.com/find-xcx-bugs/xcx-bugs-list/blob/master/images/1-way.png) 27 | 28 | ps:第二次将扫码时间与服务器端时间再次进行校验的目的:避免部分用户手动更改手机时间或者本地手机时间差距较大,导致问题出现,故再进行一次服务端时间校验。 29 | 30 | 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # xcx-bugs-list(微信小程序踩坑集合) 2 | 3 | ## 这个仓库的意义在于? 4 | 帮助开发小程序的前端工程师们避免再次进坑. 5 | 6 | 本周(2017.11.24)因为我们的小程序在线上出现了一例case,用户通过普通二维码调起小程序后传参错误, 7 | 起初我们自己排查日志后难以定位问题,找到微信侧从日志查询告知没有问题。后来同摩拜的前端小伙伴 [binnng](https://github.com/binnng) 8 | 咨询,发现他们也存在相同的问题,跨业务间存在相同的问题可能是微信的问题,因而push了微信协助解决。 9 | 所以,建立这个组织和仓库的意义更多是希望促进跨工程间相互沟通,也希望帮助后来的人走更少的路吧。 10 | 11 | 12 | ## 参与共建这个仓库的人都有哪些? 13 | 目前主要由[陈小二](https://github.com/chenyaoswu)和[蒋欢](https://github.com/Dragon-Rider)在维护,因为刚入坑,暂时没有太多的可贡献案例。欢迎大家有空也能一起贡献。 14 | 15 | ## 如何贡献 16 | 提pr即可。 17 | 18 | ## 如何加入弱势群体组织 19 | 提Issue给我,我邀请你。 20 | 21 | 22 | # buglist集合: 23 | 24 | [1.小程序扫普通二维码调起小程序 码地址传为历史地址](./docs/1-qrcode-history.md) —— Author: [陈小二](https://github.com/chenyaoswu) 25 | 26 | [2.小程序内多重调用原生promise,无返回,无报错,代码卡住](./docs/2-multiple-promise-block.md) —— Author: [蒋欢](https://github.com/Dragon-Rider) 27 | 28 | [3.小程序页面pv统计数过高,导致页面转化率低](./docs/3-pv-error.md) —— Author: [陈小二](https://github.com/chenyaoswu) 29 | 30 | [4.vConsole 将已清除掉的log记录再次打印出来,造成代码没有生效或者微信扫码错误的错觉](./docs/4-vConsole.md) —— Author: [蒋欢](https://github.com/Dragon-Rider) 31 | 32 | [5.小程序退出后扫码再进入,“外部”代码不会再次执行](./docs/5-mini-program-import.md) —— Author: [蒋欢](https://github.com/Dragon-Rider) 33 | -------------------------------------------------------------------------------- /docs/3-pv-error.md: -------------------------------------------------------------------------------- 1 | # 小程序页面pv统计数过高,导致页面转化率低 2 | 3 | ### 作者:[陈小二](https://github.com/chenyaoswu) 4 | 5 | ### 问题: 小程序使用微信支付的单页面pv数偏高,致页面转化率低 6 | 7 | 对于业务开发者来说,业务数据和数据监控是不可缺失的。 8 | 9 | 图例是我们小程序扫码付业务在数据体系搭建过程中的其中一步:技术流程拆解。 10 | 11 | 12 | ![技术流程拆解](https://github.com/find-xcx-bugs/xcx-bugs-list/blob/master/images/3-qrcode.png) 13 | 14 | 15 | 在数据选型上,我同时使用了微信自定义数据统计和公司内部第三方数据统计,并将之与微信主动上报的数据分析进行对比, 16 | 来确保数据准确性。 17 | 18 | 微信自定义数据统计和公司内部第三方数据统计方法: 19 | 20 | ![第三方数据统计代码](https://github.com/find-xcx-bugs/xcx-bugs-list/blob/master/images/3-onshow-report.png) 21 | 22 | 微信主动上报数据查询参见MP后台 微信实时统计: 23 | 24 | ![微信实时统计](https://github.com/find-xcx-bugs/xcx-bugs-list/blob/master/images/3-mp-data.png) 25 | 26 | 27 | 在数据的收集过程中,我发现支付按钮点击率(点击支付次数/页面展示次数)仅有50%+。 28 | 29 | 对比我们内部相同的H5服务,转化率过低,远远不符合我们对业务预期效果。 30 | 31 | 核查3种数据分析,我发现页面展示次数过高,并且三种方法的页面展示次数有较大差异,其中: 32 | 33 | 微信自定义数据统计pv(页面展示次数) 约等于 公司内部第三方数据统计pv(页面展示次数) 34 | 微信实时统计pv(页面展示次数) < 自定义数据统计 (包括微信自定义和公司内部第三方字数据统计) 35 | 36 | 微信实时统计pv的统计方法不得而知,而另外两种方法均是在onshow事件中触发。 37 | 38 | 39 | 40 | ### 原因: 41 | 排查过程中,发现页面在涉及到支付时,微信调起弹窗,会再次触发onshow事件,从而导致pv数重复发送。 42 | 43 | 对于微信来说,支付完以后会触发支付完成页,如图所示: 44 | 45 | ![微信支付完成页](https://github.com/find-xcx-bugs/xcx-bugs-list/blob/master/images/3-wechat-success.jpg) 46 | 47 | 点击完成后再次回到页面会继续触发onshow事件。 48 | 49 | ### 解决方案: 50 | 从技术上来说,onshow事件本应设计如此。页面再次展示应该触发onshow。 51 | 52 | 从业务上来说,onshow事件是应该用来做pv统计的。但因为涉及到类似支付的事情,业务方需要自己控制pv发送时机。 53 | 54 | 目前我的解决方案:onload中统计。 55 | 56 | ![第三方数据统计代码](https://github.com/find-xcx-bugs/xcx-bugs-list/blob/master/images/3-onload-report.png) 57 | 58 | 问题虽小,记录下来的意义更大。 59 | 60 | 61 | -------------------------------------------------------------------------------- /docs/5-mini-program-import.md: -------------------------------------------------------------------------------- 1 | # 小程序退出后扫码再进入,“外部”代码不会再次执行 2 | 3 | ## 作者: [蒋欢](https://github.com/Dragon-Rider) 4 | 5 | ### 问题: 6 | 小程序退出后再次扫码进入,只会执行生命周期函数里的代码,“外部”代码不会再执行。 7 | 8 | ### 具体描述: 9 | 在我们的项目里,我们会将一部分本地变量不写在小程序 pageConfig 的 [data][1] 中,而直接在文件头进行声明。这样是为了减少 data 的大小,加快页面渲染速度。但这也无意中带来了新问题,我们看看下面的例子。 10 | 11 | **出错的index.js文件**: 12 | 13 | ```` 14 | const localFlag = true; // “外部”代码,仅执行一次初始化,第二次扫码不会执行! 15 | 16 | const pageConfig = { 17 | data: { 18 | text: 'init data' 19 | }, 20 | onLoad(this, p) { 21 | console.error("localFlag默认为:", localFlag); 22 | 23 | // Do something you need... 24 | localFlag = false; 25 | } 26 | } 27 | 28 | Page(pageConfig); 29 | ```` 30 | 31 | 按照以上代码运行,用户初次扫码时,localFlag的值为true。可是,**当用户退出小程序,再次扫码进入时,localFlag没有再初始化,而为false了**。如下图所示: 32 |
33 | 34 |

图1 用户二次扫码进入小程序,localFlag为false

35 |
36 | 37 | 如何避免上述情况的出现呢? 38 | 39 | 其实也很简单,就是在文件头部只做本地变量声明,而不做定义。将定义部分放在生命周期函数(如:onload)内。具体代码如下: 40 | 41 | **正确的ndex.js文件**: 42 | 43 | ```` 44 | const localFlag; // 只做变量声明而不定义 45 | 46 | const pageConfig = { 47 | data: { 48 | text: 'init data' 49 | }, 50 | onLoad(this, p) { 51 | localFlag = true; 52 | console.error("localFlag默认为:", localFlag); 53 | 54 | // Do something you need... 55 | localFlag = false; 56 | } 57 | } 58 | 59 | Page(pageConfig); 60 | ```` 61 | 62 | 如此,每次进入页面 localFlag 都会被置为 true 了。 63 | 64 | ### 环境: 65 | IOS 和 安卓 均可稳定复现。 66 | 67 | ### 原因: 68 | 这看起来属于小程序自身的模块设计方式导致的。推测即使退出小程序,之前打开的页面也没有做到真正卸载,而处在内存之中。下次再次进入同一个页面时,会被唤起。 69 | 70 | ### 解决方案: 71 | 只在头部代码进行本地变量声明,**而不定义**。将本地变量的定义放在生命周期函数中去。 72 | 73 | ### 风险: 74 | 属于小程序开发的经验积累相关。 75 | 76 | 77 | [1]: https://mp.weixin.qq.com/debug/wxadoc/dev/framework/app-service/page.html 78 | 79 | 80 | -------------------------------------------------------------------------------- /docs/4-vConsole.md: -------------------------------------------------------------------------------- 1 | # vConsole 将已清除掉的log记录再次打印出来,造成代码没有生效或者微信扫码错误的错觉 2 | 3 | ## 作者: [蒋欢](https://github.com/Dragon-Rider) 4 | 5 | > 这是一个开发工具 `vConole` 带来的问题。虽然不大,但是如果你早已习惯 chrome 开发面板的使用方法,则很容易在开发中导致误解。 6 | 7 | ### 问题:vConsole 打开后点击 clear 清除log,再次操作小程序。发现会将之前清除掉的log再次打印出来,然后才打印新的log,造成代码没有生效的错觉。 8 | 1、首先,解释下什么是 `vConole` ? 9 | `vConsole` 是腾讯开发的一个轻量、可拓展、针对手机网页的前端开发者调试面板, 具体介绍见请:[vConsole官方仓库][1]。 10 | 11 | 2、小程序里的 `vConole` 工具 12 | 微信小程序在开发过程中也可以使用 `vConole` 辅助在手机端进行调试,具体方法是:点击开发版小程序又上角 `...` ,之后选择 `打开调试` ,如下图所示。 13 | 14 |
15 | 16 |

图1 vConsole使用介绍

17 |
18 | 19 | 3、在使用小程序开发工具中,由于 log 记录过多,我们在一次调试过程中可能会使用 `clear` 来清除log,事实上 `clear` 没有像 chrome 的 “clear console” 一样,做到真正的清除 log。而是将 log 清除后缓存了起来。待你下次刷新页面时会将两次 log 一起打印出来。我们在调试 “[小程序扫码bug][2]” 时就遇到了该问题。 20 | 21 | #### 举例: 22 | 23 | a、我们调试时,会在 onload 内将该函数参数打出,读取微信扫码的数据。 24 | ```` 25 | onLoad(this: IndexPage, p) { 26 | console.log('打印p参数打印p参数打印p参数打印p参数打印p参数打印p参数'); 27 | console.log(p); 28 | } 29 | ```` 30 | b、当我们第一次扫码调试时,针对商户 “巴蜀传香” 打出的log结果如图所示,之后我们**点击 clear 清除了调试工具的 log 记录**并退出。 31 | 32 |
33 | 34 |

图2 第一次扫描二维码得到的结果

35 |
36 | 37 | c、当我们第二次扫不同的二维码进入小程序时,预期onload的参数会变化。然而发现店铺变了,但扫描的结果没有改变(实际上二维码变了,店铺与log也应该会改变)。 38 | 39 |
40 | 41 |

图3 第二次扫描二维码得到的上次缓存结果

42 |
43 | 44 | d、事实上,当你将 log 记录继续往下滑会发现,新的 log 记录也已打印出来。**说明即使你之前点击了 clear ,新的 log 也会因为缓存再次打印出来。** 45 | 46 |
47 | 48 |

图4 第二次扫描二维码得到的实际结果

49 |
50 | 51 | ### 环境: 52 | IOS 和 安卓 均可稳定复现。 53 | 54 | ### 原因: 55 | vConsole 会将已经 “clear” 的缓存再次打印出来。 56 | 57 | [微信反馈](https://github.com/Tencent/vConsole/issues/131#issuecomment-350980424):“这是小程序底层的一个问题,正在修复中,不是vConsole的问题哈。” 58 | 59 | ### 解决方案: 60 | 调试的时候需要多往后翻一下,找到各次对应的扫码 log 记录。 61 | 62 | ### 风险: 63 | 开发阶段,可能因为 log 判断错误,而造成误解。 64 | 65 | [1]: https://github.com/Tencent/vConsole/blob/dev/README_CN.md 66 | [2]: https://github.com/find-xcx-bugs/xcx-bug-list/blob/master/1-qrcode-history.md 67 | --------------------------------------------------------------------------------