女王控的博客

2021TWeb学习笔记

以下是本次参加 Tweb conf 2021 的学习笔记

目录

主会场

分会场(看过)

Node.js & 大前端

  • Kubernetes 应用的 BFF 便捷开发
  • 跨端开发,也可以这样玩

低代码 & 可视化

  • 基于 serverless 的低代码平台实践

编辑器 & 研发效能

  • 稿定视频编辑器背后的故事
  • 在线文档冲突——OT 算法

以上是本次大会看过的,下面是本次大会未看过的,仅做记录

分会场(未看)

Node.js & 大前端

  • 从 0 开始,打造腾讯自研的跨端&动态化框架
  • Puerts-UnityUE 下的 Typescript 框架
  • 云时代的前端开发

低代码 & 可视化

  • WebAssembly 在哔哩哔哩创作中心的实践
  • 厘米秀 3D 形象 DIY 渲染技术揭秘
  • 信息流运营场景中的低代码探索与实践
  • 低代码页面编辑器的设计和实现

编辑器 & 研发效能

  • 腾讯文档工程实践
  • 微信小程序真机调试
  • CDN 版本化解决方案
  • 由兴趣驱动开源 Cherry Markdown 成长之路

Flutter 音视频开发实践

Flutter 简介

跨平台技术发展趋势

跨平台框架优势:一次开发,多端运行,组件复用,提升效率

  • Hybrid App(2011 年)

    • 页面运行在 webviwe
    • 开发迭代快
    • 受限于桥接层,拓展性能差
    • webview 渲染性能差
  • ReactNative(2015 年)

    • 原生控件渲染
    • 性能好于 webview
    • 渲染时要和 Native 通信
    • JIT 编译
  • Flutter(2018 年)

    • dart 语言
    • 同时支持 JIT 和 AOT 编译
    • 自渲染引擎
    • 性能接近原生

Flutter 架构

2021 10 25 15 50 32

  • FrameWork: 是一个 Dart 实现的 UI SDK,从上到下包括了两大组件库、基础组件库、图形绘制、手势识别、动画等功能
  • Engine: 实现 Flutter 渲染引擎、Dart 虚拟机、Platform 通信通道、事件通知、插件架构等功能
  • Embedder: 操作系统适配层

Flutter & Web 开发的差异

2021 10 25 15 52 08

  • StatelessWidget(无状态):内部没有保存状态,UI 界面创建后不会发生改变。
  • StatefulWidget(有状态):内部有保存状态,当状态发生改变,调用 setState() 方法会触发 UI 发生更新。
css{6-8} 复制代码
.grey {
   background: #e0e0e0;
   width: 320px;
   height: 240px;
   font: 900 24px Roboto;
   display: flex;   align-items: center;   justify-content: center;}
js{2} 复制代码
var container = Container(
   child: Center(      child: Text(
         "Lorem ipsum",
         style: bold24Roboto
      ),
   ),
   width: 320,
   height: 240,
   color: Colors.grey[300]
);

TRTC 简介

腾讯实时音视频致力于帮助开发者快速搭建低成本、低延时、高品质的音视频互动解决方案:

  • 适用于视频会议、在线教育、互动直播等场景
  • 客户有腾讯会议、企业微信、陌陌、贝壳找房等

2021 10 25 16 01 10

SDK 设计

2021 10 25 16 09 19

  • 业务层:提供给开发者调用的 API,如进退房、推拉音视频流等近 100 个接口
  • 实现层:管理 API 的核心类,可扩展、易用、性能好
  • 通信层:通过 MethodChannel 消息通道连接 Flutter 和原生 sdk,数据通讯能力升级
  • 原生层:底层是 Android 和 iOS 原生 sdk

挑战点 1-如何实现复杂的类结构体传输?

背景

  • flutter 本质是 dart 调用 native 的接口,并异步返回 native 的数据
  • 原生 sdk 存在着大量类结构体的类型定义,原有消息通道不支持传递此类型

方案

