腾讯课堂小程序开发实践与思考调用插件

你好,我是陈天忱,来自腾讯CSIG在线教育部。我所在的团队主要负责腾讯课堂平台的开发和维护,我从加入团队以来就围绕着小程序做了很多探索和优化,目前也是腾讯课堂小程序的负责人。

腾讯课堂小程序的技术演进路线

在我刚进入团队的时候,腾讯课堂小程序的工具链还处在比较原始的阶段。除了在编码层面利用了web比较成熟的scss、postcss、lint、typescript结合gulp做一些语法层面的编译以外,在测试、构建npm、上传、设置体验版、发布等阶段都是依赖的小程序开发者工具和管理后台,人工手动操作来完成的.

石器时代

在这个阶段,大部分都是简单地利用一些现有的工具,我们称之为腾讯课堂小程序的石器时代。

这个阶段存在几个明显的问题:

构建和上传依赖人工操作,有可能会因为流程操作失误而导致现网事故;

由于发布流程的不规范,需求并行时经常会出现发布撞车的情况,导致体验版相互覆盖造成预发布验证成本。

为了解决人工操作带来的隐患,我们从零开始基于小程序提供的命令行工具打造了小程序CI。让源码编译、构建npm、上传、生成开发版/体验版二维码、自动化测试等流程在CI流水中自动流转。

为了解决发布流程不规范的问题,我们将小程序的发布也接入到了业务发布平台。在发布平台上进行CheckList、CodeReview、发布评审、发布环境管理、发布静态资源等流程的流转,确保需求发布的质量、合规和有序。

工业时代

解决了开发流程中的问题之后,我们将更多的精力放到了小程序的研发效能与性能上。开发和构建阶段我们打造跨端的公共模块,通过kbone进行同构开发,利用云开发来辅助首屏性能优化,以及代替部分后台的开发,在构建方面将构建工具从gulp迁移到webpack,能对构建常务进行更细致的优化。

在发布之后,通过完善监控告警,将发布质量做到可视化的体现,并能够对出现的问题得到及时的接收和感知,减少用户的反馈。

近现代

到这里我们可以看到整个技术演进的过程,它涵盖了小程序开发、构建、测试、部署发布以及监控,形成了小程序的DevOps开发模式,这其中具体是怎么做的呢?

DevOps

构造“爽”的开发体验

首先是开发阶段,我们想要形成一个可以称之为“爽”的开发体验,并不仅仅是指coding阶段,还需要覆盖到测试以及发布阶段:

编码阶段——业务逻辑跨端可复用

测试阶段——改动持续集成、测试与开发解藕

发布阶段——规范化、流程化、可追溯

为此我们分别通过打造跨端可复用的公共模块、小程序CI、统一业务发布平台来提升开发体验。

提升开发体验

跨端公共模块

这里从一个实际场景出发,我们之前有这样一个需求:产品希望在各端的课程详情页有一个提示当前此机构正在直播的课程,可以引导用户跳转到直播间听老师讲解课程的细节。

公共模块

梳理一下这个需求的流程,发现其实还是挺简单的:

详情页渲染完成后->调用接口拉取直播间数据->渲染引导模块->用户点击跳转直播

可以看到,业务的主逻辑在各端都是一样的,但如果去看这些逻辑的细节就会发现其实各端需要的是不一样的实现,比如发起请求的api在浏览器和在小程序中是不一样的;提示的疲劳度控制需要用到本地的缓存能力,浏览器和小程序的api也是不一样的;然后在业务上,直播间在三端的页面地址也是不一样的。

各端逻辑的不同

通过ifelse或者switch的方式,在运行时判断当前的执行环境,然后调用不同的分支逻辑当然是能够实现需求的,但是这种方式会让一个端同时存在三端的逻辑,这样的逻辑多了之后,会造成比较明显的代码冗余,而在小程序端由于有2M的包大小限制,对于代码冗余是比较敏感的。

要解决代码冗余的问题,大家会很自然地想到构建时注入一个环境变量,通过tree-shaking的能力在不同端构建出对应端所需要用到的逻辑。但这个方案对于构建工具有着一定的要求,而在实际的工作场景中,新老项目往往由于历史的原因,不仅仅是源码,在构建上的技术栈也是有很多历史包袱的,比如gulp、fis、webpack等,如果要全部统一起来成本和风险都会比较大。

