谈一谈前端多容器(多webview平台)处理方案

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介:

得益于近几年移动端的发展,前端早已今非昔比,从大型框架来说angularJS、react、VueJS都有其应用场景,从工程化来说各种配套构建工具也纷纷出世,而从前端复杂度来说,最近几年的前端代码难度着实提升不少,从模块化的必须,到MVC的必要、再到组件化编程,一种分而治之的思想逐渐侵入前端领域,而这种种迹象均表明一个问题,前端代码现在不好写了!!!

抛开近几年前端交互加重而导致的难度,我们今天主要探讨下前端跨平台一块的痛点,也就是Hybrid多容器解决方案。

Hybrid是一种混合开发模式,最简单的理解就是,Native会提供一个webview容器(确实不明白可以理解为iframe),然后在里面加载你的H5站点。

在大约三年前,当时Hybrid平台还比较少,如果一个公司前端团队比较强的话可以做到一套代码三端运行就很不错了,也就是一个H5页面同时运行在:

① 浏览器

② 公司IOS APP Webview容器

③ APP Andriod Webview容器

再这里有个和简单iframe不同的是,处于Native中的话,那么很多H5的表现便不太一样了,比如header一部分的UI是Native的,比如获取定位信息直接由Native给H5,在这里面会有些差异化处理,一般来说只有保持应用层API一致,底层稍作修改即可;但也有一些特殊场景需要判断,比如,一个按钮的回调在H5站点的处理和处于Native中不一样,这个时候可能就需要if else判断处理了。

总的来说,双容器时代持续了一阵子,而因为条件仍然比较单一,无非只是判断H5站点或者自身APP容器,所以问题也就不大。

多容器

量变到一定阶段便不再一样了,简单从携程来说,Hybrid的频道从最初的一个发展到现在APP中80%都是Hybrid频道,携程APP本身有一套完整的Hybrid交互规范,俨然已经不再简单是个APP了,而是一个Hybrid平台,开发规范一旦制定,一旦进入工厂化开发就很难更改了,除了携程各个业务团队依赖这个APP外,还有很多携程子公司乃至第三方公司依赖这个APP,那么这个时候底层若是不稳定,那么导致的问题将是连锁的、不可控的。

这种平台化的APP产品远不止携程一家,已知的就有:

① 微信APP平台

② 淘宝APP平台

③ 手机百度APP平台

④ 糯米平台

⑤ 手机QQ平台

......

国内这些“平台”都有各自问题,不论是微信一些版本不支持flex、手机百度IOS、Andriod Webview容器各种不一致,还是糯米Native默认后退不处理导致假死,都可以看出为了抢占市场,各个团队走的太急,考虑的应用场景过少,推出产品后后宣传网站写的漂亮,API看似丰富,但是光鲜的只是表面,真正形成平台后,各个业务方接入会形成各种小概率场景,而Native发版是无力的,Native不动就只能业务开发代码适配,这个时候受苦的总是各个接入方,而导致骂声一片。

各个平台不稳定、考虑场景太少其实也无可厚非,毕竟Hybrid才火不到几年,各个公司真正的经验场景又很难被其它公司吸收,所以这种现象还得持续一段时间......

当然,APP底层的问题不是我们今天思考的重点,我们还是回到前端应用层。

多容器与前端

上述平台产品虽然有各自的问题,但是其流量优势是无可比拟的!所以很多业务方、第三方公司都会接入,对于前端来说难度便增加了不少,以百度为例:



最初是前端代码运行在浏览器即可,而现在一套前端代码却需要运行在:

① 浏览器

② 自身APP

③ 百度地图APP

④ 手机百度APP

⑤ 糯米APP

而各个APP平台的Hybrid交互又完全不一致,更有甚者后期还需要微信APP、手机QQ等Hybrid平台,那么就简单一个按钮的交互都会令人头疼的!因为我们的代码中可能会出现这种东东:

复制代码
 1 if (shoujibaidu) {
 2     //手机百度逻辑
 3 
 4 } else if (baiduditu) {
 5     //百度地图逻辑
 6 
 7 } else if (nuomi) {
 8     //糯米逻辑
 9 }
10 //......其它平台逻辑
复制代码
这种代码十分令人头疼,所以我们一般会封装一个方法在底层,哪个平台有差异就做特殊处理:

复制代码
1 hybridCallback({
2     //默认回调
3     callback: function() {
4     },
5     //手机百度回调
6     shoubaicallback: function () {
7     },
8     //......
9 });
复制代码
这个方法就是用于处理Hybrid差异而生,只有处于某一个环境,才会执行其中的回调,这其实只是一个语法糖,将判断的逻辑封装了,所以这个方案依旧很烂,如果哪天你要多一个容器或者少一个容器,整个站点的代码要如何处理呢?如果代码量超过万行,这个代码可不好处理!