Flutter 类结构体 -> Flutter 类结构体转 Map 对象 -> Flutter JSON 序列化 -> 通信层 JSON 反序列化 -> Android 类结构体

同时可以对参数进行约束,类型校验,提升易用性

2021 10 25 16 22 25

挑战点 2-图片怎么高效在 Flutter 和原生 sdk 之间传输?

背景

直播过程中给视频设置水印等接口需要把 flutter 项目定义的图片资源传给原生 sdk,但是 flutter 没有 bitmap 这种数据类型,如何把 flutter 项目的图片资源转成原生 sdk 需要的 bitmap?

方案

利用文档目录实现图片传输,通过文档目录(android 和 flutter 都可访问)传递文件路径的方式来实现共享

2021 10 25 16 26 16

带来的问题:拷贝文件会导致比较高的耗时,如何解决?

优化

图片传输优化-平台共享 asset:Flutter 的 asset 资源被打包在原生资源包下面,通过 AssetManager 可直接访问,节省中间层拷贝耗时。

2021 10 25 16 28 34

挑战点 3-视频在 Flutter 里面如何渲染?

背景

采集视频流 -> 云服务 -> Android 原生 -> Flutter

将摄像头采集的每一帧数据通过 MethodChanne 传递到 Flutter 中,性能消耗大

方案

  • 外接纹理:可以将原生端 opengl 图像数据共享给 Flutter 进行渲染。需要原生 sdk 提供视频帧图像数据回调接口,实现较为复杂。
  • PlatformView:主要适用于 Flutter 中不太容易实现的组件,如 WebView、视频播放器、地图等。给 Flutter 提供了嵌入 Android 和 iOS 平台原生 view 的能力。

最后采用 PlatformView 方案

2021 10 25 16 37 14

2021 10 25 16 37 41

优化

用 oppo 的一个低端机进行测试,房间有 6 个用户的时候,第二屏画面渲染异常,使用 PerfDog 性能狗,分析出 GPU 占用过高

2021 10 25 16 39 51

列表懒加载与回收

2021 10 25 16 42 26

列表优化后 GPU 占用从 72% 下降到了 53%,视频画面正常渲染显示,优化完成后的性能检测如下

2021 10 25 16 45 55

2021 10 25 16 46 25

由上图可看出,cpu、内存跟 Android 原生的占用差不多,GPU 比 Android 原生性能还差约 15%

视频帧直出

2021 10 25 16 47 42

性能消耗点:视频 view 的每一个像素流经附加的中间图形缓冲区,显著浪费显存和绘图性能

优化方案:将视频帧数据直接输出到 SurfaceTexture 上

图像纹理共享

2021 10 25 16 49 34

Flutter 与 Android 原生共享图像纹理数据,优化后性能检测如下

2021 10 25 16 50 37

2021 10 25 16 50 56

Flutter 优化后 GPU 性能提升了约 10%,基本能达到 Android 原生 sdk 的水平

挑战点 4-客户接入如何提效?

背景

面临的问题:原始 SDK API 繁多,客户接入耗时很久

场景化方案的价值:客户可以寻找契合自己业务的场景方案,参考源码实现,提升接入效率

2021 10 25 16 53 24

方案

2021 10 25 16 54 30

核心目标:易接入,开箱即用,降低客户的接入门槛

2021 10 25 16 55 38

SDK:接口不超过 30 个,而且语义更加场景化

未来

flutter 桌面端的支持不太好,未来需要支持全平台

2021 10 25 16 57 59

2021 10 25 16 59 11

腾讯文档渲染优化之路

DOM

方案

Sheet

使用 Handsontable 的 dom 渲染,主要页面构成为:

  • 单元格:数量多、结构类似
  • 图表、选区:数量少,结构独立

2021 10 26 13 56 57

doc

使用 React 作为 dom 渲染

优化

渲染管道

  • layout 优化

    • 尽量避免改变元素的几何属性(例如宽度、高度、左侧或顶部位置等)
    • 修改 paint only 属性(例如背景颜色、文字颜色等)-> repaint
  • Paint 优化

    • 使用 will-change 或 translateZ 等提升元素层级
    • 使用 transform 和 opacity 属性

