第三周:来拷打一下小程序

博客新增了许多功能,包括作者资料,友链,样式优化,社交链接等等,其中Steam社交链接格式不正确,我给博客主题的作者提了一个 pull request,这是我的第一个pr,只修改了一个单词,很幸运地被merge了, 如果你也在使用DoIt主题,那么说不定其中某行代码就是我写的😋

博客也增加了RSS功能,欢迎订阅!


最近回家后琐事明显增多了,基本没什么产出,就来拷打一下之前遇到的一些东西吧

大概一个月前帮一位同学做了一个很简单的小程序,只有一个按钮,这其中我遇到了小程序的不少槽点

先简单介绍一下小程序是什么,小程序和web页面很像,但小程序的JS执行线程和渲染线程是分开的,这是最大的区别,也造成了很多麻烦的东西

小程序的逻辑层和渲染层是分开的,逻辑层运行在 JSCore 中,并没有一个完整浏览器对象,因而缺少相关的DOM API和BOM API。这一区别导致了前端开发非常熟悉的一些库,例如 jQuery、 Zepto 等,在小程序中是无法运行的'

官方称将JS线程和渲染线程分开的目地是为了提高页面渲染性能,避免性能不足的移动设备出现卡钝、动画生硬等问题

以下是我的批评

自绝于npm庞大的生态,而且造成了不必要的麻烦

宣传口径中,小程序的一个优点是不需要让用户安装app,android和ios用户都能使用。然而小程序的运行环境非常割裂

运行环境逻辑层渲染层
iOS,iPadOS, MacOSJavaScriptCoreWKWebView
安卓V8基于 Mobile Chromium 内核的微信自研 XWeb 引擎
windowsChromium 内核Chromium 内核
小程序开发者工具NWJSChrome WebView

可以看到以上平台基本把各种环境来了一个排列组合,然而开发者不一定有这么多设备可以测试。即使有足够多的设备,小程序写好后还需要在不同平台测试,检查平台差异,徒增工作量

WXSS 渲染表现不一致:尽管可以通过开启样式补全来规避大部分的问题,还是建议开发者需要在各端分别检查小程序的真实表现。

以上已经提及DOM不完整,此外因为JS环境割裂,导致不同平台的DOM API不仅仅是不完整的,而且每个平台的DOM API支持情况也不相同

这导致了开发者不确定某个DOM API在其他平台是否可用,最后干脆都不使用了(小程序到底可以使用哪些DOM API,官方并没有文档说明)

最坑的情况是,在小程序开发者工具中可用,但在真机不可用(因为小程序开发者工具的JS环境跟真机也不相同)

以上似乎还是比较合理的,但实际使用下来就会发现小程序非常坑的一点
我开发的小程序是对接阿里云的某个API,涉及加密,URL参数处理等。加密直接从网上找了一个函数实现,剩下的字符串处理被小程序坑了两次

atobbtoa这两个函数是DOM API提供的将base64和二进制数据相互转换的配套函数

我使用的场合很简单,只需要将一个普通的字符串使用base64编码即可,这种情况下应该使用atob

小程序并没有atob,但讽刺的是它有btoa。发现这一事实后我相当的愤怒,因为atobbtoa 只是简单的字符串处理函数而已,小程序的JS环境对这两个配套的函数,居然能作出只支持其中一个的行为。此外, 即使JS环境就是这么随意,小程序官方也完全可以提供一个JS实现的btoa,并在小程序执行前动态绑定到DOM上,避免给开发者造成 不必要的麻烦


有人可能会说,既然btoa只是一个简单的字符串处理函数,为什么开发者不能自己造一个轮子呢?

因为base64编码是一种标准,涉及诸多细节,例如查码表,位数补齐等等,所以实现一个符合标准的btoa是一个简单但琐碎的工作,这种工作一般是由标准库完成,而不是由开发者完成