所以我们需要一个能够跨端复用,按需打包,而且不依赖项目构建体系的公共模块。

我们基于gitsubmodule的方式从组件、业务、工具三个维出发,每个维度根据具体的逻辑按照执行环境将其拆分成同构目录(isomorph)、浏览器目录(lib)、小程序目录(wx),各个项目将lib目录或者wx目录作为引用的入口,而入口文件会继承或者透传导出isomorph目录下的逻辑,对环境有依赖的特殊逻辑则在lib目录和wx目录下分别实现。

在开发阶段通过路径别名来统一引用路径,例如小程序的项目中设置tsconfig.json的paths为"ke-modules/*":"submodules/ke-modules/*/wx",这样就可以统一业务层面的代码逻辑。在构建阶段submodule会通过ts单独编译成js,如果是h5和PC的项目就只会将isomorph和lib目录构建到产物中,小程序的项目就只将isomorph和wx目录构建到产物中。

公共模块的编译阶段

这样就确保了在保证兼容性的基础上不会产生冗余的代码,以此来满足我们之前提出的几个需求。

小程序CI/CD建设

我们搭建小程序的CI/CD的起因,是由于开发者工具中很多人工操作带来的一系列问题,比如:

在构建过程中,很容易漏掉构建npm依赖

在上传时的版本信息和版本号也不规范

不同需求的体验版需要管理后台切换,需求并行非常不友好

开发版二维码需要开发者实时提供,影响测试进度要解决以上这些问题就需要从自动化和流程控制来入手。

我们先是基于小程序官方提供的一个命令行工具进行了封装和扩展,支持小程序的npm构建、上传、获取二维码、自动获取版本号、版本信息等功能,并作为小程序CI流水线中的核心插件。

CI流水线支持通过githook、OpenAPI、手动的方式触发执行。在流水线的流转执行中,完成代码拉取、分支检查、版本号迭代及版本信息更新、小程序代码包上传、开发/体验版二维码获取,同时归档小程序产物、sourcemap等文件便于对性能和错误的分析。

小程序CI/CD的流程建设

建设了这样一套CI/CD的流程之后,之前遇到的问题就都得到了解决。

通过在构建过程中获取依赖的npm信息来判断是否需要更新及构建npm,并自动执行;

上传时根据Angular的gitcommit规范,自动迭代major、minor、patch的版本号,更新changelog;

CI使用机器人账号上传小程序,通过业务发布平台对小程序的发布环境进行管理,避免发布冲突;

这是我们在CI/CD上面的一些实践经验,以及在开发体验上面的一些处理方案。

小程序性能优化

小程序的启动方式分为冷启动和热启动,而小程序的性能瓶颈大部分也都集中在冷启动这一阶段。

小程序的冷启动

体积优化

业务代码的体积优化需要通过构建来解决,以一个项目的常规结构来看,我们一般会将一些有可能复用的模块放置到公共模块中。如下图所示,引用关系如果只进行编译的话,根据小程序的规则,公共模块和组件的大小都会被计算到主包中,我们希望通过构建来优化产物结构,避免主包太大的问题。

主包太大

再者,随着需求的迭代,可能某一个组件的引用就丢失了,这种情况在小程序的规则下,依然会被计算在主包里面,可以看下面这张图。我们希望能通过构建将未使用的模块或者组件进行过滤。

未使用模块未过滤

另外,如果某一个分包与主包引用了同一个模块,这时候将这个模块计算到主包中是OK的,但如果这个分包是一个独立分包的情况下,再去引用主包的模块,是有可能报错的。上面这种情况需要通过构建的方式将模块复制一份放到独立分包下面才能保证小程序的正确执行。

独立分包引用报错

我们面对的上面三个问题有一个核心思路是需要在构建的过程中,针对小程序的规则进行依赖分析。下面是我们对比目前市面上比较成熟的构建工具,从四个维度进行了分析:

支持组件的依赖分析

根据对比的结果,webpack对于需求的支持还是比较成熟的,我们最终决定选择webpack作为小程序的构建工具,但是webpack也不支持小程序的组件,这一点就需要我们自己进行支持了。

以app.js作为入口文件,根据小程序的配置规则找到对应的json文件,逐层递归就可以将整个小程序所使用到的页面和组件分析出来,并将所有的页面和组件都作为webpack的entry,就可以获取到小程序中js模块的引用信息了。

通过plugin对引用信息根据一定策略进行计算chunk:

分包处理