滚动复用

类似于长列表的虚拟滚动:复用 DOM、离屏时销毁 DOM

缺点

随着页面复杂程度、页面滚动速度的增加,重排重绘开销随之线性增长

Canvas

2021 10 26 14 13 53

极端场景的全表双边框

背景

2021 10 26 14 17 48

渲染时间:单边框 6.71ms -> 双边框 14.91 ms

  • 绘制量:对比单边框,直接翻倍
  • 对接逻辑:需要额外的对接逻辑

产生原因

2021 10 26 14 23 17

  • 上下文设置 style

    通过 canvas 上下文设置的 fill_stylestroke_style 等状态, 实际上都是 CanvasStyle 这个类的实例

  • GC 逻辑低效

    GarbageCollected 自己实现了一套 GC 逻辑,并不会走 V8 引擎的 GC,不如 C++ GC 高效

  • 性能开销

    Canvas API 调用设置状态操作,性能开销较大

Canvas 在渲染过程中针对单元格需要渲染背景色、边框线、富文本,而不同的颜色、文本等又需要不同的状态,所以需要频繁切换状态机

  • 渲染单元格:渲染背景色、渲染边框线、渲染富文本
  • 渲染⽂本:渲染 color(black 文字)、渲染 color(red 文字)、渲染 color(blue 文字)

2021 10 26 14 29 28

优化

切换状态机优化

通过提前收集、统一整理,减少切换状态机

2021 10 26 14 31 43

  • 遍历待绘制内容

    遍历待绘制的所有边框线、文字等

  • 相同状态内容整理

    相同状态的绘制内容,进行合并、排序等整理

  • 分类渲染

    整理之后的内容,根据状态机进行分类渲染

渲染复用
  • 离屏 Canvas

    离屏 Canvas 缓存主 Canvas 绘制内容

  • 复用

    直接复用离屏 Canvas 缓存的内容

2021 10 26 14 36 26

针对业务逻辑减少 GC

浏览器垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存

  • 频繁 GC 导致帧率不稳定

    • 大量创建对象会导致更频繁的 GC
    • 频繁的 GC 会导致帧率不稳定,引起卡顿
  • 对象池优化

    • 建立对象池缓存,从对象池获取对象
    • 减少渲染主循环过程中新建对象操作,从而减少 GC

Alloy 精确统计 FPS

如何精确、自动化统计 FPS?

背景

现有 Web 前端 FPS 统计⽅式:

  1. 类似 Chrome devtools 的开发者⼯具

    1. 需要人工实时监测、无法自动化
    2. 更加适合开发阶段进行自测
  2. RequestAnimationFrame API

    1. 统计的 FPS 结果不够准确,因为以两次主线程执行时间间隔作为一帧
    2. 模拟交互不够真实,需要引入脚本且实现对应代码

同时由于主线程阻塞情况下浏览器的优化,即使嵌入死循环 js,滚动依然流畅,影响 FPS 的统计

js 复制代码
function block() {
   while (true) {}
}
setTimeout(block, 2000);

Chrome 浏览器在主线程阻塞情况下,会将页面滚动处理由主线程移交给合成线程

2021 10 26 14 52 50

此时需要我们理解 FPS 本质是:

  • 帧率

    浏览器渲染动画或页面每一帧的速率

  • 渲染管道

    浏览器渲染每一帧经历的固定流程

同时主线程阻塞情况下,页面渲染可能在其之后的合成线程、GPU 线程进行处理

2021 10 26 14 55 39

方案

  • Chrome devtools performance:普遍常用的 Chrome devtools performance 面板
  • Tracing view:信息更加详细、全面的的 Tracing view 工具,使用 chrome://tracing 开启

Tracing view 介绍

  • 进程、线程

    展示对应进程、线程信息

  • Flow

    事件对应的流向

  • TRACE_EVENT

    表示浏览器内核函数调用执行情况

