前言

昨日看朋友圈,据说有人花钱买star,不知道真的假的?以前以为只是大家开玩笑。今日早读文章由百度EUX@田光宇投稿分享。

正文从这开始~~

微信小程序

微信小程序包含下面四种文件:

js

json 配置文件

wxml 小程序专用 xml 文件

wxss 小程序专用 css 文件

{{ text }}

Page({

data:{

text:"这是一个页面"

},

onLoad:function(options){

// 页面初始化 options为页面跳转所带来的参数

},

// ........

})

微信小程序只能通过其 mvvm 的模板语法来动态改变页面,本身 js 并不支持 BOM 和 DOM 操作。

从开发工具看微信小程序架构

在 mac 端直接解压应用 发现 app.nw 文件夹,即开发工具源码。可以知道该项目由 nw.js 编写; 在 package.json 文件下找到应用入口:app/html/index.html。入口 js 为 dist/app.js 我们可以看到整个编辑器的大致逻辑。

但我们关心的是构建过程,在 weapp 文件夹下存在 build.js 文件。没有找到有用的信息,只看到了 upload 模块,包括对大小限制,上传包命名。

为此怀疑,微信小程序本身和 RN 类似。是在服务端打包成 native 语言的。但是通过,android 边框测试发现,微信小程序根本不是 native 原生内容。且,我们在开发工具上写 微信语法,竟然可以直接预览。说明一定有问题。

原生长这样的

编译过程

继续在 trans 文件夹下发现了编译模板。

transWxmlToJs wxml 转 js

transWxssToCss wxss 转 css

transConfigToPf 模板页配置

transWxmlToHtml wxml 转 html

transManager 管理器

用到的内容:

发现用到了一个模板:app.nw/app/dist/weapp/tpl/pageFrameTpl.js, app.mw/app.dist.weapp/tpl/appserviceTpl.js

wcc 可执行程序,wcc用于转转wxml中的自定义tag为virtual_dom

wcsc 可执行程序,用于将 wxss 转为 view 模块使用的 css 代码,使用方式为 wcsc xxx.wxss

在模板中,我们发现使用了 WAWebview.js 文件,WAService.js文件。 在 transWxmlToJs 中我们发现一段 generateFuncReady 事件的函数。对比注册该事件的函数在 WAWebview.js 中。

我们尝试使用 wcc 对input.xml 文件进行编译。

wcc -d input.xml

生成了一段脚本:

window.__wcc_version__ = 'v0.6vv_20161230_fbi'

var $gwxc

var $gaic =