例如,某一个页面引用了一个模块,先判断模块是否在分包内,如果在分包内则按照常规方案打包;不在分包内则判断引用它的分包是否为独立分包。如果是独立分包则复制一份(新建一个chunk);是普通分包则收集是否被多个分包引用。若不是,则将模块移动到分包下(新建一个chunk,并将原来的删除)。

计算完chunk之后就可以通过webpack的load去处理另外的资源文件,包括css、image、font,提取静态资源文件,替换引用路径。

处理资源文件

处理完成后的效果也相当明显,我们的主包从1900多kb优化到了900多kb,优化幅度达到50%,总包的一些体积也优化了27%。

体积优化效果

优化的体积主要来自以下三个方面:

模块下沉到了分包

对未使用到的组件和模块进行了过滤

静态资源文件上到CDN

我们的优化在实际的启动耗时上也有比较显著的效果,主包下载耗时优化了43%,js的注入耗时优化了18%。

启动耗时优化效果

兼容小程序的SDK方案

另一方面,当小程序需要通过npm的形式使用一个比较复杂的SDK时,由于小程序的npm包需要单独构建一次,无法做到编译时按需打包,这也会遇到体积较大的问题。

在我们的实际业务场景中就有这样的问题,腾讯课堂作为在线教育业务,有个核心能力是直播互动,就是用户在线上上课的过程中聊天、举手、连麦、抽奖等形式的交互行为。

为了让这个核心能力能够达到跨端跨业务的复用效果,我们团队开发了一个直播互动的SDK,对外抛出简单的API,内部设计了接口层、适配层、通道层、策略层,结构非常清晰,使用起来也很方便,初始化后开发只需要监听或请求对应的命令字即可,无需关心内部的转化,并且能够利用ts的类型推断能力直接拿到通道返回的数据类型。

改造前架构及使用方式

但是当我们在小程序端进行接入时,遇到了几个问题:

为了支持跨端跨业务,SDK内置了所有功能的逻辑,在小程序端使用会造成大量的包体积浪费

针对web设计,不兼容小程序;单独维护一个小程序的版本成本比较大

不同项目和业务对SDK的迭代会导致版本管理混乱

要解决上面这些问题,我们必须对SDK进行升级改造。

我们改造的方案是进行插件化处理,将接入层(业务层)和适配层作为SDK的内核抽离出来,并添加了pluginAdaptor对插件进行适配管理,将策略层和通道连接层的逻辑进行抽象处理,制订好对应的规范,根据抽象类和业务需求实现对应的策略插件和通道插件。

插件化改造

在业务中的改造非常简单,只需要初始化之前注册当前场景和功能所需要的插件,后续在使用上与之前完全一致,业务的改造成本非常低。

改造后使用方式

兼容性上通过rollup打包,在构建时注入不同的环境变量,输出对应端所需要用到的bundle。

rollup打包

插件化改造之后,好处就显而易见了:

按需引入,运行时它的体积是最小的,改造前后SDK运行时体积从384KB减少到42KB,优化了近90%

多包结构迭代比较清晰,内核和抽象通道也很稳定,各个插件可以进行单独的版本迭代

跨端复用能力得到了扩展,统一维护

运行时的请求优化

请求的优化也是小程序性能优化中很重要的一环,在冷启动和页面跳转的过程中,我们分别对请求时机以及弱网阻塞两种情况进行了优化。

请求时机上,可以利用小程序的全局app实例将数据请求的时机提前到页面加载之前,进一步利用小程序的数据预加载能力,将首屏数据的请求时机提前到启动小程序时:

请求优化

页面加载前发起请求的流程如下,在onLaunch或者页面跳转时就直接发起下一个页面的请求,并将请求的Promise挂载在app实例上,当页面加载完成出发onLoad的时候则直接通过app上的Promise返回进行渲染,根据我们的统计平均可以优化100ms的耗时,而且相对静态的数据可以通过本地缓存的方式,在二次加载此页面时通过缓存数据渲染,达到秒开的效果。

在页面加载前发起请求的流程

而数据预拉取则类似于web的服务端渲染,在启动小程序时通过云函数根据启动参数调用业务后台的服务获取数据并返回给小程序,小程序启动后就可以直接使用预拉取的数据进行渲染,预拉取成功可以平均优化90%的首屏数据请求耗时。

数据预拉取流程

