{"id":19509806,"url":"https://github.com/dcloudio/test-framework","last_synced_at":"2025-04-05T18:08:16.506Z","repository":{"id":34457991,"uuid":"177580849","full_name":"dcloudio/test-framework","owner":"dcloudio","description":"框架测试汇总","archived":false,"fork":false,"pushed_at":"2023-03-06T17:29:47.000Z","size":3620,"stargazers_count":381,"open_issues_count":107,"forks_count":91,"subscribers_count":22,"default_branch":"master","last_synced_at":"2025-03-29T17:08:01.382Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dcloudio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-25T12:20:25.000Z","updated_at":"2024-08-24T02:18:03.000Z","dependencies_parsed_at":"2025-01-20T01:23:50.116Z","dependency_job_id":null,"html_url":"https://github.com/dcloudio/test-framework","commit_stats":{"total_commits":38,"total_committers":4,"mean_commits":9.5,"dds":0.368421052631579,"last_synced_commit":"bdfd5e6d7e07f4b09f0b22792b05d85d75ed54fa"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcloudio%2Ftest-framework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcloudio%2Ftest-framework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcloudio%2Ftest-framework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dcloudio%2Ftest-framework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dcloudio","download_url":"https://codeload.github.com/dcloudio/test-framework/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247378142,"owners_count":20929296,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-10T23:13:25.033Z","updated_at":"2025-04-05T18:08:16.480Z","avatar_url":"https://github.com/dcloudio.png","language":"JavaScript","readme":"这是为《小程序跨端框架全面测评》准备的仓库。\n\n本项目分别使用微信原生版、wepy版、mpvue版、taro版、uni-app版、chalemeon版，各自开发一个仿微博小程序首页的复杂长列表，支持下拉刷新、上拉翻页、点赞功能。\n\n该项目主要用于两项测试：\n- 跨端支持度如何：是否真能实现各框架宣传的那样，一次开发、多端发布？真的不需要二次开发？\n- 跨端框架性能如何：跨端框架基本都是`compiler` + `runtime`模式，引入的`runtime`是否会降低运行性能？尤其是与原生微信小程序开发相比性能怎么样？\n\n大家可自助测试，启动测试请修改 `utils` --\u003e `config.js` 下各项配置：\n- `PERF_MAX` 总翻页次数\n- `PERF_LIKE_MAX` 总点赞次数\n- `PERF_AUTO` 是否开启自动测试\n- `PERF_USING_COMPONENTS` 是否为原生组件，`mpvue`、`wepy` 为 `false`, 其他均为 `true`，请勿手动修改\n\nTips:\n\n- `kone` 修改的配置跟其他平台有些区别，项目编译之后到微信开发者工具找到 `common --\u003e utils --\u003e perf.common.js` 文件，修改文件 `97行` 的  `PERF_MAX` 等变量，与上述描述一致，开始自动测试。\n\n- 因为 `kone` 翻页到 33 页会导致节点超出，脚本无法继续进行，为了方便查看日志，在 `common --\u003e utils --\u003e perf.common.js` 文件搜索 `showToast`， 大概 187 行，注释掉 `showToast` 弹窗提示的实现 ，并在手机端开启调试模式，查看报错日志。\n \n## 测试结果@20200409 \n\n参考：[跨端开发框架深度横评之2020版](https://juejin.im/post/6844904118901817351)\n\n## 测试结果@20190327\n\n### 1. 跨端支持度如何\n\n开发一次，到处运行，是每个程序员的梦想。但现实往往变成开发一次，到处调错。\n\n各个待评测框架，是否真得如宣传的那样，一次开发、多端发布？\n\n我们将上述[仿微博App](https://github.com/dcloudio/test-framework)依次发布到各平台，验证每个框架在各端的兼容性，结果如下：\n\n|平台\t\t\t| 微信原生\t|wepy\t|mpvue\t|taro\t\t\t\t\t|uni-app|chameleon\t\t\t\t\t\t\t\t|\n|:-\t\t\t\t|:-\t\t\t|:-\t\t|:-\t\t|:-\t\t\t\t\t\t|:-\t\t|:-\t\t\t\t\t\t\t\t\t\t|\n|微信小程序\t\t|⭕️\t\t|⭕️\t|⭕️\t|⭕️\t\t\t\t\t|⭕️\t|⭕️\t\t\t\t\t\t\t\t\t|\n|支付宝小程序\t|❌\t\t\t|❌\t\t|⭕️\t|⭕️\t\t\t\t\t|⭕️\t|❌\t\t\t\t\t\t\t\t\t\t|\n|百度小程序\t\t|❌\t\t\t|❌\t\t|⭕️\t|⭕️\t\t\t\t\t|⭕️\t|❌\t\t\t\t\t\t\t\t\t\t|\n|头条小程序\t\t|❌\t\t\t|❌\t\t|⭕️\t|⭕️\t\t\t\t\t|⭕️\t|❌\t\t\t\t\t\t\t\t\t\t|\n|H5端\t\t\t|❌\t\t\t|❌\t\t|❌\t\t|上拉加载/下拉刷新失效\t|⭕️\t|上拉加载/下拉刷新失效\t\t\t\t\t|\n|App端\t\t\t|❌\t\t\t|❌\t\t|❌\t\t|上拉加载失效\t\t\t\t\t|⭕️\t|列表无法滚动，无法测试上拉加载/下拉刷新|\n\n*测试结果说明：*\n- ⭕ 表示支持且功能正常，❌ 表示不支持，其它则表示支持但存在部分bug或兼容问题\n- `wepy` 2.0 宣称版已支持其他家小程序，本测试基于`wepy`官网指引安装的`wepy-cli`默认版本为1.7.3，尚不支持多端\n- `chameleon`尝鲜版宣称支付宝、百度小程序，本测试基于`chameleon`官网指引安装的`chameleon-tool`默认版本为0.1.1，尚不支持其它小程序\n\n通过这个简单的例子可以看出，跨端支持度测评结论：`uni-app` \u003e `taro` \u003e `chameleon` \u003e `mpvue` \u003e`wepy`、`原生微信小程序`\n\n但是仅有上面的测试还不全面，实际业务要比这个测试例复杂很多。但我们没法开发很多复杂业务做评测，所以还需要再对照各家文档补充一些信息。\n由于每个框架的文档中都描述了各种组件和API的跨端支持程度。我们过了几家的文档，发现各家基本是以微信小程序为基线，然后把各种组件和API在其他端实现了一遍：\n- `taro`：H5端实现了大部分微信的API，App端和微信的差异比较大。\n- `uni-app`：组件、API、配置，大部分在各个端均已实现，个别API有说明在某些端不支持。可以看出uni-app是完整在H5端实现了一套微信模拟器，在App端实现了一套微信小程序引擎，才达到比较完善的平台兼容性。\n- `chameleon`：非常常用的一些组件和API在各端已经实现，这部分的平台差异较少。但大量组件和API需要开发者自己分平台写代码。\n\n跨端框架，一方面要考虑框架提供的通用api跨端支持，同时还要考虑不同端的特色差异如何兼容。毕竟每个端都会有自己的特色，不可能完全一致。\n- `taro`：提供了js环境变量判断和统一接口的多端文件，可以在组件、js、文件方面扩展多端，不支持其他环节的分平台处理。\n- `uni-app`：提供了条件编译模型，所有代码包括组件、js、css、配置json、文件、目录，均支持条件编译，可不受限的编写各端差异代码。\n- `chameleon`：提供了多态方案，可以在组件、js、文件方面扩展多端，不支持其他方式的分平台处理。\n\n跨端框架，还涉及一个ui框架的跨端问题，评测结果如下：\n- `taro`：官方提供了`taro ui`，支持小程序(微信/支付宝/百度)、H5平台，不支持App，[详见](https://taro-ui.aotu.io/#/)\n- `uni-app`：官方提供了`uni ui`，可全端运行；uni-app还有一个插件市场，里面有很多三方ui组件，[详见](https://ext.dcloud.net.cn/)\n- `chameleon`：官方提供了`cml-ui`扩展组件库，可全端运行，但组件数量略少，[详见](https://cmljs.org/doc/component/expand/expand.html)\n\n最后补充跨端案例：\n- mpvue：微信端案例丰富，未见其它端案例\n- taro：微信端案例丰富，百度、支付宝、H5端亦有少量案例\n- uni-app：微信、App、H5三端案例丰富，官方示例已发布到6端\n- chameleon：未看到任何端案例\n\n综合以上信息，本项的最终评测结论：`uni-app` \u003e `taro` \u003e `chameleon` \u003e `mpvue` \u003e `wepy`、`原生微信小程序`\n\n之前曾有友商掀起一番真跨端和伪跨端之争，通过本次Demo实测，这个争论可以盖棺定论了。\n\n### 2. 跨端框架性能如何\n\n跨端框架基本都是`compiler` + `runtime`模式，引入的`runtime`是否会降低运行性能？\n\n尤其是与原生微信小程序开发相比性能怎么样，这是大家普遍关心的问题。\n\n我们依然以上述仿微博小程序为例，测试2个容易出性能问题的点：长列表加载、大量点赞组件的响应。\n\n#### 2.1 长列表加载\n\n仿微博的列表是一个包含很多组件的列表，这种复杂列表对性能的压力更大，很适合做性能测试。\n\n从触发上拉加载到数据更新、页面渲染完成，需要准确计时。人眼视觉计时肯定不行，我们采用程序埋点的方式，制定了如下计时时机：\n\n- 计时开始时机：交互事件触发，框架赋值之前，如：上拉加载（onReachBottom）函数开头\n- 计时结束时机：页面渲染完毕(微信setData回调函数开头)\n\nTips：`setData`回调函数开头可认为是页面渲染完成的时间，是因为微信`setData`定义如下([微信规范](https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html?search-key=Page.prototype.setData))：\n\n|字段\t|类型\t\t|必填\t\t|描述\t|\n|:-\t\t\t|:-\t\t\t|:-\t\t|:-\t\t|\n|data\t|Object\t\t|是\t\t\t|这次要改变的数据|\t\t\t\t\t\t\t\t\t\t\t|\n|callback\t|Function\t|否\t\t|setData引起的界面更新**渲染完毕**后的回调函数\t|\n\n\n测试方式：从页面空列表开始，通过程序自动触发上拉加载，每次新增20条列表，记录单次耗时；固定间隔连续触发 N 次上拉加载，使得页面达到 20*N 条列表，计算这 N 次`触发上拉 -\u003e 渲染完成`的平均耗时。\n\n测试结果如下：\n\n|列表条数\t| 微信原生\t|wepy\t|mpvue\t|taro\t|uni-app|chameleon\t|\n|:-\t\t\t|:-\t\t\t|:-\t\t|:-\t\t|:-\t\t|:-\t\t|:-\t\t\t|\n|200\t\t|770\t\t|625\t|969\t|752\t|641\t|1261\t\t|\n|400\t\t|876\t\t|781\t|4493\t|974\t|741\t|1970\t\t|\n|600\t\t|1111\t\t|-\t\t|-\t\t|1250\t|910\t|2917\t\t|\n|800\t\t|1406\t\t|-\t\t|-\t\t|1547\t|1113\t|4040\t\t|\n|1000\t\t|1690\t\t|-\t\t|-\t\t|1878\t|1321\t|5196\t\t|\n\n说明：以400条微博列表为例，从页面空列表开始，每隔1秒触发一次上拉加载（新增20条微博），记录单次耗时，触发20次后停止（页面达到400条微博），计算这20次的平均耗时，结果微信原生在这20次 `触发上拉 -\u003e 渲染完成` 的平均耗时为876毫秒，最快的`uni-app`是741毫秒，最慢的mpvue是4493毫秒\n\n大家初看这个数据，可能比较疑惑，别急，下方有详细说明\n\n**说明1：为何 mpvue/wepy 测试数据不完整?**\n\n`mpvue`、`wepy` 诞生之初，微信小程序尚不支持[自定义组件](https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/)，无法进行组件化开发；`mpvue`、`wepy` 为解决这个问题，将用户编写的`Vue`组件，编译为`WXML`中的[模板（template)](https://developers.weixin.qq.com/miniprogram/dev/framework/view/wxml/template.html)，变相实现了组件化开发能力，提高代码复用性，这在当时的技术条件下是很棒的技术方案。\n\n但如此方案，在复杂组件较多的页面，会大量增加 dom 节点，甚至超出微信的 dom 节点数限制。我们在 红米手机（Redmi 6 Pro）上实测，页面组件超过500个时，`mpvue`、`wepy`  实现的仿微博App就会报出如下异常，并停止渲染，故这两个测试框架在组件较多时，测试数据不完整。这也就意味着，当页面组件太多时，无法使用这2个框架。\n\n\u003e dom limit exceeded please check if there's any mistake you've made \n\n*Tips：`wepy`在400条列表以内，为何性能高于微信原生框架，这个跟自定义组件管理开销及业务场景有关（`wepy`编译为模板，不涉及组件创建及管理开销），后续对微博点赞，涉及组件数据传递时，微信原生框架的性能优势就提现出来了，详见下方测试数据。*\n\n**说明2：uni-app 比微信原生框架性能更好？逆天了？**\n\n其实，在页面上有200条记录（200个组件）时，`taro` 性能数据也比微信原生框架更好。\n\n微信原生框架耗时主要在`setData`调用上，开发者若不单独优化，则每次都会传递大量数据；而 `uni-app`、`taro` 都在调用`setData`之前自动做`diff`计算，每次仅传递有变化的数据。\n\n例如当前页面有20条数据，触发上拉加载时，会新加载20条数据，此时原生框架通过如下代码测试时，`setData`会传输40条数据\n\n```\ndata: {\n    listData: []\n},\nonReachBottom() { //上拉加载\n    let listData = this.data.listData;\n    listData.push(...Api.getNews());//新增数据\n    this.setData({\n        listData\n    }) //全量数据，发送数据到视图层\n}\n```\n\n开发者使用微信原生框架，完全可以自己优化，精简传递数据，比如修改如下：\n\n```\ndata: {\n    listData: []\n},\nonReachBottom() { //上拉加载\n    // 通过长度获取下一次渲染的索引\n    let index = this.data.listData.length;\n    let newData = {}; //新变更数据\n    Api.getNews().forEach((item) =\u003e {\n        newData['listData[' + (index++) + ']'] = item //赋值，索引递增\n    }) \n    this.setData(newData) //增量数据，发送数据到视图层\n}\n```\n\n经过如上优化修改后，再次测试，微信原生框架性能数据如下：\n\n|组件数量\t| 微信原生框架（优化前）\t|微信原生框架（优化后）\t|uni-app|taro\t|\n|:-\t\t\t|:-\t\t\t\t\t\t|:-\t\t\t\t\t\t|:-\t\t|\n|200\t\t|770\t\t\t\t\t|572\t\t\t\t\t|641\t| 752\t|\n|400\t\t|876\t\t\t\t\t|688\t\t\t\t\t|741\t| 974\t|\n|600\t\t|1111\t\t\t\t\t|855\t\t\t\t\t|910\t| 1250\t|\n|800\t\t|1406\t\t\t\t\t|1055\t\t\t\t\t|1113\t| 1547\t|\n|1000\t\t|1690\t\t\t\t\t|1260\t\t\t\t\t|1321\t| 1878\t|\n\n从测试结果可看出，经过开发者手动优化，微信原生框架可达到更好的性能，但 `uni-app`、`taro` 相比微信原生，性能差距并不大。\n\n这个结果，和web开发类似，web开发也有原生js开发、vue、react框架等情况。如果不做特殊优化，原生js写的网页，性能经常还不如vue、react框架的性能。\n\n也恰恰是因为`Vue`、`react`框架的优秀，性能好，开发体验好，所以原生js开发已经逐渐减少使用了。\n\n复杂长列表加载下一页评测结论：`微信原生开发手工优化`,`uni-app`\u003e`微信原生开发未手工优化`,`taro` \u003e `chameleon` \u003e `wepy` \u003e `mpvue`\n\n#### 2.2 点赞组件响应速度\n\n长列表中的某个组件，比如点赞组件，点击时是否能及时的修改未赞和已赞状态？是这项测试的评测点。\n\n测试方式：\n- 选中某微博，点击“点赞”按钮，实现点赞状态状态切换（已赞高亮、未赞灰色），\n- 点赞按钮 `onclick`函数开头开始计时，`setData`回调函数开头结束计时；\n\n在红米手机（Redmi 6 Pro）上进行多次测试，求其平均值，结果如下：\n\n|列表数量\t|微信原生\t|wepy\t|mpvue\t|taro\t|uni-app|chameleon\t|\n|:-\t\t\t|:-\t\t\t|:-\t\t|:-\t\t|:-\t\t|:-\t\t|:-\t\t\t|\n|200\t\t|91\t\t\t|279\t|666\t|92\t\t|93\t\t|101\t\t|\n|400\t\t|111\t\t|501\t|1507\t|125\t|107\t|145\t\t|\n|600\t\t|144\t\t|-\t\t|-\t\t|152\t|148\t|178\t\t|\n|800\t\t|176\t\t|-\t\t|-\t\t|214\t|181\t|236\t\t|\n|1000\t\t|220\t\t|-\t\t|-\t\t|229\t|234\t|272\t\t|\n\n说明：也就是在列表数量为400时，微信原生开发的应用，点赞按钮从点击到状态变化需要111毫秒。\n\n测试结果数据说明：\n- wepy/mpvue 测试数据不完整的原因同上，在组件较多时，页面已经不再渲染了\n- 基于微信自定义组件实现组件开发的框架（uni-app/taro/chameleon），组件数据通讯性能接近于微信原生框架，远高于基于`template`实现组件开发的框架（wepy/mpvue）性能\n\n组件数据更新性能测评：`微信原生开发`,`uni-app`,`taro` \u003e `chameleon` \u003e `wepy` \u003e `mpvue`\n\n综上，本性能测试做了2个测试，长列表加载和组件状态更新，综合2个实验，结论如下：\n\n`微信原生开发手工优化`,`uni-app`\u003e`微信原生开发未手工优化`,`taro` \u003e `chameleon` \u003e\u003e `wepy` \u003e `mpvue`\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcloudio%2Ftest-framework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdcloudio%2Ftest-framework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdcloudio%2Ftest-framework/lists"}