URLSearchParams表示url的查询参数,我使用这个函数将参数组装成查询字符串,简单来说,有一些参数

JS

const params = {
    a: 1,
    b: "aaa"
}

组装成a=1&b=aaa的格式,看起来很简单,但查询字符串需要符合URL标准,即只能使用URL安全的字符,也就是某些URL不安全的字符需要转义,所以这也是一个简单但琐碎的工作

毫不意外地,小程序没有提供这个API,于是我在确认查询参数中不存在URL不安全字符后,造了一个非常简陋的轮子

甚至我找到一篇问答抱怨URLSearchParams的支持情况,其中的部分回答

都快2024了还不支持………………..

懂不懂就说背锅,这么基础的东西都不支持

以上原因,导致一个非常简单的需求,我都花了几小时实现,开发体验极差。简单的字符串处理函数都不支持,我开发后的感想就是,小程序官方无作为。。。

我对小程序的质疑如下

  1. 如果它真的是一个先进的技术,为什么我至今没看到国外有使用?
  2. 很多APP都有小程序,他们提供的平台能力也不一样(例如微信小程序和支付宝小程序),为微信开发的小程序没法在支付宝使用
  3. 接上,为了解决小程序的“跨平台”问题(跨平台这个词真是讽刺),有uniapp这样解决方案,但uniapp本身就是一个不逊于小程序的大坑
  4. 小程序由一家商业公司维护,而web有W3C维护标准,一群巨头浏览器厂商竞争,我为什么要开发小程序而不开发web?
  5. chrome没有将渲染和JS执行分成两个线程,但chrome在移动设备上的表现也不低于小程序,将渲染和JS执行分开是否有必要?

前文拷打的小程序,我认为它出现的一个原因是android的webview非常割裂,新机型和老机型的webview版本相差太多,以至于微信选择了另一条与web标准并立的方式,让许多老机型也能 正常使用web

私以为,webview割裂的一个原因是,国内android无法使用google框架,所以也无法使用google play这个在安卓生态中占据统治地位的应用商店, 所以系统自带的webview只能依靠国产安卓vendor提供更新

然而很多老机型,国产android厂商很久,或者根本不推送更新了,也就导致老机型的webview永远停留在了一个很旧的版本,这样的机型早已被日新月异的Web标准抛弃


此外,国内很多移动互联网用户并没有经历桌面互联网时代,而微信占据了国内移动互联网的绝大部分流量,自然有能力另起一套方案与占据了互联网大部分入口流量的google竞争, 可以顺理成章地得出,小程序只是微信为了圈住流量,将微信成为流量入口的一个工具而已。

前文提及小程序的DOM API不完整,实际上小程序对ECMA Script标准的支持也不完整,对于这种情况,可以使用一种被成为pollyfill的技术,即使用已有的东西去模拟出缺失的东西

微信小程序内置了core.js,但因为时间有限我并没有搞明白怎么使用。相反,我发现有一个开源项目polyfill.io,只需要引入它的一个JS文件,它的服务器会自动根据UA判断出缺失的功能, 并只发送能够polyfill这些缺失的功能的JS脚本

在这篇文章写下的几天前,polyfill.io被发现向千万个站点返回了恶意JS脚本,现在其仓库polyfillpolyfill/polyfill-service 已经被github封禁,polyfill.io也无法访问

这个现实非常可怕,因为我曾经也尝试过使用polyfill.io(虽然最终并没有使用),也让我产生另一个对小程序官方不作为的批评:小程序官方不提供足够的polyfill,导致开发者寻求第三方解决方案,但第三方不一定是安全的

实际上,以上提到的很多问题也许都能通过脚手架或框架避免,但我的观点仍然同polyfill,小程序不提供足够的能力,而将工作交给开发者,这造成了以下问题

  • 个人开发者:花费精力寻找并对比合适的脚手架
  • 企业:花费精力确认脚手架的安全性,稳定性