混合应的程化实践...wkwebview 内存 uiwebview wkwebview 渲染时间 30 + 5 × n 2 × n + x...
TRANSCRIPT
-
混合应⽤用的⼯工程化实践
美团点评 平台及酒旅事业群 李李罡
-
李李罡前端⼯工程师,平台前端基础架构
曾经从事桌⾯面软件开发
⽬目前负责前端发布系统、混合应⽤用框架产品
github.com/sartrey
http://github.com/sartrey
-
迭代速度快
业务周期短
业务数量量多 包⼤大⼩小
App 发版周期 基于 WebView
现状 约束 ⽅方案
基于 Native 动态化
-
设备 提供底层⽀支持
桥 连接设备与容器器
容器器 承载⻚页⾯面
WebViewWebView
WebView
设备能⼒力力
基础功能
业务功能
Hybrid 应⽤用
-
容器器
• 接⼊入多个 App,Crash 率极低
• ⽀支持离线化、⻓长连接通道
桥
• 提供基础 API,⽀支持扩展业务 API
• 推进多个历史框架收敛下线
• ⽀支持微信、⽀支付宝等第三⽅方 App
我们的产品与服务
-
桥鉴权 简化改善效率
⽹网络优化 分段各个击破
数据收集 克制避免⻛风险
100 个业务桥需要 100 次发版吗?
如何屏蔽复杂⽹网络环境的体验差异?
怎样收集数据更更有利利于发掘数据内涵?
-
案例例⼀一 · 桥鉴权
-
加载统⼀一桥
调⽤用 Native
加载桥实现
调⽤用统⼀一桥
调⽤用失败
桥鉴权 设置回调 Native 回调
清除回调
解析 UA
未通过桥鉴权
鉴权成功
加载 调⽤用
桥的加载与调⽤用
-
优点与缺点
• 完整、安全、标准
• 复杂、缓慢、⻛风险传递
典型应⽤用
• 微信第三⽅方应⽤用登录
• 美团桥鉴权(旧)
业务鉴权服务器器
客户端 中央鉴权服务器器
5. 客户端和中央鉴权服务器器校对
6. 返回鉴权结果
⻚页⾯面
1. 发 JSONP 请求到业务鉴权服务器器
3. 返回 token 数据
2. 获取 token4. 调⽤用 init(token) ⽅方法7. 鉴权完成
业界⽅方案 OAuth2
-
业务实际情况
• ⻚页⾯面偶尔出现功能失效
• 弱⽹网、鉴权服务宕机
• 99% 的⻚页⾯面是公司,1% 的⻚页⾯面是第三⽅方
⽤用户侧鉴权
改进⽅方案
• 本地验证内部业务
• ⽹网络验证第三⽅方业务
• 验证只做⽩白名单匹配
业务鉴权服务器器
客户端 中央鉴权服务器器
⻚页⾯面
1%99%
-
业务实际情况
• 申请业务桥需要等待容器器组件发版
• 发版节奏不不⼀一致、升级引⼊入新⻛风险
• 平均每周都有业务桥申请
改进⽅方案
• 使⽤用数字签名验证替代⽩白名单
• 授权⽅方掌握私钥提供签名
• 容器器携带公钥和验证逻辑
开发者鉴权
业务
容器器团队 安全存储:私钥
数字签名
容器器内置:公钥
1. 申请
2. 调取
4. 分发签名
3. ⽣生成签名
业务代码
5. 代码中写⼊入签名6. 校验签名
-
发起桥调⽤用
使⽤用缓存结果
全局配置下发
调⽤用失败
检查调⽤用源 公钥验证桥签名
未命中⽩白名单
命中⽩白名单
JS SDK Native
是否已鉴权
是
否
桥⽅方法匹配
调⽤用失败
⽅方法不不匹配
私钥⽣生成桥签名 调⽤用成功
⽅方法匹配
简化桥鉴权
-
案例例⼆二 · ⽹网络优化
-
WebView初始化 加载主⽂文档建⽴立连接
加载样式 ⻚页⾯面渲染
加载脚本 ⻚页⾯面运⾏行行
⽆无反馈 ⽩白屏 展现
移动端⻚页⾯面⾸首屏时间消耗 = 资源加载 + ⾸首屏渲染 + 脚本执⾏行行
* 受限于设备性能,⻚页⾯面渲染和脚本执⾏行行时间需要重视 * 参考 https://tech.meituan.com/WebViewPerf.html
执⾏行行脚本
⻚页⾯面的加载渲染
-
渐进式⽹网络优化
请求前 请求中
主⽂文档
静态资源
数据请求
前端业务⽇日趋复杂 资源体积膨胀、请求数量量增加
HTTP 缓存
离线化
⽤用户⽹网络环境复杂 劫持篡改频现、弱⽹网情况常⻅见
HTTPDNS、HTTPS、HTTP2
专⽤用链路路
-
PWA
• 渐进式 Web 应⽤用
• Service Workers、App Manifest、Push
• 承载业务⽆无关逻辑
Service Workers
• 本质是⽹网络代理理 + 独⽴立 JS 进程
• Android 5.0+,⽀支持占⽐比约 84%
• iOS 11.3 已⽀支持
统⼀一容器器离线化
• 类似 Service Workers
• 基于请求拦截实现
• iOS 部分⽀支持 / WKWebView 暂不不⽀支持
离线化 / 所谓 PWA
LocalStorage 缓存
• 定制 Loader 强耦合发版流程
• 重度侵扰业务开发、容量量和能⼒力力受限
• 兼容性良好
-
不不要迷信离线化
• 我们不不可能⽐比浏览器器内核更更懂缓存
• 较 HTTP 缓存的⽹网络收益甚微
• 弱⽹网成功率提升、⾸首次性能提升
主⽂文档配合
• 避免完全 SSR
• AppShell + 客户端渲染
• 动态⽣生成主⽂文档何苦离线化
离线化 / 不不是银弹
install
activate
fetch
预加载资源 / ⽆无法覆盖⾸首次访问
初始化与清理理 / 伴随 install
使⽤用缓存或发起请求 / 确保能过期
-
⻚页⾯面 容器器 服务
⻚页⾯面加载
注册离线化
请求拦截 线上服务
离线打包离线缓存
读 / 写
桥调⽤用
代理理 访问
下发
类似 Service Workers 通⽤用的缓存拦截 可选开启离线打包
离线化 / 主逻辑
-
打包服务
增量量服务 计算增量量包3. bsdiff
1. 选择或爬取
分发服务
线上资源 计算全量量包2. ⽣生成 ZIP
4. 发布到 CDNCDN 计算分发策略略3.5. 策略略计算
离线化 / 离线包预下发
-
链路路优化 / ⻓长连接
基本假设
• ⾮非 HTTP 请求不不会被劫持
• 传输数据短⼩小⾼高频
业务相性
• AJAX 请求最适合
• 主⽂文档需要权衡
• 静态资源最不不适合
客户端客户端
DNS Server
WWW
业务服务
⻓长连接集群保持⻓长连 专线打通
meituan.com 103.37.152.41
-
链路路优化 / 容器器对接⻓长连接的踩坑过程
第三坑 / POST 跨域协商第⼆二坑 / 拦截处理理 POST第⼀一坑 / 桥性能有瓶颈
• evaluateJavascript 固有消耗
• 执⾏行行速度正相关响应体积
• ⽤用拦截器器替代桥
• 桥性能瓶颈⽆无从优化
• shouldInterceptRequest 缺陷
• 安卓不不⽀支持拦截 POST
• ⽤用⾃自定义 header 模拟 body
• ⻚页⾯面请求添加 header 承载 body
• 拦截后 header 换成 POST body
• ⾃自动发起 OPTIONS
• 浏览器器⾃自动进⾏行行跨域协商
• ⾃自定义 header 参与协商内容
• 篡改 OPTIONS 协商内容
• 移除⾃自定义 header
• 避免服务端感知到这⼀一层
-
链路路优化 / WKWebView 对接⻓长连接
UIWebView :: NSURLProtocol
WKWebView :: WKURLSchemeHandlerJSONP
XHR
iOS 11.0 +
完美拦截所有请求
所有信息封装在 URL 负载有限
-
案例例三 · 数据收集
-
请求上报
请求 URL + 状态 + 来源 URL
桥上报
桥名称 + 状态 + 来源 URL
⽤用量量
性能
流量量
访问成功率
桥成功率
桥性能
⻚页⾯面性能
容器器与桥的关键指标
-
上游数据队列列
下游数据队列列
Elastic Search
猎豹通道
性能平台
Falcon 报警
Lighter Stream
算⼒力力成本
• 维度展开的乘法规模
• 采样丢弃 + 减少维度
• 重 CPU 计算任务
• 调度算法
计算设施
-
总量量控制
• 基于设备 ID 采样
• ⽩白名单强制上报
• 容器器关闭时⼀一定上报
数据压缩
• ⼀一次请求聚合更更多记录
• 移除 query / cookie
• Gzip
误差
量量级
优化前
优化后
请求数减少 80%,流量量减少 75%
采样率 0.01
采样率 0.5
1%
10%
1e71e4
优化数据上报
-
上报那么多数据,你真的看过吗
• 每天 100W URL × 100W URL 的⽇日志
• 每天上报 全中国所有的 地理理坐标
简单的策略略减省⼤大量量的冗余
• URL 泛化
• 优化后每个维度减少 99% 冗余数据 • 地理理⽹网格
• 从⽆无穷多的坐标到有限的地理理⽹网格
https:// i .meituan.com/trip /123/456 https:// i .meituan.com/trip /abc/def
https:// i .meituan.com/trip /*/*
116.487353, 40.008305数据规模 e17
116.5, 40.0数据规模 e6
优化数据构成
-
运⾏行行稳定
体验⼀一致
功能丰富
性能良好 最次要
最优先 业务流程安全
统⼀一容器器与桥
补充设备功能
改善加载渲染
+
+
+
容器器与桥的原则
-
Q&A
-
更更多技术资料料欢迎关注“美团点评技术团队”
招聘:前端⼯工程师邮箱:[email protected]
mailto:[email protected]
-
• loadURL
• evaluateJavascript
• callback的调起与清理理
• JsPrompt / Android
• 加载代理理 / iOS
• ⽅方法映射 / Android + iOS
NativeJavaScript
桥的通信原理理
-
WebView
• 基于系统 WebView 增强
• 独⽴立于系统升级
• 从 Android 4.4 开始
PostCSS
桥通信
• JsPrompt
• Cordova
• JavascriptInterface
• 存在安全问题 / 4.2+ 注解显式启⽤用
容器器的内核选型 / Android
-
WebView
• 基于 UIWebView 增强
• ⽀支持 WKWebView
• 进程隔离 / 不不⽀支持任意拦截
桥通信
• shouldStartLoadWithRequest
• 构造 iframe 发起请求
• Cordova
• WKScriptMessageHandler
UIWebView
WKWebView
内存⽤用量量
UIWebView
WKWebView
渲染时间
30 + 5 × n
2 × n + x
容器器的内核选型 / iOS
-
WebView
• 基于 Web 技术
• 跨平台、多 App 复⽤用
• 性能⼀一般 / 功能依赖桥
Native 动态化
• 基于⾃自定义 DSL
• ⽤用户体验好
• 缺乏规范 / 维护成本⾼高
WebView
Native动态化
RN / Weex
功能
性能
WebView / Native 动态化