除了上面常规情况的请求优化,我们还注意到小程序有一个网络使用限制,最大的并发限制是10个,这就会造成隐患。因为在小程序加载和用户交互的过程中会产生很多的上报请求,例如PV上报、错误日志等,在弱网的情况下,很容易出现上报请求响应慢而阻塞了业务请求的发送导致超时,而我们也确实收到了类似情况的反馈。

为了优化弱网情况下存在的隐患,我们对请求队列进行了优化,通过设置请求池与等待队列,并劫持wx.request,在发送请求时对请求的url进行优先级排序,将业务请求设置为高优先级的请求,上报请求的优先级降低。当请求通道相对紧张时会将高优先级的请求优先发送,低优先级的请求在请求通道空闲时再进行补发。

弱网下的请求排队

在实际运行过程中的逻辑如下图:

弱网下的请求排队运行逻辑

渲染优化

首屏优先,分步渲染

但由于小程序的双线程模式,通过setData的方式更新视图是同步更新逻辑层数据,异步更新视图层数据,所以并不能简单地在处理完一部分数据后调用setData再继续处理其余的数据,甚至通过Promise也做不到分步渲染,而使用setData的回调或者setTimeout的方式又会出现逻辑嵌套的问题,降低代码的可读性和可维护性。

针对这个问题,我们的解决方案是基于setTimeout根据Promise的表示封装了一个PromiseMacro的类,这样我们就可以向使用Promise一样通过then方法将小程序的渲染拆分成多个步骤达到渐进式渲染的效果。

渐进式渲染

质量保证的监控体系

一个产品的质量不仅仅是靠好的产品设计和代码质量,还有很大一部分需要通过收集操作和性能日志,为技术优化提供方案,而对现网报错的比例及数量进行监控,能让我们及时响应并修复。之前我们的小程序上报也依赖了好几个上报系统来完成:

通过BadJS来收集前端报错和操作日志

通过Wang进行测速上报

通过Monitor进行打点监控告警

通过Tdw进行产品需求上报

通过不同的系统进行上报会存在一些问题:

依赖的SDK比较多,每一个SDK的API都不一致,学习和维护的成本会比较高,这一点对于新人来说尤其明显;

每个SDK上报的数据结构也不一样,想要查找对应的数据,就必须去对应的统计平台进行搜索。

解决这些问题的首要任务就是需要对这些上报的SDK进行整合,根据产品和业务需求将日志、测速、监控、上报收归到一个SDK里面,并统一上报的数据结构,部分功能会在SDK中进行备份转发,保证原上报系统的功能也能得到利用。

imlog监控体系

再结合小程序提供的几个API就可以在日志收集的同时对用户进行多维度的统计:

Grafana性能监控

在统一上报数据结构的前提下,就可以自定义制定多维度的统一看板,降低质量监控的成本。

图片性能监控可视化

总结

随着我们课堂小程序的技术演进,围绕小程序逐渐形成了DevOps的开发模式:开发阶段,我们打造了兼容小程序端的公共模块,提升了小程序30%~40%的研发效率,同时在CI/CD建设方面,减少了人工操作的风险,充分利用工程化自动化来解放开发的生产力,而且小程序CI建设的很通用化,公司内部有140+的项目接入。

开发体验提升

在性能优化方面,我们通过在体积、请求、渲染方面的优化,将冷启动下的首屏性能优化了1.5s,达到了42.7%的优化比例。

性能优化提升

在监控告警方面,通过小程序的API再结合收拢的上报SDK,可以让统计力度更细,而且可视化可定制。

图片监控告警提升

展望

1.异步化打包策略

分包异步化可以极大地缩小首屏包的大小,目前分包异步化的特性已经适配了2.11.2的基础库版本,兼容性的问题也已经得到了解决;接入分包异步化的能力,可以尝试在小程序构建打包时将一个页面拆分成首屏包+异步逻辑包+异步组件包的形式,结合分包预加载功能,将首屏的代码包下载耗时和加载耗时降至最低。

2.基于录制回放的自动化测试

小程序团队很早就支持了小程序的自动化测试,但是在UI自动化测试方面,测试用例的维护成本是最大的痛点,我们尝试在本地录制操作流程,按照一定的约定转换成测试用例,可以极大地降低测试用例的维护成本,提高代码质量。

作者简介

陈天忱腾讯CSIG在线教育部前端高级开发工程

