感谢钉钉小程序这些年赏我饭吃🍔,嗝~

avatar
@古茗科技

前言

弱弱的问,有多少同学知道钉钉也是有小程序的?那有多少同学参与过开发过钉钉小程序?深度参与过呢?有多深,至少50个页面起吧!一轮筛选过后应该没剩下多少勇士了,古茗应该算是勇士之一了。

在两年前我们决定all in钉钉小程序,因为h5的一些体验问题、业务需要快速迭代,所以小程序是首选;本身公司所有的用户、组织等数据也都是绑定在钉钉上,所以最后敲定钉钉小程序。tob业务目前有6个应用是由钉钉小程序承载的,页面500+,除了小程序还有h5应用也是跑在钉钉容器内,表单引擎、组件库、request、oss、F2、debug工具库等配套基建也是围绕着钉钉小程序卷了一遍,客观来说真的是靠钉钉小程序吃饭啊!

但是在这两年和钉钉小程序的py交易中,总能感受到钉钉小程序承接业务能力的天花板很低,业务稍微发力就能够到,以至于给产品留下了“坏印象”(前端不太行~😒)。所以我们也一直主动保持和钉钉小程序团队的沟通,几乎每周都会反馈问题和建议。但是伤心的是大部分的问题都是要靠自己解决,直到前几天的一个工单让我绷不住了。

批评

准备好了,开始喷了。

诡异的数字键盘

是什么原因让我必须站出来"夸"一下它呢?就是钉钉小程序ios端不能正确弹出数字键盘这件事的让我彻底绷不住了。冷静,我还是一名前端er,让我们回归技术

我们都知道手机浏览器会根据inputtype 类型唤起对应类型的键盘,手机可以直接点击查看

小程序侧也是针对 input 提供了对应的配置。但是你知道吗,钉钉小程序的这个配置就是个摆设,

于是我们怀着揣着疑问去钉钉社区里面提问,得到的回复如下,不知回复的人是否是官方技术,很震惊

得不到结果,接着又去官方提了工单,得到的肯定的回复是 ios webkit存在bug,需要等 apple 修复,我们(钉钉)处理不了 瞬间懵逼

单纯的我想那这个问题肯定很严重吧,去看看微信吧,结果微信是ok的,如图真机验证。

不对,可能微信小程序是同层渲染更高级,钉钉小程序暂时做不到吧。

那我们再去看抖音小程序,结果抖音也是ok的。啊~这...

那我们再去看看同父异母的支付宝小程序吧,咦~虽然展示有点奇怪,但至少能弹出数字键盘可以满足需求。

果然师出同门,看来弹出ios原生数字键盘真的有难度

于是找到钉钉官方希望他们能抄支付宝的方案,至少排期处理一下。得到的回复是 不予处理,你们自己可以写一个数字键盘 我特么...

有bug正常,谁都不能保证程序完美无缺,但是对待bug的态度要正确呀~这态度真的不太行

尤其是作为开放平台对于这么明显的bug说摆烂就摆烂吗?而且真的很难处理吗?真的是 webkit 的锅?第一张图的demo就是用钉钉webview容器打开的,为啥能正确弹出呢?

我这里也打个问号,希望懂的大佬帮忙答疑解惑一下

小程序开发工具2.0,KPI IDE?

不吐不快,接着夸

微信和支付宝都有对应的开发工具,我们开发钉钉小程序实际上用的也是支付宝IDE,但是前段时间偶然间发现钉钉官方出了一个钉钉小程序专用的开发工具,好奇的我当然要尝鲜一下,看看有哪些体验升级,于是下载安装

果然钉钉从不让我失望,帅不过三秒,dd.getAuthCode 无论如何都是请求失败,这个接口是拿钉钉授权token的,最前置的api,拿不到token后续什么都干不了

怎么办?惯例去找官方吧,得到的回复我都看笑了 别用这个,推荐我使用支付宝IDE进行开发 我特么~那你搞这个干嘛,还2.0

其实这个问题5.15我就提的工单,直到发文这天我还特意打开验证,依然没有修复,效率杠杠滴,难道真的只有我在用?

工单群已经被关闭了,无图无证据,这个回复就当我编的,纯当我自己使用不当,ok?反正我也不会再用了

慎用 regeneratorRuntime

大概半年前,小伙伴的电脑本地构建后访问一直报错,前端报错为 regeneratorRuntime_default is not function,但是上CI平台构建测试环境都是正常的,龟龟最烦这种问题,好在能稳定复现。

