深入理解支付宝小程序 -- web Components、rpx 篇


web Components

微信小程序

调试ide版本:v1.02.1907300
微信小程序 ide 使用 nw.js 开发,我们可以尝试打开它的控制台

document.getElementsByTagName('webview')[0].showDevTools(true,null)

我们拿到了微信小程序的渲染层页面,注意body中的标签 wx-viewwx-open-data,这看起来是一种类似 web Components的实现,这是一种浏览器原生支持的组件形式。

支付宝小程序

调试 ide 版本:2.1.9
支付宝小程序是使用 Electron 开发的,我们也可以打开它的控制台:

document.getElementsByTagName('webview')[1].openDevTools()

外部套着模拟器,内部是iframe,这里应该就是小程序本身代码,也就是 iframe 部分

这里并没有和小程序类采用了组件的形式,而是原生标签 + class的形式。尝试全局修改a-view的样式,竟然真的生效了。
进一步测试发现,标签选择器会被编译成.a-*的形式,不局限于已有的标签,如果是a标签也会这样编译。

分析

微信小程序的标签需要基础库去解析,支付宝这里似乎是没有的,他直接编译成了html,并且html没有做到样式隔离,能够被外部影响。如果无意中写了类似标签,还是非常难以排查的。

rpx

rpx 是小程序平台的响应式单位。

rpx(responsive pixel)可以根据屏幕宽度进行自适应,规定屏幕宽为 750rpx。以 Apple iPhone6 为例,屏幕宽度为 375px,共有 750 个物理像素,则 750 rpx = 375 px = 750 物理像素,1rpx = 0.5 px = 1 物理像素。

微信小程序

viewport 设置

<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1">

rpx 转换:

var BASE_DEVICE_WIDTH = 750;
var isIOS = navigator.userAgent.match('iPhone');
var deviceWidth = window.screen.width || 375;
var deviceDPR = window.devicePixelRatio || 2;
var checkDeviceWidth =
  window.__checkDeviceWidth__ ||
  function () {
    var newDeviceWidth = window.screen.width || 375;
    var newDeviceDPR = window.devicePixelRatio || 2;
    var newDeviceHeight = window.screen.height || 375;
    if (window.screen.orientation && /^landscape/.test(window.screen.orientation.type || '')) newDeviceWidth = newDeviceHeight;
    if (newDeviceWidth !== deviceWidth || newDeviceDPR !== deviceDPR) {
      deviceWidth = newDeviceWidth;
      deviceDPR = newDeviceDPR;
    }
  };
checkDeviceWidth();
var eps = 1e-4;
var transformRPX =
  window.__transformRpx__ ||
  function (number, newDeviceWidth) {
    if (number === 0) return 0;
    number = (number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth);
    number = Math.floor(number + eps);
    if (number === 0) {
      if (deviceDPR === 1 || !isIOS) {
        return 1;
      } else {
        return 0.5;
      }
    }
    return number;
  };

支付宝小程序

viewport 设置

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0, viewport-fit=cover">

根字体设置:

// af-appx.min.js
function Sy() {
        _y = document.documentElement.clientWidth, xy = document.documentElement.clientHeight, wy = Math.min(_y, xy);
        var t = 100 * _y / 750 + "px";
        document.documentElement.style.fontSize !== t && (document.documentElement.style.fontSize = t)
    }

编译之后的样式文件:

/*ACSSCompileContext:{"atImports":[]}*/var internal_style;

internal_style = ".title {background:red;font-size:0.5rem}.ttt {font-size:0.5rem}.hair {height:1px}.a-view {background:orange}.ttt .a-a {font-size:100px!important}#id {font-size:1rem}";
export default internal_style;

分析

微信小程序,rpx 被转换成了px。支付宝小程设置了根字体,rpx 最终被转换成了 rem。支付宝根字体的转换找到了代码,rpx 转 px 没有找到代码,猜测,应该是在编译过程中已经进行了转换,我分析的运行时部分没有这部分代码。

总结

貌似一样的众多小程序,仔细分析,发现还是有很多很多的不同,某些不同,还是基础架构层面的不同,深入分析,应该可以挖掘出更多有意思的东西。

参考


 上一篇
深入理解支付宝小程序 -- sjs 篇 深入理解支付宝小程序 -- sjs 篇
在平时的开发中,我们很少会主动去使用 sjs,程序能够运行,不加班,已经是极好的事情了:)。但我们这个系列不可以,深入原理部分,必须对每一个细节都了若指掌,差之毫厘谬以千里。 sjs 定义以下是官方定义: SJS(safe/subset
2021-07-31
下一篇 
深入理解支付宝小程序 -- 准备篇 深入理解支付宝小程序 -- 准备篇
深入理解总是困难的,耐心和寂寞相伴,沉默和思考相随,进一退三,推着我们前进,是对未知的渴望,是残存的技术热情。 本系列,将开始对支付宝小程序的运行时的分析,网上资料比较少,一些猜想不一定对,我姑且说之,您姑且听之。因为微信小程序的先驱性
2021-07-31
  目录