运行环境差异
- iOS:JavaScriptCore->WKWebView渲染
- Android:X5 JSCore来解析(X5基于Mobile Chrome 53/57 内核)
- DevTool:nwjs->Chrome Webview渲染
架构
两个线程 - 视图层(webView)->渲染页面
- AppService逻辑层(JSCore)->逻辑处理、数据请求、接口调用
setData完整流程代码
/*
setData 主流程精简还原,并非完整主流程,内有注释
*/
function setData (obj) {
if (typeof(obj) !== 'Object') {
console.log('类型错误'); // 并没有预期中的return;
}
let type = 'appDataChange';
// u.default.emit(e, this.__wxWebviewId__) 代码还原
let e = [type, {
data: {data: list},
options: {timestamp: +new Date()}
},
[0] // this.__wxWebviewId__
}];
// WeixinJSBridge.publish.apply(WeixinJSBridge, e); 代码还原
var datalength = JSON.stringify(e.data).length; // 第一次 JSON.stringify
if (datalength > AppserviceMaxDataSize) { // AppserviceMaxDataSize === 1048576
console.error('已经超过最大长度');
return;
}
if (type === 'appDataChange' || type === 'pageInitData' || type === '__updateAppData') {
// sendMsgToNW({appData: __wxAppData, sdkName: "send_app_data"}) 代码还原
__wxAppData = {
'pages/page1/page1': alldata
}
e = { appData: __wxAppData, sdkName: "send_app_data" }
var postdata = JSON.parse(JSON.stringify(e)); // 第二次 JSON.stringify 第一次 JSON.parse
window.postMessage({
postdata
}, "*");
}
// sendMsgToNW({appData: __wxAppData, sdkName: "send_app_data"}) 代码还原
e = {
eventName: type,
data: e[1],
webviewIds: [0],
sdkName: 'publish'
};
var postdata = JSON.parse(JSON.stringify(e)); // 第三次 JSON.stringify 第二次 JSON.parse
window.postMessage({
postdata
}, "*");
}
::: tip 通信方式
系统层的WeixinJsBridage
两边提供的 evaluateJavascript 所实现。
即用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立环境。
数据绑定原理
- 开发者工具:window.postMessage
- IOS:window.webkit.messageHandlers.invokeHandler.postMessage
- Android:WeixinJSCore.invokeHandler
数据传输实际是一次 evaluateJavascript 脚本过程
:::
Native组件
- Native实现的组件
<canvas/> <video/> <map/> <textarea/>
- Native组件层在WebView层之上
小程序存在的问题
小程序仍然使用WebView渲染,并非原生渲染
需要独立开发,不能在非微信环境运行 。
开发者不可以扩展新组件。
依赖浏览器环境的js库不能使用,因为是JSCore执行的,没有window、document对象。
WXSS中无法使用本地(图片、字体等)。
WXSS转化成js 而不是css。
WXSS不支持级联选择器。
小程序无法打开页面,无法拉起APP。
小程序的优点
提前新建WebView,准备新页面渲染。
View层和逻辑层分离,通过数据驱动,不直接操作DOM。
使用Virtual DOM,进行局部更新。
全部使用https,确保传输中安全。
加入rpx单位,隔离设备尺寸,方便开发。
::: tip rpx(responsive pixel):
可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。
如在 iPhone6 上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
设备 | rpx换算px (屏幕宽度/750) | px换算rpx (750/屏幕宽度) |
---|---|---|
iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
iPhone6Plus | 1rpx = 0.552px | 1px = 1.81rpx |
:::