自己先模拟复现,一步步debug,因为我们中间还套了一层 Taro,重点都在排查 Taro 构建逻辑,排查到最后才往钉钉的构建链路上面想,排查到的结果真的是惊呆了😱😱,居然是钉钉在构建时来了一波偷天换日,甭管你是什么逻辑,只要是命名相同直接给你换掉。

钉钉小程序在编译时会内置一些变量,比如 regeneratorRuntime,应该还有其他的,估计支付宝小程序也这样(我没有验证过)

20230711150104.jpg 我理解和常用的环境变量 process.env.xxx 一样,在构建时会做替换。问题就出现在这,Taro 在特殊场景下会将 await 函数转化成如下

// 部分代码只为了展示
...
regeneratorRuntime = webpack_required(20)

regeneratorRuntime_default = wepack_required.n(regeneratorRuntime)
...

碰巧命名撞上了,数据结构变了,页面直接GG。

我们去看了官方文档,只字未提!!! ~这么重要的黑盒不说明一下吗?

又想吐槽了,文档质量真的,想要的总是查不到,垃圾话一堆,有的时候都是直接看支付宝文档。 咱不拿微信小程序开发文档对比,就对标一下竞品飞书开放平台,不说别的,单拿出小程序的开发文档对比真是的被吊打。

更更重要的是当时也给钉钉官方提了意见可以把类似的说明加上去,他们说会加的;对,是的,他们会加的,几个月过去了现在好像还没加,可能今年内会加上?

还有这种编译时变量能定义的稍微 “抽象” 一点吗?别这么轻易就命中,你看一命中,半天的时间都给了钉钉小程序,你说是不是钉钉小程序赏饭吃。

我想上传超过一分钟的视频

看似很简单的需求,和钉钉小程序官方拉扯快俩月了,到现在都没有一个结论。

我们这边有大量上传下达的场景,比如拍出杯操作流程视频,一般都是在三分钟左右,本来门店就很忙没多少时间处理总部管理事项,现在一个视频还得分几段拍。真的每天都有人在吐槽

那有人会问,不能先拍摄再上传吗?答案是不行,钉钉会崩溃,可能大部分内存处理不好的app都会崩溃;首先钉钉小程序不提供分片上传,只能小程序端直推,内存占用会很大;并且大部分的门店工作机配置都不是很高,上传成功率会大大降低

我们也想了几个解决方案:

  1. chooseVideo 增加拍摄时长
  2. chooseVideo 降低分辨率,延长拍摄时长
  3. 分片上传
  4. 先拍摄->门店去压缩->再由钉钉小程序上传
  5. 不在钉钉小程序内处理上传

123钉钉目前还是都不支持,45考虑到操作链路也被否定掉了

恳请钉钉小程序团队考虑下,至少给我们一条路,工单很早就提了,适当的时候排下期?隔壁飞书这点飞的比你们快呀~

除了上传视频,钉钉的 bridge api 在文件的处理上也是有缺失的比如 openDoucemntchooseMessageFiledownloadFile (不能处理文件)。

缺也就算了,有些 api 还不稳定,比如蓝牙相关 api,特定的场景就需要断开重连,而且稳定复现,最后我们只能用提示兜底。

“永远”升不上去的版本

实话实说,钉钉小程序的版本升级真的太不稳定了,刚迁移到钉钉小程序我们线上环境等着验证,它就是不升级,我们就真的傻乎乎的等了一个多小时,是真的!各种清除缓存没有用的,还是太年轻。后面我们成长了,直接卸载钉钉重新安装,这样每次打开小程序只都能同步获取最新版本

别跟我说用咋不用体验版?有些场景本来就只能发版后正式环境验证,比如一些消息类场景。

几乎团队内所有人都问过我一个问题,钉钉小程序这版本是咋么个玩法?怎么还是旧版本?怎么还不升级?

我们如是问了钉钉官方,得到如下回复:

  • 策略1 若检查到本地没有对应的离线包(首次打开), 则客户端会发起同步更新, 下载最新离线包;
  • 策略2 若距离上次发起更新超过 48 小时, 则客户端会发起一次同步更新,下载最新离线包;
  • 策略3 若距离上次打开该小程序超过 10 分钟但小于 48 小时, 则客户端会在展示本地离线包给用户的同时, 发起异步更新, 获取最新离线包信息, 有新版则静默下载更新.(下次启动即为新版本,部分保活小程序需要重启钉钉进程);
  • 策略4 若距离上次打开该小程序不超过 10 分钟, 不发起更新;