$gwx = function (path, global) {

function _(a, b) {

b && a.children.push(b);

}

....

通过代码我们发现,调用 $gwx 函数会再生成一个有返回值的函数(前提是 path 填写正确);于是我们执行如下代码:

$gwx("input.xml")("test")

得出如下内容:

{

"tag": "wx-page",

"children": [

{

"tag": "wx-view",

"attr": {

"class": "section"

},

"children": [

{

"tag": "wx-input",

"attr": {

"autoFocus": true,

"placeholder": "这是一个可以自动聚焦的input"

},

"children": []

}

]

}

]

}

这应该是一个类似 Virtual dom 的对象,交给了 WAWebivew.js 来渲染,标签名为 wx-view, wx-input。

WAWebview.js

代码在最一开始提供的是兼容性工具,还有一个 WeixinJSBridge 引入。

接下来是一个 Reporter 对象,它的作用就是发送错误和性能统计数据给后台。

wx 核心对象,包含了 wx 对象下的 api。但是这里的 api 数量远远少于官方的 api 文档数量。

我们可以再代码里面发现,wx 下注册的 api 最终都会调用 WeixinJSBridge 方法,这个方法。应该是在打包的时候端上注入的。然而,我们也可以在 WAServeice.js 中找到该方法的定义。

所以我们得到了一个结论,WAService.js 是编辑器用来接受 wx 方法回调的代码。

wxparser 对象,提供 dom 到 wx element 对象之间的映射操作,提供元素操作管理和事件管理功能。

接都是对 exparser 对象的处理,包括注册 WeixinJSBridge 全局事件,Virtual dom 算法实现,样式注入等。介绍几个组件重要的内容

exparser.registerBehavior 注册组件基础行为,供组件继承。

exparser.registerElement 为各种内置组件,注册模板,行为,属性,监听器等内容

这里我们观察到,组件:wx-video, wx-canvas, wx-contact-button, wx-map, wx-textarea 等 behaviors 都含有 “wx-native” 属性。这是不是意味着,这类组件都是native 原生实现的呢。我们打开边框检查,发现这类组件确实都时原生的组件。

综上,微信小程序的界面有部分组件使用原生方式实现的,Native组件层在WebView层之上。大部分还是用前端实现的,这样解释了微信小程序的一个bug。

因为 scroll-view 是前端实现,在里面使用 native 组件,这样就无法监听滚动了。

WeixinJSBridge

组件是需要数据来渲染的,查看文档我们知道发送请求的 api 为 wx.request;通过上面分析,我么你知道 wx.request 实际调用的是 WeixinJSBridge。现在我们看看 WeixinJSBridge

WeixinJSBridge 真正发送处理数据请求的时这端代码;如果当前环境是 ios, 那么调用 WKWebview 的 window.webkit.messageHandlers.invokeHandler.postMessage。如果所处环境是 android 则调用 WeixinJSCore.invokeHandler(调用的时候,默认会带上当前 webviewID)。

WAService.js

在我们看的 WeixinJSBridge.js 分析中,我们并没有发现前端的通讯实现,路由能力,数据绑定等级制。进一步查看找到了一个 WAService.js 文件。 查看 WAService.js 文件源码:

在代码最开始,跟 WAWebview.js 一样的 WeixinJSBridge 兼容模块

然后是跟 WAWebview.js 一样的 Reporter 模块。

比 WAWebview.js 中 wx 功能更为丰富 wx 接口模块。(剩余的那部分 wx api 都在这里)

appServiceEngine 模块,提供 Page,App,GetApp 接口

为 window 对象添加 AMD 接口 require define

综上,WAService.js 主要实现的功能:

App( ) 小程序的入口;Page( ) 页面的入口

wx API;

页面有的作用域,提供模块化能力

数据绑定、事件分发、生命周期管理、路由管理

到这里我们得出结论,小程序的架构方案:

整个小程序由两个 webview 组成,代码分为 UI 层和逻辑层。UI 层运行在第一个 WebView 当中,执行 DOM 操作和交互事件的响应,里面是 WAWebview.js 代码及编译后的内容。逻辑层执行在(第二个webview 中)独立的 JS 引擎中(iOS:JavaScriptCore, android:X5 JS解析器;统称 JSCore;开发工具中,nwjs Chrome 内核),WAService.js 代码和业务逻辑。

当我们对 view 层进行事件操作后,会通过 WeixinJSBridge 将数据传递到 Native 系统层。Native 系统层决定是否要用 native 处理,然后丢给 逻辑层进行用户的逻辑代码处理。逻辑层处理完毕后会将数据通过 WeixinJSBridge 返给 View 层。View 渲染更新视图。

架构的讨论

微信的这种架构,对逻辑和UI进行了完全隔离,小程序逻辑和UI完全运行在2个独立的Webview里面来处理。那么这么做的好处是啥?总感觉更加麻烦了。除了小程序外,还有人采用这种架构设计么?

在网上搜索了一下,目前使用这种架构的项目还真有一个:去哪儿最新的 YIS 框架

YIS 采取了类似小程序的架构,分为逻辑层和UI层。UI 层运行在 WebView 中,而逻辑层运行在独立的 JS 引擎中。相应地,整个应用的代码,也分为两个大的部分,一部分运行在 WebView 中,一部分运行在JS引擎中。JS引擎计算DOM结构输出给WebView,WebView转发用户的点击事件给JS引擎。

该项目做法和小城十分类似,唯一缺少的就是没有 native 的组件吧。然而官方文档上也没有任何介绍,为什么要这么做,只是说更流畅了。

一些看法

传统 web 页面显示需要经历一下几个步骤:

webview 初始化

加载 HTML, CSS, JS

编译 JS

Render 计算

DOM Path

而利用小程序架构后,我们就可以将上述过程拆解成两部分并行执行: webview 部分:

webview 初始化

加载 HTML,CSS, JS (经过拆分后,体积大幅度减小)

编译 JS

等待页面需要的数据

反序列化数据

执行 Patch

渲染页面

等待更多消息

jscore 部分:

初始化

加载框架 js 代码

编译 js

加载业务逻辑 js 代码

编译 js

计算首屏虚拟 DOM 结构

序列化数据,传输

等待 webview 消息,或者 Native 消息

这样渲染进程和逻辑进程分离,并行处理:加速首屏渲染速度;避免单线程模型下,js 运算时间过长,UI 出现卡顿。 完全采用数据驱动的方式,不能直接操作 DOM,避免低质量的代码。 webview 和 jscore 可以预

当然这种架构方案也有这一定的缺点:

不能灵活操作 DOM,无法实现较为复杂的爱的暖效果

部分和 NA 相关的视图有使用限制,如微信的 scrollView 内不能有 textarea。

页面大小、打开页面数量都受到限制

需要单独开发适配,不能复用现有代码资源。

参考资料

微信小程序底层的实现原理是怎样的

微信小程序架构解析,工作原理解析

微信小程序架构分析

最后,EUX曾分享过:

为你推荐:

android 微信小程序原理,微信小程序架构原理相关推荐

  1. 编程内功心法「底层原理系列」 底层架构原理,分析CPU处理器鲜为人知的那些秘密

    前提概要 所谓,知彼知己百战不殆,针对于计算机的优化技术来讲,最底层也不过是针对于CPU技术的优化了,但是如果要区优化程序,涉及到CPU的执行能力,那必须要了解CPU的原理和概念以及执行过程等概念,所 ...

  2. 浅析微信小程序的底层架构原理

    一.小程序基础知识 小程序是基于WEB规范,采用HTML.CSS和JS等搭建的一套框架,微信官方给它们取的名字:WXML.WXSS,但本质上还是在整个WEB体系之下构建的.WXML说到底就是xml的一 ...

  3. 小程序商店刷榜_微信小程序游戏跳一跳刷榜原理解析!

    最近微信出了一个"跳一跳"的小游戏,这个游戏其实在之前有手机端版本,无奈微信借助强大的用户把这游戏又拿起来弄火了,而且通过最新版的微信可以看出,微信已经开始重视小程序的入口释放了, ...

  4. 2017年最后一篇文章:微信小程序游戏跳一跳刷榜原理解析!

    最近微信出了一个"跳一跳"的小游戏,这个游戏其实在之前有手机端版本,无奈微信借助强大的用户把这游戏又拿起来弄火了,而且通过最新版的微信可以看出,微信已经开始重视小程序的入口释放了, ...

  5. 教你理解微信小程序的生命周期和运行原理

    写微信小程序,他的生命周期不能不知道,不知道小程序就会出现各种bug而无法解决.小助君公众号带你学习小程序的生命周期和运行原理. 小程序由两大线程组成:负责界面的线程(view thread)和服务线 ...

  6. android用qq浏览器打开微信网页版,QQ浏览器怎么打开微信小程序?

    继微信.QQ 之后,QQ 浏览器上也可以使用小程序了. 现已实现与微信小程序打通.QQ 浏览器 Android 版现已上线小程序,在搜索的场景下,小程序嵌入 QQ 浏览器「搜索直达」,作为直接的内容承 ...

  7. 微信 android兼容性问题怎么解决方案,微信小程序兼容性问题

    本文我们来谈谈微信小程序系统兼容性的那些坑. 微信小程序兼容性问题 微信小程序发布一周多了,兼容性问题,特别是 Android 平台兼容性问题特别严重.据我观察,好多小程序掉到兼容性的坑里.掉坑里不要 ...

  8. 提高微信小程序的应用速度的常见方式有哪些? 小程序怎么实现下拉刷新? 简述微信小程序原理? 小程序的发布流程(开发流程)分析下微信小程序的优劣势?小程序授权登录流程? 小程序支付如何实现

    小程序部分常见面试题 提高微信小程序的应用速度的常见方式有哪些? 提高页面加载速度 用户行为预测 减少默认data的大小 组件化方案 分包预下载 小程序与原生App相比优缺点? 优点: 基于微信平台开 ...

  9. android源码大全 IOS游戏源代码打包下载 小游戏|视频教程 微信小程序源码带后台全套|公众号平台

    不断更新中,下面是2017-12-22更新部分 IOS_源码及视频一小部分: 开发环境:Xcode 基于cocos2d的tweejump跳跃游戏ios经典游戏源码.rar  https://pan.b ...

最新文章

  1. 机器学习中的一些概念
  2. php use include区别,php use和include区别总结
  3. java欧洲_java欧洲/明斯克时区问题
  4. 构建Blazor WASM和服务器一体化解决方案
  5. java同步队列_Java 中队列同步器 AQS(AbstractQueuedSynchronizer)实现原理
  6. Struts2回顾复习02
  7. TabBars代码解读之——Visual Studio的自动化接口
  8. paip.为什么使用多线程的原因.
  9. 增值税防伪税控系统到底是什么呢?
  10. java服务安装(三):使用appassembler
  11. 产品需求文档到底该怎么写?
  12. 关于360插件化框架Replugin竖屏修改为横屏解决方案
  13. HDU 5234 DP背包
  14. JavaScript 中的事件类型2(读书笔记思维导图)
  15. “庄家”:腾讯的投资“六合彩”
  16. NTFS下的USN日志文件研究
  17. Vue使用快速使用Echarts图标以及使用水滴图
  18. openCV人脸识别简单案例
  19. QR分解、RQ分解与SVD
  20. 微信录音amr音频文件转mp3格式

热门文章

  1. python循环10次怎么写_python循环怎么写
  2. 中概股周四异动:陌陌大涨18%新浪微博大涨11%
  3. 分析一下人际界限模糊的定义
  4. Python 3.X | 一文看懂不懵圈:位置参数(必选参数)、默认参数、可变参数、关键字参数、形参、实参...
  5. tensorflow分布式框架
  6. odoo ORM中的filed的关系映射的使用详解1
  7. Linux下time函数
  8. 微信小程序[ app.json 文件内容错误] app.json: app.json 未找到解决方法
  9. DC静态时序分析之时钟篇
  10. 机器学习: Viola-Jones 人脸检测算法解析(一)