2019年加入腾讯,目前是腾讯前端高级工程师,IMWeb团队成员。负责腾讯课堂平台的教学教研方面的开发和维护,作为腾讯课堂小程序负责人,在小程序性能优化、持续集成等方面有深入的见解和丰富的实践经验。2019年在公司内部开发推出了小程序CI并持续优化迭代,其跨系统的兼容性及优秀的使用体验,被各个BG超过150个项目接入并使用,赋能开发测试及产品,依托于腾讯CI开发的小程序插件获得2020年度腾讯CI年度优秀插件。

THE END
1.在线教育平台架构设计课程平台架构在线教育平台架构主要包含以下几方面 1. 课程在线购买,学员签约、课程学习、在线练题及考试、交流社区 2. 课程音视频的管理、存储、在线播放 3. 视频的直播 主要针对在线教育平台的复杂业务场景进行重点设计,当前识别到的复杂业务场景主要包含以下几方面 1. 在线教育PC端端,日常的登录、浏览课程、购买课程并不会形成https://blog.csdn.net/licbc/article/details/117526882
2.在线教育平台51CTO博客已为您找到关于在线教育平台的相关内容,包含IT学习相关文档代码介绍、相关教程视频课程,以及在线教育平台问答内容。更多在线教育平台相关解答可以来51CTO博客参与分享和学习,帮助广大IT技术人实现成长和进步。https://blog.51cto.com/topic/zaixianjiaoyupingtai.html
3.教育机构如何进行在线教学平台的搭建首先,对教育机构的课程、教师资源、教学质量等方面进行系统性分析,充分调研潜在的目标客户群与市场需求,从而构建具有针对性的在线教学平台。 **2. 平台技术架构:** 选取合适的云服务提供商和技术方案,以保障平台的稳定性和扩展性。以下是几种常用的技术架构: https://news.17173.com/z/kfb/content/11032024/235604562.shtml
4.在线教育云课堂系统设计云课堂在线教育系统的架构设计需要满足高并发访问、灵活的业务逻辑、可扩展的内容管理和稳定的支付体系。通常采用分层架构设计,常见的分层如下: 前端层:用户界面,支持Web端和移动端。前端通过REST API或GraphQL与后端交互,展示课程内容、用户中心和支付页面。 https://www.jianshu.com/p/b24c68909332
5.在线教学平台学习者参与方式研究前沿领域根据ICAP框架,在线教学平台中学习者的各类学习行为(如观看视频、完成作业、参与讨论、线上测试等),可以根据其潜在的认知过程被划分为不同的参与方式,从而实现对学习者学习行为、参与方式和学习成果等的描述和理解,为平台的改善、课程的设置和教学的改进等提供理论支撑和有效建议。https://www.eduwest.com/html/2021/qianyanlingyu_0908/610.html
6.“三融合三平台四步走”打造教学资源库建设新样板(一)满足职教改革需求,推进三融合,精准设计整体框架 以服务石化产业高质量发展为宗旨,在分析调研的基础上统筹构建课程和教学资源体系,按照智慧职教平台的资源库逻辑架构和应用路径,推进三融合,即国家标准与AHK国际标准相融合,“政行企校”跨界融合,协同建设,学历教育与职业培训相融合,面向4类用户建设专业园地、课程中心http://www.dyxy.edu.cn/s.php/syhg/item-view-id-69245.html
7.浙江师范大学网络教学平台更多国家级精品在线课程 幼儿园课程 王春燕 更多杭州幼儿师范学院在线课程 特殊教育概论 朱宗顺等 学前儿童艺术教育(一) 吕耀坚等 幼儿园课程 王春燕 信息技术教学应用 潘振锋 更多创新创业教育系列课程 TRIZ创新方法 冯林 创新创业实战 陆向谦等 大学生创业导论 http://zjnu.fy.chaoxing.com/
8.线上教学平台使用培训方案(精选11篇)为了确保事情或工作安全顺利进行,通常需要预先制定一份完整的方案,方案具有可操作性和可行性的特点。那么优秀的方案是什么样的呢?以下是小编收集整理的线上教学平台使用培训方案(精选11篇),供大家参考借鉴,希望可以帮助到有需要的朋友。 线上教学平台使用培训方案 1 https://www.ruiwen.com/fangan/6607664.html
9.江西师范高等专科学校关于开展2020年春季线上课程教学的通知利用校内教学平台进行教学的课程,会全程记录学生端的学习数据和教师端的教学数据,教师可在电脑端的课程后台自定义设置线上考核方式及权重比例,要求各任课教师每次上课必须做学生签到考勤,授课课程的每章至少设置1次章节测验、布置1次课后作业或进行1次讨论互动。在线学习期间的签到考勤、学习表现、作业、互动、章节测验等https://www.jxsfgz.com/info/1009/2415.htm
10.微课堂微课堂在线教学平台微课堂-微课堂在线教学平台-微课程教学平台是一种非常流行的教育方式,对于教育机构来说,微课堂在线教学平台不仅成本相对较低,而且很方便,对于微型化教育,或者选择合适的微型化平台可以事半功倍。 在选择SAAS网络教育系统时,需要将自己的需求结合起来,选择一个功能完美、强大、能够在一个模式下解决各种网络教育需求的能力https://www.yunduoketang.com/article/ljr2026.html
11.线上教学平台运行总结(通用15篇)培养学生德智体美劳全面发展是我们教育的根本,为促进学生身心健康均衡发展,疫情期间学校也在线上开展了全学科教学。四年级的小学科任教教师高度重视,积极推送课程,组织学生参与活动。 总之,立足本职工作、关注学生需求、从学生实际出发、努力完成教学任务、为学生创造更好的学习氛围,是我们不断追求并为之不懈奋斗的目标。https://m.oh100.com/kaoshi/jiaoxuezongjie/646722.html
12.232门职业教育国家精品在线开放课程数据分析课程学时数、教学周数、课程内容单元数量等信息可以在一定程度上反映课程建设的科学性、完整性。依据课程平台公布的课程学时数、开课教学周数、课程内容单元数量等信息进行统计分析,发现认定的职教国家精品在线开放课程平均学时数为59学时,平均教学周数为16.7周,平均单元数为10.6个单元,这一结果与高职院校教学安排大体一致https://www.mzlxy.cn/info/1016/9795.htm
13.在线课程平台当拒“水课”近日,教育部等五部门联合发布《关于加强普通高等学校在线开放课程教学管理的若干意见》(以下简称《意见》),要求在线开放课程要做到线上与线下课程同管理、同要求。《意见》还明确在线开放课程教学管理责任主体,并提出高校不得将在线开放课程考试完全交由在线课程平台等第三方负责。 https://www.gzstv.com/a/a5c2e10ee6d74ff3a32b108934f1c644
14.西安欧亚学院线上通识课程为大学生量身打造,足不出户提升通识课程全面解析计算机相关知识、信息检索及工具软件的使用,提升学习者的信息素养,以适应现代信息社会的需求;提炼办公技巧,使学习者熟练运用Office软件解决实际问题;线上与线下学习融合,增强自主学习能力。 课程框架:实用的办公技能 本课程旨在通过情境模拟和职场实战等教学模式,培养学习者的职场办公技能,提高学习者处理日常办公https://tsjy.eurasia.edu/info/1053/1470.htm
15.在线教学平台介绍西安交通大学城市学院教学科研部在线教学平台介绍 为了普及主要网络教学平台的使用方法,提升教师在线教学能力与课程运行管理水平,保障疫情防控期间教学进度和教学质量,现将常用四个在线教学平台功能介绍、使用指南公布如下,请老师们及时查看学习并积极试用。教学服务中心将持续开展在线教学平台的系列培训课程,以推进信息技术与教育教学深度融合的教与学改革http://jwc.xjtucc.cn/info/1119/2135.htm
16.“赣教云”线上教学平台使用指南微信关注“赣教云”公众号(在微信搜索公众号“赣教云”,点击关注),点选“资源应用”中的“线上教学”,即可参与学习。 电脑、平板: 在浏览器中输入网址:http://study.jxeduyun.com/ ,即可进入学习。 中小学在线课程表 (一)线上教学时间 1、小学一、二年级:周一至周五,上午9:00-11:30,下午2:30-3:55; https://www.meipian.cn/2nxford6
17.学堂在线方案包括课堂智慧教学平台“雨课堂”、校内网络教学平台“学堂云”、在线课程运行平台“学堂在线”以及课程国际化推广平台,为高校提供从辅助课堂教学,到SPOC教学,到国家精品在线开放课程运行,再到课程和学位国际化的在线教学服务。 2、高校教师培训项目 学堂在线汇聚全球优质资源,为高校用户量身定制教师培养方案,名师讲授、https://www.xuetangx.com/about/