说实话,得到版本升级策略后我看了三遍,突然发现有点头疼~(开玩笑)

反正按回复的策略,我们验证的结论是:不能全信

除此之外还有一些疑惑:

  1. 新版本发布48小时后依然有旧版本日志(可能一直没有退出)
  2. 策略3何时触发离线包下载?
  3. 48小时对于紧急发布太久了

小程序的更新机制就不过多做介绍了,有需要复习点击 小程序的更新机制小程序更新策略介绍 了解下

无法感知冷启动

钉钉小程序在版本管理这一块感觉还有一个点,就是没有启动页面,所以无法感知冷启动。微信小程序的启动页

为什么会要纠结冷启动呢?因为冷启动会触发版本check,有新版本会异步下载新版本离线包,钉钉文档也是这样描述的。

小程序相对于传统的spa应用中间多了缓存层,小程序也会制定各种策略来管理缓存,好处不言而喻,坏处就是开发者想要精准控制版本相对来是比较困难,所以想要主动控制版本选项之一就是依赖冷启动来下载新版离线包,但是可以被感知的这一环节被阉割了。

那么来致敬下微信,微信是有几个准确的时机会销毁小程序,销毁后下一次打开也必定是冷启动,而且误差可控

  1. 小程序切到后台看不到后,一般 5 分钟内就会被微信客户端主动销毁;
  2. 在微信客户端下拉最近访问的小程序里删除,也会从内存里销毁;
  3. iOS 下如果 5 秒内连续大于等于 2 次的内存告警,会被销毁;

钉钉相应的功能也是有的,比如下拉副屏管理小程序。

但是1、2条我们也都验证过,从结果看并不能准确触发新版离线包的下载。

微信小程序在版本管理最近推出了重磅更新 「优先使用本地版本设置」「小程序最低可用版本设置」,也就是说可以同步升级小程序;咱们钉钉啥时候借鉴一下,这个配置简直一劳永逸,b端应用就需要这样的功能。

header 有坨翔

依然是ios端,有点心疼钉钉小程序了,每次都是ios找麻烦

自定义header的场景,左侧绿色部分不能点击,点击事件不能透传被阻止冒泡,像盖了脱翔,真恶心

本来真实的业务左上角是个头像位,点击弹出操作侧边栏,ios怎么都点出...我们只能硬生生的用 username 现做占位

好在提了工单之后,这么明显的bug不能在不处理了(面子上过不去),答复是8月的版本会修复,我们是六月末提的,可以接受,至少是有盼头了

这是谁的菊花?

看看这是谁的菊花loading,我们花了小半天的时间排查,确定了,这个是钉钉的菊花!

起因是有用户反馈访问钉钉小程序,一直卡死在这个loading页面,看来晚饭又有着落了🍗。

于是对遍了项目内所有的菊花,没有一个跟它长得一样,它太紧致了~ 最后发现特喵的这个 loading 根本就不是我们的,压根就没有进入到我们的小程序,所以我们根本也无法控制。

气不打一处来,于是在反馈群敲下 "**钉钉",最后离职战胜愤怒😡,一字字退回,最后 "对不起,给你添麻烦了,您在切换到4G试试的,我们也会继续跟进的",估计客户也在想:"天天就知道道歉,啥也不是"

直到前几天还有用户反馈这个问题,没记错这个问题应该已经一年多了,我们也很无奈,鞭长莫及啊!

惯例我们其实早就联系钉钉,钉钉小程序官方也一直没有回复我们这个loading原因。

自己看现象分析应该是小程序容器初始化失败的loading,而且特定场景能稳定复现,尤其网络条件比较差时。

钉钉小程序官方大大抽空看看吧,至少给个官方话术让我们回复用户也好,敬礼了

maxlength 不生效

在来一个ios端的问题,嘻嘻,趁你病...

textarea maxlength 配置后,再有换行 + 空格的场景下,maxlength限制会失效,可以无限输入;钉钉官网的组件demo都可以复现

反馈给官方后,答复很熟悉,ios系统问题,不予处理

无灰度控制

目前发版还没有控制灰度的功能,所以只能自己处理,我们有两套解决方案

  1. 耦合到代码内,通过配置圈定范围来进行灰度控制
  2. 新创建灰度小程序,在由外层做流量分发

要是支持了就好了,我点一百个赞。估计你们也不会理我,全当我yy好了

长列表性能问题

老生长谈的话题了,同样的场景(一年区间的日历组件平铺) 一些低端机已经很卡了,尤其是在组合了一些动画效果后,但是webview打开毫无压力