更好的解决方案是抽离共性,是继承,一般来说,Hybrid还是有一个很大的特点:主要逻辑与H5一致,一些差异往往是显示什么,不显示什么(比如糯米中不显示H5推荐下载APP的广告),更多的是一些点击回调的响应,于是我们找到了更好的方案:



多容器解决方案

容器判断

解决多容器的第一步是容器判断,一般来说,不同的Webview容器会有不同的userAgent:

复制代码
//微信中UA为:
Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Mobile/11D257 MicroMessenger/6.1.5 NetType/WIFI

//浏览器中为:
Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53 

//糯米
Mozilla/5.0 (iPhone; CPU iPhone OS 9_2_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13D15 BDNuomiAppIOS
复制代码
手机百度也会包含关键字:bdbox_x.x(x.x一般是版本号),根据ua我们可以知道当前处于什么环境(ios还是Andriod)与什么平台。

前端实现

如果是页面片的开发模式,一个页面往往会有一个js文件,做的好的团队这个js文件会是一个类,通过requireJS可以轻易拿到该文件,我们这里不做无用功,直接在之前代码的基础上做,有疑问的朋友请移步该文章:

【组件化开发】前端进阶篇之如何编写可维护可升级的代码

在上文中,我们将一个个页面以组件化的方式打散了,我们这里新增一个index页面,并且新增一个按钮,点击按钮弹出一个提示:





 View Code
复制代码
 1 propertys: function ($super) {
 2     $super();
 3     this.template = layoutHtml;
 4     this.events = {
 5         'click .js_clickme': 'clickAction'
 6     };
 7 },
 8 
 9 clickAction: function () {
10     this.showMessage('显示消息');
11 },
复制代码
首先我们看看这个回调,假如我们需要做到在糯米容器中使用Native的弹出提示的话,代码便有所不同了:

http://dev.nuomi.com/#/guide/doc/api_doc/.%252Fcomdoc%252Fcomp_api%252Fcomp%252Fapi_doc%252Fbnjs_ui_doc.md

我们使用的应该是:

 View Code
复制代码
1     // 仅显示'ok'按钮
2     BNJS.ui.dialog.show({
3         title: '测试Dialog',
4         message: '我是测试Dialog~~~~',
5         ok: 'ok',
6         onConfirm: function() {
7             BNJS.ui.toast.show('您刚刚点击了ok按钮');
8         }
9     });
复制代码
于是我们在index目录中新增了一个nuomi.index.js的文件,继承自index.js,并且在入口文件main_webviews(原main.js文件)中做更改:



复制代码
 1 define([
 2     'IndexPath/index'
 3 ], function (
 4     IndexView
 5 ) {
 6     return _.inherit(IndexView, {
 7 
 8         clickAction: function () {
 9             BNJS.ui.dialog.show({
10                 title: '测试Dialog',
11                 message: '我是测试Dialog~~~~',
12                 ok: 'ok',
13                 onConfirm: function () {
14                     BNJS.ui.toast.show('您刚刚点击了ok按钮');
15                 }
16             });
17         }
18 
19     });
20 });
复制代码
如此,在一般浏览器中点击按钮便是H5的UI组件,在糯米中便是使用的糯米组件了,如果哪天不需要糯米这个平台将nuomi.js删除即可:





可以看到,按钮的点击已经不一样了,当然还有很多不足,比如糯米中header部分便没有做处理。

header组件

header这种组件与上述问题又不一致,这种不一致主要体现在两个方面:

① 由于底层实现问题,做不到一致

比如手机百度就不支持返回按钮定制,就连最简单的title改变都是直接监听的document.title的变化,并且Andriod还有BUG,像这种底层实现直接就抹杀的基本没法,一般来说就是把原来的header换个方式显示在页面中,可以是弧形按钮,可以是其它方式。

② header是系统级别的操作,不应该由用户控制

如同该文中对header组件的处理:浅谈Hybrid技术的设计与实现,像header这一类组件,这类组件必须满足在H5站点与Hybrid中API使用一致,而底层实现各异,与之前不同的是,这里的header组件要考虑的可不止2个平台那种问题了,他可能是这样的:

ui.eader //H5站点使用
nuomi.ui.header //糯米使用
xx.ui.header //......
我们这里将场景变小,暂时只考虑糯米与H5的实现,于是会在底层多出一个header的实现:



我这里工作做的多一些,考虑了微信时候的场景,但是这里业务代码暂时只考虑糯米,对应糯米的文档:

http://dev.nuomi.com/#/guide/doc/api_doc/.%252Fcomdoc%252Fcomp_api%252Fcomp%252Fapi_doc%252Fbnjs_ui_doc.md

 View Code
代码实现很简单,只要保持与H5使用API一致即可,这个时候再简单改下入口文件,便能适配了。

PS:注意,这里的适配只是简单实现,考虑多场景的话不能这样写代码!!!

于是我们在糯米中便能很好的运行了



结语

代码地址

https://github.com/yexiaochai/mvc

demo地址

http://yexiaochai.github.io/mvc/webapp/bus/index.html

测试糯米时请扫描第二个二维码:

 

这里抛出了前端多Webview容器会遇到的一些问题,并提出了一个解决思路,后续可能会有更加完整解决方案与demo出来,希望对各位有用,若是有已经涉及到这块业务的朋友可以私下交流下。



本文转自叶小钗博客园博客,原文链接:http://www.cnblogs.com/yexiaochai/p/5204847.html,如需转载请自行联系原作者
相关文章
|
5天前
|
存储 运维 Kubernetes
正式开源,Doris Operator 支持高效 Kubernetes 容器化部署方案
飞轮科技推出了 Doris 的 Kubernetes Operator 开源项目(简称:Doris Operator),并捐赠给 Apache 基金会。该工具集成了原生 Kubernetes 资源的复杂管理能力,并融合了 Doris 组件间的分布式协同、用户集群形态的按需定制等经验,为用户提供了一个更简洁、高效、易用的容器化部署方案。
正式开源,Doris Operator 支持高效 Kubernetes 容器化部署方案
|
1月前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
99 3
|
1月前
|
开发框架 安全 开发者
Docker 是一种容器化技术,支持开发者将应用及其依赖打包成容器,在不同平台运行而无需修改。
Docker 是一种容器化技术,支持开发者将应用及其依赖打包成容器,在不同平台运行而无需修改。本文探讨了 Docker 在多平台应用构建与部署中的作用,包括环境一致性、依赖管理、快速构建等优势,以及部署流程和注意事项,展示了 Docker 如何简化开发与部署过程,提高效率和可移植性。
75 4
|
2月前
|
前端开发 数据可视化 搜索推荐
深入剖析极态云优雅的前端框架设计方案(上)
最近在体验极态云,这款低代码软件开发产品,发现其前端框架设计方案很优雅很强大! 在接下来的学习过程中,我将持续输出自己对极态云前端框架设计方案的深入理解,包括具体的使用技巧、优势分析以及可能的应用场景等方面的内容,希望能为大家提供有价值的参考。
|
2月前
|
存储 运维 Kubernetes
云端迁移:备份中心助力企业跨云迁移K8s容器服务平台
本文将简要介绍阿里云容器服务ACK的备份中心,并以某科技公司在其实际的迁移过程中遇到具体挑战为例,阐述如何有效地利用备份中心来助力企业的容器服务平台迁移项目。
|
3月前
|
缓存 前端开发 JavaScript
前端的全栈之路Meteor篇(二):容器化开发环境下的meteor工程架构解析
本文详细介绍了使用Docker创建Meteor项目的准备工作与步骤,解析了容器化Meteor项目的目录结构,包括工程准备、环境配置、容器启动及项目架构分析。提供了最佳实践建议,适合初学者参考学习。项目代码已托管至GitCode,方便读者实践与交流。
|
3月前
|
JavaScript 前端开发 Docker
前端的全栈之路Meteor篇(一):开发环境的搭建 -全局安装或使用容器镜像
本文介绍了如何搭建 Meteor 开发环境,包括全局安装 Meteor 工具和使用 Docker 镜像两种方法,以及创建和运行一个简单的 Meteor 项目的基本步骤。 Meteor 是一个全栈 JavaScript 框架,适用于构建实时 Web 应用程序。文章还提供了遇到问题时的解决建议和调试技巧。
152 3
|
3月前
|
前端开发 JavaScript Docker
拿下奇怪的前端报错(五):SyntaxError: Unexpected token ‘??=‘或‘xxx‘ - 基于容器搭建开发环境或许是更好的选择
在前端开发中,同时维护多个项目时可能会遇到不同Node.js版本的问题。低版本Node.js可能导致依赖无法安装或启动失败,而高版本Node.js则可能引起第三方库的兼容性问题。推荐使用Docker搭建独立的开发环境,以避免版本不一致带来的困扰。
1020 1
|
4月前
|
Kubernetes API Docker
跟着iLogtail学习容器运行时与K8s下日志采集方案
iLogtail 作为开源可观测数据采集器,对 Kubernetes 环境下日志采集有着非常好的支持,本文跟随 iLogtail 的脚步,了解容器运行时与 K8s 下日志数据采集原理。
|
3月前
|
缓存 前端开发 UED
前端 8 种图片加载优化方案梳理
本文首发于微信公众号“前端徐徐”,详细探讨了现代网页设计中图片加载速度优化的重要性及方法。内容涵盖图片格式选择(如JPEG、PNG、WebP等)、图片压缩技术、响应式图片、延迟加载、CDN使用、缓存控制、图像裁剪与缩放、Base64编码等前端图片优化策略,旨在帮助开发者提升网页性能和用户体验。
569 0