2021 10 26 14 58 57

分析主线程阻塞时滚动

  • 主线程 V8 执行 js 死循环
  • 合成线程处理滚动

2021 10 26 15 01 18

寻找关键 TRACE_EVENT

  • 关键 TRACE_EVENT

    关键 TRACE_EVENT 出现次数 = 帧渲染次数

  • 排除主线程

    将寻找关键 TRACE_EVENT 的路径集中到主线程之后的流程

2021 10 26 15 03 54

确定关键 TRACE_EVENT

2021 10 26 15 05 04

确定关键 TRACE_EVENT,合成线程中 ProxyImpl::ScheduledActionDraw 可以作为关键 TRACE_EVENT 进行 FPS 统计

AlloyPerf 实现原理

截止 2021-10-26 15:10:27,AlloyPerf 未开源

// TODO 查看 AlloyPref 源代码

2021 10 26 15 06 48

  • Docker 集成环境

    docker 集成 chrome、chrome driver 统一环境,支持跨平台

  • 自动化 CI

    支持自动化 CI,通过测试用例自动化测试统计对应、对应交互的页面 FPS

    2021 10 26 15 08 35

远程办公下开发测试协同如何提效

异地开发测试协同

背景

  • 开发联调:截图、传递抓包文件、需要同步联调信息
  • 测试:测试测出问题反馈给开发,开发需要重现步骤,然后推到测试环境才能让测试测,问题定位步骤长很低效
  • 产品体验:如果异地的老板想看测试环境的效果,需要部署外网地址才能访问

业界方案

vpn + 修改 host

实现的途径:

  1. 手动修改
  2. 借助工具修改(比如 switchhosts)

但暴露的问题有

  1. 功能受限
  2. 不支持移动端
  3. 信息同步慢

由此开发联调、测试、产品体验效率都很差

vpn + 代理工具

实现途径:

  1. whsitle
  2. fiddler
  3. charles

对比以上的 vpn + 修改 host 分别有以下优点

  1. 支持各种复杂规则配置
  2. 支持移动端
  3. 分享抓包信息

但是通常一个代理工具需要以下步骤才能使用

  1. 启动代理工具
  2. 配置系统代理或使用浏览器插件
  3. wifi 代理
  4. 手机配置 https 证书

由此导致的问题有:

  1. 体验前置步骤多、成本大
  2. 分享抓包路径长
  3. 配置不共享
  4. 本地需要启动代理服务

测试、产品的体验效率很差

vpn + 测试域名

优点:访问方便

缺点:

  1. 无抓包,定位问题复杂
  2. 配置固定,修改配置麻烦
  3. 切换环境不方便
  4. 安全性如何保证

测试、产品体验很方便,但联调、定位问题的效率差

痛点

  1. 访问不方便
  2. 测试环境中业务信息保密性
  3. 本地启动代理服务
  4. 定位问题不方便(抓包、分享不方便)
  5. 多人协作修改规则不方便(配置不共享)

如何协作提效

TDE 的现状与未来规划

TDE 的实现原理

如何创造一门上万人使用的语言

Kubernetes 应用的 BFF 便捷开发

跨端开发,也可以这样玩

基于 serverless 的低代码平台实践-TWEB

稿定视频编辑器背后的故事

在线文档冲突——OT 算法

从 0 开始,打造腾讯自研的跨端&动态化框架

Puerts-UnityUE 下的 Typescript 框架

2021 Tweb 云时代的前端开发 王伟嘉

WebAssembly 在哔哩哔哩创作中心的实践

厘米秀 3D 形象 DIY 渲染技术揭秘

信息流运营场景中的低代码探索与实践

低代码页面编辑器的设计和实现

腾讯文档工程实践

微信小程序真机调试

CDN 版本化解决方案

由兴趣驱动开源 Cherry Markdown 成长之路

评论

阅读上一篇

WebGL 理论基础——基础概念
2021-11-12 00:32:53

阅读下一篇

TypeScript 入门学习
2021-10-22 13:47:44
目录
0%