也不是钉钉小程序自己的问题,所有小程序应该都是很头疼的场景,中间转换好几层后性能肯定会有丢失。

但是有一说一,对比过微信小程序,同机型同代码,微信小程序流畅度确实好很多~

这里也给ios正名,渲染性能差别不大,主要是安卓的低端机,卡起来很要命

最后的解决方案是我们自己实现懒加载

page-meta

page-meta 是一个小程序的原生组件,可以动态修改一些页面根节点的数据,我们有些需求需要用到这个组件,钉钉还是一句话 不支持

师出同门支付宝小程序已经实现了,适当的时间copy下?

点赞

钉钉小程序也不全是槽点,有些功能设计还是很开放的,有些建议的处理也还是很积极的

webview 通信

微信小程序想要和webview通信,在特定时机(小程序后退、组件销毁、分享等)才能通信;这种机制对h5应用渐进迁移小程序是非常痛苦的,好在钉钉小程序处理webview通信方案还是开放的

钉钉小程序提供 postmessage 方法,只要webview中的应用调用,小程序内就可以接受到回调,没有其他的限制。这种机制就可以做很多事情了,也就是做小程序的api h5应用全部能用

我们基于这点大概做了下面几个事情

  1. 登录授权同步
  2. 数据缓存同步
  3. 常用dd api映射
  4. 统一媒体资源上传
  5. h5落地页重定向到小程序

这套开放的通信机制还是对我们渐进迁移小程序帮了大忙的,当然现在我们已经80%业务已经完成了小程序重构,bridge 用的会越来越少

小程序版本管理

小程序不想IDE构建上传版本怎么办?想要自动化发布体验、正式版本怎么办? 内部小程序管理api钉钉小程序需要用它,现在它完全可以闭环整个钉钉小程序自动化发布流程,这个必须可以吹一波!

大约半年前发布流程

我们想要将钉钉小程序的完整发布流程都托管到内部的CI/CD平台上,但是当时的 dingtalk design cli 只是提供了简单的上传和预览,最后的发布版本还是需要到钉钉管理后台手动点一下,也就说最后一步要靠人工干预。

想象一下当天有两个版本在排队发布发布

  • 在线上回归时要分别发布体验预览版本
  • 验证通过后要分别到管理后台发布正式版本
  • 对应分支要push到master

如果不出意外还好,就怕但是,有人忘记点了正式版本发布呢?分支最后没有推送到master呢?已经推送到master但是线上有问题需要回滚呢?

因为小程序发布正式版本并没有相应的钩子回调导致我们CI/CD平台不能在正确时机的将分支合并到master,这之间有可能存在很多变数

所以我们给钉钉提了需求,希望增加发布预览版本、发布正式版本、回滚版本等cli。好在半年后,6月份功能发布了并且同步了我们

现在发布流程

  • CI/CD 打通gitlab和钉钉管理后台,全程只需在 CI/CD 平台上操作
  • 同时只能有一个条发布流程,允许多分支合并提测(不允许发布正式)
  • 验证回归完成后自动发布正式版本和合并master分支
  • 增加一键自动回滚,同时回滚钉钉小程序版本和代码

剧透下,后续我们负责CI/CD的同学也会做沉浸式的分享 😈😈😈

结尾

和钉钉的故事还很多,毕竟团队30多人或多或少都在和钉钉打交道,就算没bug早晚也得卷出bug。耳边忽然响起了渣渣辉的声音:你知道这几年我们是怎么过的吗,我们要想找bug,耶稣都拦不住

爱之深责之切,能承载我们这么多业务很感谢钉钉平台,说这么多,还是希望钉钉开放平台能做的更好,不只是看数据,更多是注重的开发体验和对待问题的态度,毕竟想要被产品大佬认可还是要靠钉钉小程序给的多不多 😄。

希望有一天能说出,钉钉小程序-你给的太多了。

钉钉小程序的开发者可能真的不多,但遇到疑难杂症也真的痛苦。相比微信小程序那么大的体量,活跃的官方答疑社区,钉钉有问题就只有一个给官方提工单这一个选择。 或许我们可以拉一个钉钉小程序的答疑群?抱团取暖?

最后来个小互动,如果微信小程序开发体验是10分,恳请参与过钉钉小程序开发的勇士评论区给它的开发体验打个分🚀🚀🚀

最后

关注公众号「Goodme前端团队」,获取更多干货实践,欢迎交流分享~