web前端用户体验-web前端开发电商网站前端架构
互联网教育行业风起云涌,优质的在线教学平台是每个互联网教育企业的核心和基石。 本文是tutorabc前端总监何俊在LiveVideoStackCon 2017的分享整理,主要介绍在线教学系统Tutormeet+前端开发实践,包括技术选型、性能优化、持续交付实践和APM系统.
致辞/何军
组织/LiveVideoStack
大家好,感谢LiveVideoStack提供分享的机会。 今天分享的主题是《优质互动在线课堂与开发实践》,是基于我司的一款教学平台产品。 首先,让我自我介绍一下。 我有十多年的前端和后端开发经验。 近年来专注于前端架构和前端技术体系建设。 我曾在途牛等互联网公司工作过。 我目前负责TutorABC的前端。
今天的话题将围绕五个方面展开。 如何打造优质的在线教学平台?
技术选择方向
优化方向
如何提高课堂互动性
工程相关的持续交付
前端APM
首先,让我们介绍一下我们的产品。 全称是TutorMeet+(简称TM+)。 上图是教学平台的教师界面。 可以看到布局还是比较合理的:有视频区、聊天区、教材白板区,最下面是学生名单。 学生端的界面看起来更明亮、更清爽,但整体布局与上图类似,包括双向白板和辅助教师控制功能。 这里只列出PC端效果图,其他包括微信端和APP端。
1、技术选型
1)为什么选择WebRTC?
我们选择WebRTC作为音视频技术栈,主要是基于以下考虑: 由于WebRTC是基于浏览器的,不需要下载或加载任何插件; 而且开发成本低,官方有详细的文档说明WebRTC的技术社区也比较齐全,常用的API有十几个,所以基本上半天就能熟悉WebRTC是怎么开发的前端; 并且有谷歌背景,开源安全; 目前 browse 对它的支持已经越来越友好了。 最后,Flash 将在 2020 年彻底退役,这是向 WebRTC 过渡的最重要原因。
2)WebRTC浏览器占比
根据上面的WebRTC浏览器占比我们可以看到,截至2017年9月,全球范围内支持WebRTC的浏览器占比已经达到70%,基本涵盖当代主流浏览器。 提到8月份Safari发布的第11版也支持了,这意味着WebRTC已经包揽了“当代浏览器”的所有阵地,而且这个比例在未来还会继续增加。
3) WebRTC API
WebRTC的前端相关API比较简单,主要分为以下三个模块:
它常用的API很简单,这里简单罗列一下。 基本上掌握了这些就可以开始动手了。 其中chrome://webrtc-internals是Google专门为开发者打造的监控平台,所以在做WebRTC的时候可能需要一直开启,这是很重要的一个。
4) WebRTC Polyfill 和适配器
在浏览器不断升级的过程中,这些API也会发生变化。 因此需要引入Polyfills或者Adapters来进行不同浏览器和浏览器版本之间的兼容和降级处理。 下面介绍三种常用的 Adapter。 :第一个是官方的Adapters; 第二个不仅会支持支持WebRTC的浏览器,还会通过插件支持一些不支持的浏览器,但是因为不是官方产品,而且以后随着浏览器对WebRTC支持的完善,推荐使用第一个。
5)不同场景下的技术选择
上图是TutorMeet+的教学场景,从业务形态上大致可以分为两种形式:
针对这两种业务形态,我们采用不同的技术选型。 首创大班教学方式,采用WebRTC+流媒体技术。 老师通过WebRTC与服务器建立PeerConnection,服务器通过推流到CDN可以支持10000人同时在线观看直播。 这个技术和主流直播网站的技术基本一致,比较接近,支持RTMP和HLS。 小班使用经典会议模式,支持智能服务切换,通过判断终端网络环境动态切换到相应服务器。
6)TM+前端架构
上图是TutorMeet+的前端架构。 前端UI层基于React。 在这一部分,我们将遵循 React 的一些最佳实践,将 Component 分为四个层次。 第一层是原子Component,即Widget; 还有一个纯粹的 UI Component——它可能是由各种原子 Component 组成的; 最后组装成一个业务Component,或者说是一个容器Component,里面封装了一些业务逻辑; 我们的状态管理是用Redux来完成的,所有的数据流通信都只是在Redux和业务Component之间进行,不会和上面组件库中的Component进行通信。 最后我们会封装多媒体的操作,一些WebSocket消息,一些工具方法和教师控件。
所有消息都通过中间件传输。 这里我们借用Express中间件的概念,通过一个通讯桥来与媒体服务和消息服务进行通讯。 所有的前端UI都可以通过配置参数动态加载所需的组件和模块。 值得一提的是,在 Facebook 最终将 React 迁移到 MIT 协议后,我们也同时将 React 升级到了 16 版本; 游戏开发使用白鹭引擎。 开发构建使用Webpack3.0、Babel/PostCSS,所有构建开发基于React Storybook,单元测试使用Jasmine。 以上就是整个TM+前端的整体架构。
7)网络课堂Web前端的特点
和普通的web应用相比,我们的交互性会更强,用户在页面停留的时间会更长——一节课大概45-60分钟,我们和普通的web应用不同的是,尽量避免刷新页面有可能,因为刷新老师端会导致所有学生黑屏。 而且由于整个页面的功能非常丰富,包括游戏、白板、教材、音视频等,这也导致整个静态资源包的体积非常大,那么如何打造一个长期稳定的和流畅的在线教育课? 这就需要对这些特性进行优化。
2.优化
优化将分为三个主要部分:
Build-time optimization,即编译时优化
运行时优化,
用户体验优化
1)构建时优化:
当代web前端工程肯定离不开构建。 5年前的所有网页,可能已经写好的源代码是在生产环境上运行的代码,但后来引入了web前端构建过程。 我们基于 Webpack 实现了这部分。 因为我们的课堂类型比较特殊,分为各种应用场景:公开课、大课、小课、课程回放等,这个和客户端不一样。 一般是客户端将所有的业务表单打包到一个APP或者程序中。 但是Web由于其灵活性,可以根据不同的课堂类型进行拆分,所以首先要做的就是将所有的业务类型拆分成多个条目,这就利用了Webpack的多条目特性。
接下来就是对一些大包进行Code Splitting——将代码进行拆分,将一些不需要首屏加载的JS单独打包成一个bundle,最后“按需”加载到页面中" 不影响首屏的渲染过程。
第三部分也是优化比较大的部分,就是按需加载本地优化的语言包。 许多第三方库都有一些语言包文件。 最典型的例子就是moment.js,原包可能达到好几百K,但其实很多东西是不需要的,所以我们要保证只加载当前环境需要的语言包。 经过上述优化后,整个包的体积会减小很多,这也是包优化最重要的手段——减小包的体积。
使用Webpack3.0的特性:Tree-shaking、Scope Hoisting。 Tree-shaking 的作用是去除项目中的死代码。 之前,我们使用 uglify.js 来删除死代码。 其原理是压缩代码逻辑,去除Source Code中不需要的模块和代码片段。 Tree-shaking 的不同之处在于“提取需要的模块”,进一步减小了包的体积,其配置也更加简单。 以官方给出的例子为例,上图中一共有三个模块,其中main.js模块指的是前两个模块,但是前两个模块实际用不到,如果在Webpack2.0或者没有Tree -shaking 接下来会把这两个包同时打进去,完全没有必要,Tree-shaking会去掉不需要的代码。
另一个重要的优化是范围提升。 熟悉Webpack的同学都知道,Webpack会为所有的模块分别生成一个闭包作用域函数,所有的模块会整合成一个数组。 模块通过数组引用。 要查找的索引。 比如之前官方例子中的三个模块,打包后会生成一个数组,包含三个Function,每个Function包含对应的代码,但是会出现一个问题:在做模块引用的时候,find会根据到数组中的索引,这是一种低效的方法。 但是通过Scope Hoisting,将闭包中的所有模块都提到了一级,最终生成的代码中不会再有数组,减少了包的大小,同时提高了运行效率。
Prepack也是一个比较重要的特性。 它是Facebook开发的一种打包优化工具。 它的作用是尽可能将运行时的代码求值前置到Compile-time,这样就不需要在运行时消耗太多的性能,而且可以直接在打包的时候做求值。 从而大大提高了运行性能,同时也减小了包的体积。 从下图可以看出,代码从六七行代码节省为一行代码(因为prepack处于实验阶段,还没有用于生产环境)。
这是通过这种前端构建方式实现的,Source Code和Production Code之间的差距会越来越大,保证Source Code的可读性和可维护性,而Production Code的执行效率最高,体积最小。 以上是构建时优化涉及的一些知识点。
2)运行时优化
代码真正上线运行时如何优化代码? 我们遵循Google的RAIL模型,很多UI层面的优化都遵循这个模型,主要分为四个部分:
响应是指人机交互时,人在交互时,机器必须在100毫秒内做出响应; 动画也是如此,保证在客户端达到60FPS的效果,这就要求帧计算在10ms以内,然后需要一定的时间渲染到页面上; 最大化空闲时间,即尽量让CPU不运行,这样观看体验会更流畅。
loading 是指页面在首屏第一次加载时需要在1000毫秒内提供内容。 谷歌做过相关实验。 首屏加载时间越长,客户流失越大。 如果达到8-9秒,客户根本不会停留在页面上。 所以TM+的所有优化都是基于这个模型。 .
这里不得不提的是像素流水线,也就是一帧帧是怎么制作出来的。 首先进行JavaScript计算,然后是Style——计算出当前元素的样式,然后是Layout——元素在页面中实际使用时会对布局产生什么影响,最后Paint和Composite是浏览器内核渲染的过程到页面并合并图层。
我们可以通过Chrome Devtools调试工具看到这五个步骤的时间比例。 如您所见,黄色部分是脚本时间,紫色部分是样式和布局时间,绿色部分是绘制和合成时间。 在这个例子中,Javascript 计算耗时将近 16 秒,这是典型的糟糕表现。
分析完以上情况,接下来就是Profile部分了。 这部分基本没有第三方工具可以选择。 可以说web前端用户体验,Chrome Devtools 是“史上最好的网页开发调试工具”。 虽然面板看起来很复杂,但调试前端性能时通常分为以下几个步骤:首先,选择一个峰值的值,可以看到上图中黄色区域的峰值很高,属于耗时带; 最下面的Timeline选择耗时帧,可以通过宽度来判断每帧耗时大小。 选择后,下方会显示该帧消耗的时间; 具体分析主要是Bottom-up、Call Tree和Event Log。 Item,通过分析它所有的调用栈和每一步消耗的时间,定位到需要优化的点,然后进行优化。
优化一个frame的过程大致分为四个步骤,中间有两个比较重要的环节:一个是分析band的火焰图,显示当前band中所有frame的调用栈,可以直观的看出哪一帧耗时长web前端用户体验,哪一帧的调用栈很深,哪一帧做了一些不必要的操作; 其次是内存分析,可以看到内存分析突然下降是因为浏览器做了垃圾回收。 但是,浏览器频繁的垃圾回收也会影响当前的执行性能。 它的主要用途是定位——定位垃圾回收,是否有内存泄漏,大对象是否已经释放。 基本上就是这六个步骤。
上图是一个在线课堂白板的优化示例。 执行配置文件后,我们发现脚本编写时间过长。 定位问题后,我们采用了一些优化方法:首先,复用了页面上的一些大型JavaScript对象,避免了频繁垃圾回收的过程; 其次,优化所有笔记在白板上的路径,这样整个浏览器渲染到页面的时间就会减少,消息通信的数据量也会减少; 流量控制是指在不影响用户体验的情况下,控制一些频繁触发的操作的频率; 最后是优化白板上图形的拖动、缩放等交互操作。 经过以上优化方式,可以发现脚本编写时间减少了30%,是比较大的提升。
3)用户体验优化
接下来,从用户体验的角度,如何优化我们的在线课堂? 其实和一般web开发的体验差不多。 例如:
预加载/延迟加载:预加载页面中的教材和视频,延迟加载图片不在首屏的教材。
响应式布局:根据不同分辨率的屏幕,视频的大小和白板教材的大小恰到好处。
渐进式用户体验:让用户在不同的设备上体验。 在一些不支持的,比如低端机上,降级处理也可以使用在线课堂。
层次结构管理在我们的应用程序中尤为重要。 因为页面很复杂,上面有很多层,包括布局层,上面的内容层,白板层,游戏层,控制层等等,因为层数很多,页面z- index需要管理:对每一层限制一个z-index段,比如第一层限制为0到10。
Web 安全颜色/安全字体:确保您在不同终端上看到的内容是相同的。 例如,苹果的字体在苹果电脑上使用,但在Windows设备上显示不正确。 不同的字体有不同的宽度,可能会出现换行的问题。 尤其是在白板上书写时,可能会出现错位,极为严重。 对用户体验影响很大。
3.互动性
除了优化在线课堂,我们还在教学过程的交互性方面对产品进行了优化升级。 这是因为K12教学对整个教学内容的趣味性要求很高。 课堂已经不能满足用户的需求。 这里有一些功能。
1)游戏化白板
首先介绍游戏化白板的概念,主要应用于少儿教学场景,即老师可以玩游戏让学生玩,从而提高整个网络课堂的互动性。 除了师生互动之外,学生还可以通过游戏进行比赛,并配备了一定的激励机制。 这部分由白鹭引擎实现。