1 导读
一艘船,什么角色最重要?船长,舵手
是的,大部分人都会想到这个答案,这个答案不算错,也是大部分Leader扮演的角色之一。其实还有一个重要的隐形角色,就是设计师!因为船的设计从底层决定着用途、航速等核心指标。比如本来要去打仗的船,却设计成了游艇,要花两个小时才能左转20度,不管船长和舵手再厉害,这艘船也厉害不起来。
同样的,一个好的框架和平台也从底层决定着业务的交付效率、线上质量、用户体验。信也借款业务的23个移动Web应用都是使用Vax(Vue as everything)移动Web应用研发PaaS平台创建的。写这篇文章的目的既是为了宣传一下Vax,也是对它进行阶段性总结和梳理。
Leader是设计师+老师+服务者。——彼得·圣吉(MIT”学习型组织”理论的缔造者)
1 Vax 简介
信也科技自研的移动端Web应用研发PaaS平台具有以下三个特点:
- 标准化API,让页面打开更快、埋点更准、白屏更少、研发更简单
- 快速创建和升级移动Web应用
- 可视化埋点和API在线验证,让产研更高效
2 架构
2.1 业务领域
服务端按业务领域架构的微服务思想在前端也是一样的,也就是微前端思想。
首页、主营、第三方成交、运营活动、市场投放各业务领域独立评审、独立开发、独立测试、独立发布、独立回滚,彼此互不影响,职责明确。各业务线具有清晰的责任人,业务开发熟练度高,保证了交付质量和效率。
2.2 JS SDK
各业务领域都引用统一的、标准的JSSDK,避免各业务线分别实现思路各异、功能不同的请求、埋点、监控、追踪等API。否则发现问题后,要针对每个业务进行分析,解读其实现思路,定位和修复难度大,交付质量也难以管理,开发成本高。
2.2.1 Widget.UI.JS
顾名思义,这个SDK是前端开发时常用的Button、List、Panel、Tabs等组件,同时也包含开源的MintUI中的部分组件。之所以将MintUI放在统一的UI.JS中是因为三方的UI库也会有Bug,而且这类Bug不好修复,比如列表滚动时就会出现两个列表项之间有空白的问题。
将它们封装在UI.JS中,各业务线问题可以统一修复,还可以避免第三方组件升级带来的影响。而且此SDK只保留基础UI组件的最小集,体积小,版本更新频率低,可以强缓存在客户端,提高页面打开性能。
//UI在线引入
<script src="//xxxwebui.xxxx.com/2.1.9/index.js" type="text/javascript"></script>
2.2.2 Widget.BC.JS
BC组件是Business Unit,也就是业务单元。它与UI的不同是BC包含接口请求、状态判断等逻辑,比如滚动卡片、优惠券列表、图表、协议、校验器等。BC可以依赖UI进行开发,可以被不同的业务线共同使用。比如优惠券列表同时使用在优惠券管理和运营活动两个不同的业务领域,此组件应该放在BC中。如果业务工程间相互引用,因为不符合设计规范,引用关系很快就会变成网状结构,最后就只有“重构”一个选择了。
BC.JS并不同于UI.JS是在线引用的,因为BC组件的开发需求非常多。为了保证业务领域代码的最小化,BC组件是需通过NPM Module引入的,使BC组件直接构建进入业务线代码。
//按需引入BC
import { encrypt } from '@xxx/bc';
2.2.3 PPDNetwork.JS
PPDNetwork.JS主要实现网络通信、监控、错误码的标准化。在离线包模式下网络请求使用客户端通道,在H5模式下网络请求使用Ajax通道。使用客户端通道可以防止DNS劫持,也可以让API请求快速回源。
它还可以监控网络请求的时间,将数据上报到实时数据进行分析。对网络异常和服务端数据结果错误的情况进行统一处理,提示Toast并上报错误信息。另外,在客户端Token异常时还可以尝试重新获取Token,来保证用户登录态的有效性。
// 业务中直接使用sendRequest方法发送请求
export function queryUserConfig(params) {
return sendRequest({
method: 'post',
noErrMsg: true,
url: '/xxxx/userService/userConfig',
params
});
}
2.2.4 PPDTracker.JS
PPDTracker.JS将埋点行为封装为埋点时机和埋点类型两部分。埋点时机包含“Onload”(页面正常加载)、“OnResume”(页面后台切前台)、“Event”(点击、输入、滚动、拖动)、“Network”(网络请求返回),这四个时机会触发埋点。埋点类型分为曝光类型和事件类型。Tracker.JS会自动读取配置文件完成页面埋点行为的初始化,埋点方法不会侵入业务代码。
正在研发的可视化埋点,实现了产研自助化埋点,PM不需要写Excel,研发不需要开发,测试不需要验证,可以大幅提高产研人效。PM在数据港完成埋点项目创建后,只要加载线上页面即可完成埋点配置并进行发布和验证。因为前端页面上的每个DOM元素都有唯一的标识,只要页面整体布局不发生变化,修改代码后各组件的标识就不会变化,因此需求上线后只要更新变化元素对应的埋点配置即可。
// 初始化PPDTracker
let ppdTracker = new PPDTracker({
EXPOSED_PERCENT: 0.5,
isHalfAppPage: true,
STAY_TIME: 2000
});
2.2.5 PPDMonitor.JS
对于前端页面的性能监控有四个核心指标“白屏时间”、“首屏时间”、“可交互时间”、“完全加载时间”。Monitor.JS取页面中第一个元素出现的时间作为白屏时间(first Paint Time,IOS平台可以取Header标签中资源加载最长的时间),取ViewPort内最后一张图片或DOM元素渲染完成的时间作为首屏时间,取第一个可交互元素渲染完成的时间作为可交互时间(DCL),取页面所有外链资源加载完成的时间作为完全加载时间(Loaded)。
Monitor.JS还可以通过addEventListener(‘error’,)来完成子资源加载错误的监控,通过“window.onerror”事件完成对JS执行错误的监控,通过“window.Vue.config.errorHandler”完成Vue执行错误的监控。并最终将监控数据上报到实时数据,配置告警策略,急时发现线上问题。
// Monitor的构造函数
constructor(){
this.perfData = {};//性能数据
this.jsErrorData = {};//JS报错信息
this.vueErrorData = {};//Vue 报错信息
this.docErrorData = {};//子资源加载错误信息
this.handleDocError();//处理子资源错误方法
this.handleJsError();//监听JS 报错方法
this.handlePerf();//获取性能数据方法
}
2.2.6 PPDDeeplink.JS
运营活动和市场投放需要下载APP的功能。比如,当用户打开页面后检查是否安装APP,如果已安装则直接调起APP并打开指定页面,如果没有安装则自动下载或者跳转到商城下载。不同业务页面只要引用此SDK即可实现该类功能。
// 引入SDK
deelLinkJsUrl:'//xxxtool.xxxx.com/latest/deeplink.js'
2.2.7 PPDFingerPrint.JS
Landing页会投放到抖音、微信、头条等渠道中去获客。如果用户完成了注册,但没有立即下载APP,而是过一段时间自己去应用商店下载了APP,如何追踪到他?PPDFingerPrint.JS解决了此问题,筛选出未下载APP的用户来做精准营销。因为它使用了IP、UA、GPU绘制Canvas参数、开源JS库来生成设备指纹,之后将指纹信息编码为二进制字符串,使用零宽字符 ‘​’、 ‘‌’、 ‘‍’一个代表1、一个代表0、一个代表空格编码后写入剪切板,这样用户在粘贴内容时是看不到剪切板中内容的。最后在APP启动时进行逆向解码,使用服务端对前端和客户端数据进行对比分析,最终追踪到未下载APP和发生借款的用户,实现精准营销。
// 指纹数据
const data = {
type: 0,//type:0表示H5,1表示APP,3其他
phBrand: device.manufacturer,//设备品牌
phModel: phModel,//设备型号
osVersion: `${os.name}${os.version.original}`,//系统版本
screenSize: `${screen.width}*${screen.height}`,//屏幕尺寸
ua: navigator.userAgent,//设备UserAgent
currentUrl: location.href,//当前url
deviceFingerprint: hash,//设备指纹
gpu: getGPUInfo(),//设备GPU信息
canvasFingerPrint: getCanvasFingerPrint()//设备Canvas指纹
}
2.2.8 PPDWebUI.JS
作为Hybrid APP,前端和客户端通信是核心功能,WebUI.JS可以实现传参和方法调用两种容器配置方式。在开启一个容器时可以通过传参来设置容器样式,比如开启沉浸式、按钮样式、回调函数注册等,也可以经过方法调用来完成容器设置。
每个回调函数都有一个CallbackId,用一个队列进行维护,客户端只回调ID,然后前端使用Hooks函数进行分发,这样可以避免一个容器中JS函数重名引发的线上问题。
// 使用WebUI容器打开指定
jumpToUrl(url) {
if (PPDWebUI && PPDWebUI.os.inApp) {
window.PPDWebUI.xxxService.openUrl({
url
},
function (data) {
console.log('OpenUrl调用成功')
},
function (err) {
console.log('OpenUrl调用失败')
}
)
} else {
window.location.href = url
}
}
2.2.8 PPDFrame.JS
此SDK只包含单纯的Vue运行时、基础CSS、字体等,一般几年都不会发生变化。可以将运行时提前预置到客户端来提高页面打开性能。若Vue3.0成熟,则可以直接升级运行时版本,之后各业务线升级依赖即可,不需针对每个业务线手动修改配置进行升级。
讲了那么多JSSDK,其实还有已经完成了LDPassport.JS,以及即将开发的PPDPassport.js、PPDMetrics.JS、PPDRouter.JS没有介绍。由于篇幅原因,如果大家对他们有疑问欢迎线下撩~~
2.3 编译层
编译层涉及到Vue的编译原理、ES6/7/8/9/10编译为ES5的原理、SASS/LESS/PostCSS编译为CSS3的原理、HTML编译为WXML的原理、CSS3编译为WXSS的原理、JS编译为WXS的原理、JS和Dart相互编译的原理,这里不再赘述。概括的说,编译过程就是首先完成模板编译,然后将前端语法转化为AST,之后将AST转化为AST’,最后将AST’转化为前端新语法,这个过程可以通过Webpack Loader和Bable完成,不同点是不同的目标平台需要不同的Plugin。
2.4 渲染层
Vax在APP中可以作为离线包通过Webkit完成渲染,在浏览器可以作为PWA完成渲染,在服务端可以通过同构完成渲染,在微信、支付宝、头条等渠道可以作为小程序完成客户端渲染,在Flutter中可以使用Skia完成渲染(Web for Flutter),在客户端可以使用YOGA(RN、Weex)完成渲染。
因业务特点目前只实现了离线包渲染,服务端同构渲染、PWA渲染正在开发中。其它如小程序、Flutter、RN、Weex渲染可以视业务需求进行实现。
3 Vax-CLI向导
虽然CLI向导是一个被开发同学反复立项的课题,但它确实是必须的。而且,一个好的CLI工具对团队而言具有十分重要的意义。因为它从根本上决定了代码的规范、工程的结构、项目的基础配置、单元测试框架、依赖组件的管理以及项目升级改造的成本。
Vax-CLI向导除了具有Vue-CLI快速创建前端项目工程的功能外,还具有公共组件依赖管理、公共组件升级、项目模板升级的功能。
那么多的JSSDK和项目配置,如果没有标准的模板作为规范,各个业务工程将会出现很严重的碎片化现象,一段时间以后将变得无法追溯和维护。比如,每个业务工程要依赖不同的JSSDK、对于同一个JSSDK又会依赖不同的版本,如何做好依赖管理显得格外重要。
“business-template”是业务工程模板,主要用于创建业务开发代码工程。它使用HandleBars模板自动生成主文档。这样当开发执行NPM RUN DEV命令时就可以调用接口判断公共组件版本,根据CLI向导完成组件升级操作。另外,每个业务工程可独立构建成一个离线包。业务工程还可以执行NPM Create SPA来快速创建单页,每个单页又具有专属的埋点配置文件。
“widget-template”是公共组件库工程模板,主要用于创建组件框架代码工程。在执行NPM RUN Publish命令时会将公共组件的版本信息发送到服务端,这样业务工程在开发前就可以通过判断版本来完成依赖升级。另外,公共组件工程还会构建出不同版本的组件库,每个组件库又构建为不同的离线包。组件库中的每个JSSDK还具有专属的TestPage来完成API功能在线验证。
CIWeb是一个管理公共组件依赖的服务,当组件有新版本发布时会自动发送企业微信和邮件通知,相关开发和测试可以及时获得更新内容,实现信息同步。还可以将基础组件在业务工程中的使用情况展示在Vax官网上,方便开发在线查看组件升级记录。
结语
在负责好业务的同时,作为产品经理+项目经理+总架构师完成技术平台和产品自助平台建设还是挺难的,难免有很多不完善的地方,有很多需要改进的地方。但只要持续不断的浇灌,我们相信Vax一定可以成长为一个行业内优异的研发平台。
在此感谢信也移动应用大前端各位同学们付出的努力,感谢各位领导的支持,我们还有Maltose管理系统研发PaaS平台、神笔设计平台、CMS资讯管理平台、可视化埋点、Node同构服务等项目,可以按序分享下。下一篇将介绍Maltose管理系统研发PaaS平台,让我们一起“乘风破浪,云帆济海”。
作者介绍
CC,信也科技借款前端Leader,目前负责借款业务前端研发、大前端平台建设工作。