看优酷 Node 重构之路,Serverless SSR 未来可期

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: 在2017年底,优酷只有Passport和土豆的部分页面用Node.js,PC和H5核心页面还都是PHP模板渲染。而最近2年,基于阿里巴巴的技术体系,我们对PC、H5多端进行了技术改造。在2019年,React SSR第一次且成功地扛起双11重任,具有一定意义。

作者 | 优酷前端技术团队

在2017年底,优酷只有Passport和土豆的部分页面用Node.js,PC和H5核心页面还都是PHP模板渲染。而最近2年,基于阿里巴巴的技术体系,我们对PC、H5多端进行了技术改造。在2019年,React SSR第一次且成功地扛起双11重任,具有一定意义。

image.png

本文将对这一技术演进之路进行总结和展望,有2点突出变化:

1) 我们将优酷C端核心页面全部用Node重写,完成了PHP到Node.js的迁移。在没有PHP同学的情况下,前端可以支撑业务;

2)从Bigpipe+JQuery到React SSR,性能明显提升。PC页面首屏渲染降到150ms、播放器起播时间从4.6秒优化到2秒。H5站上了React SSR后,性能提升3倍。

演进之路

优酷前端团队在之前 PC 首页/频道页面改造的基础上,将 React 服务端渲染沉淀出了一个技术框架,该项目已经在 Github 开源,截止目前已有 900+ star,具体使用方式和源码请查看egg-react-ssr项目地址

第一版:Bigpipe + jQuery

image.png

核心还是采用Bigpipe + Nunjucks模板编译实现的。模板tpl和data编译,生成html,这个部分其实Biglet的render方法里做的。然后在请求写入的生命周期上,将html分块写入浏览器。

1)采用Bigpipe有2大核心优势:

  • 兼容IE6等低版本浏览器,不得不用。现代Web框架只支持主流浏览器。之前开发对jQuery都比较熟悉,二者结合是当时最完美的选择;
  • 业务属性决定的,新老接口拼凑(PHP的,Java的,HTTP的),采用Bigpipe,利用Node.js并发,将接口请求从前端转移到服务端,即可以保证业务快速迭代,也可以保证页面性能;

将页面进一步抽象,以前理解是每个模块都Biglet。但实际使用中,进行分级处理会更好。

  • 首先渲染布局;
  • 核心:渲染首屏,对于播放页重点是播放器和剧集内容;
  • 其他:看不到的可以偷偷加载,及时不展示也没问题;

2)性能

image.png

当前:React SSR

采用React SSR,是在Node.js Bigpipe做了一些之后才考虑的。稳定性有了,低版本浏览器兼容有了,接下来就要考虑团队成长和架构升级的问题。

  • 会JQuery,不会React,大家是非常想用想学的;
  • Bigpipe虽好,但依赖模板编译,在内存和CPU使用上非常高,优化不易;
  • 老系统慢慢下掉,之前混着新老接口一起用的方式也需要重新梳理。为了快速迭代而产生的“狗粮”还是要吃的;

其实,如果把React当模板,结合Bigpipe,可以达到和之前解决方案一样的效果。问题不能很好的利用React的优势,React自身也提供SSR基本能力。所以,我们需要做的是如何结合React的SSR,构建出符合业务特点的SSR框架。

组件级同构: 支持 CSR/SSR 一键切换

在技术调研期,我们分别看了next.js和easywebpack。

  • easywebpack在使用上,我不认可使用egg的worker来做。easy-team的方案本地开发采用了在Node中启动webpack编译bundle的方案,将服务端bundle打包在内存中,agent进程通过memory-fs提供的api来读取文件内容,并且通过worker与agent进程的通信,来让worker进程可以获取到文件的字符串内容。然后采用了Node的runInNewContext api,类似于eval的方式去执行js字符;
  • next.js写法上是完美的。结合上面讲过的Biglet,请求方法抽取成静态方法,可以复用。另外在服务端渲染,先执行请求方法,是最高效的方式;

写法上,最终定了采用next.js式的写法。

该技术方案具有以下优点:

  • 实现方式简单优雅
  • SSR/CSR 无缝切换
  • 全面拥抱 JSX
  • 拥抱阿里生态

我们的代码既可以在服务端运行又可以在客户端运行。这里需要重点讲一下CSR和SSR,我们是业内第一个这样做的。它也带给我们一个意外惊喜,那就是在服务降级上提供了一个更好的方案。

播放页的服务支持两种渲染方式,当服务端有渲染压力时或集群不稳定时,可以切换为客户端渲染,服务端只负责页面的 SEO 数据获取,渲染工作交给浏览器。另外一种方式是当数据源服务出现问题时,可以使用 CDN 数据兜底进行页面容灾。

3组件: 多模块升级配合改造

播放页的页面组件包括首屏、分发区、弹幕、播放器、评论等等一系列的组件,此次播放页升级对应的组件也做了重构,其中弹幕、评论已随新版播放页一起灰度上线。

服务端 JSBundle 发布: 变更无需发布应用

在 SSR 改造中我们总结出了一套基于配置下发的服务端和客户端文件的流程。该流程有以下优点:

  • 构建方式一致
  • 发布方式一致
  • 服务端 bundle 变化无需走服务端发布
  • 及时生效

下面是发布的流程图:

image.png

性能对比

以预发版本播放页为例,使用 chrome 无痕模式测试。

优酷PC播放页:150ms首屏,首屏文档大小37kb。文档到达时间平均为 120ms。

优酷H5播放页性能提升3 倍。

未来:Serverless SSR

从beidou、next.js、egg-react-ssr到Umi SSR,可以看出服务端渲染是很重要的端侧渲染组成部分。无论如何,React SSR都是依赖Node.js Web应用的。那么,在Serverless时代,基于函数即服务(Functions as a Service,简写为FaaS)做API开发相关是非常简单的:1)无服务,不需要管运维工作;2)代码只关系函数粒度,面向API编程,降低构建复杂度;3)可扩展。

image.png

在FaaS下,如何做好渲染层呢?直出HTML,做CSR很明显是太简单了,其实我们可以做的更多, Serverless时代的渲染层具有如下特点:

  • 采用next.js/egg-react-ssr写法,实现客户端渲染和服务端渲染统一;
  • 采用Umi SSR构建,生成独立umi.server.js做法,做到渲染;
  • 采用Umi做法,内置webpack和React,简化开发,只有在构建时区分客户端渲染和服务端渲染,做好和CDN 配合,做好优雅降级,保证稳定性;
  • 结合FaaS API,做好渲染集成。

通过提供ctx.ssrRender方法,读取dist目录下的Page.server.js完成服务端渲染。

核心要点:

  • ssrRender方法比较容易实现;
  • 采用类似Umi SSR的方式,将源码打包到Page.server.js文件中;
  • 在发布的时候,将配置,app.server函数和Page.server.js等文件上传到Serverless运行环境即可。

综上所述,我们大致可以推出架构升级的4个阶段。

image.png

  • 在CSR中,开发者需要关心React和webpack;
  • 在SSR中,开发者需要关心React、webpack和egg.js;
  • 在Umi SSR同构中,开发者需要关心React和egg.js,由于Umi内置了webpack,开发者基本不需要关注webpack;
  • 在未来,基于FaaS的渲染层,开发者需要关心React,不需要关心webpack和egg.js。

在这4个阶段中,依次出现了CSR和SSR,之后在同构实践中,对开发者要求更高,甚至是全栈。所有这些经验和最佳实践的积累,沉淀出了更简单的开发方式,在未来Serverless环境下,希望前端更加简单、高效。

规范

image.png

实现

image.png

生态

image.png

致敬所有多端坚守者

感谢苹果,将用户体验提升到了前无古人的位置。移动互联网兴起后,PC Web日渐没落。在AI时代,没有“端”的支持可以么?明显是不可以的。不只是“端”的概念,而是真真正的用户体验。

1)我们可以利用PC/H5快速发版本的优势,快速验证AI算法,继而为移动端提供更好的模型和数据上的支撑;

2)多端对齐,打好组合拳。既然不能在移动端有更大的突破,大家只能在细节上血拼。按照木桶原理,哪个地方是短板,整体水位就在那里。

今天的大前端,除了Web外,还包括各种端,比如移动端、OTT,甚至是新的物联网设备。我们有理由相信Chrome OS当年的远见:“给我一个浏览器,我就能给你一个世界”。


好书推荐:
前端代码是怎样智能生成的

image.png
关注「Alibaba F2E」
回复 电子书,立即下载

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
3月前
|
JavaScript Java Serverless
函数计算产品使用问题之如何使用Node.js编写程序
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
3月前
|
消息中间件 JavaScript 中间件
函数计算产品使用问题之WebIDE编写的Node.js代码是否会自动进行打包部署
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
3月前
|
弹性计算 前端开发 JavaScript
Serverless痛点解决问题之实现SSR 应用的页面瞬开如何解决
Serverless痛点解决问题之实现SSR 应用的页面瞬开如何解决
35 1
|
4月前
|
JavaScript NoSQL Serverless
函数计算产品使用问题之如何创建一个自定义运行时并指定Node.js版本
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
3月前
|
JavaScript Serverless Linux
函数计算产品使用问题之遇到Node.js环境下的请求日志没有正常输出时,该如何排查
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
3月前
|
缓存 JavaScript Serverless
阿里云云效产品使用合集之如何在Serverless Devs阶段指定Node.js版本
云效作为一款全面覆盖研发全生命周期管理的云端效能平台,致力于帮助企业实现高效协同、敏捷研发和持续交付。本合集收集整理了用户在使用云效过程中遇到的常见问题,问题涉及项目创建与管理、需求规划与迭代、代码托管与版本控制、自动化测试、持续集成与发布等方面。
|
6月前
|
运维 JavaScript Java
Serverless 应用引擎产品使用之阿里云Serverless函数计算中,在Node.js环境中执行jar文件如何解决
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
6月前
|
JavaScript 前端开发 Serverless
函数计算新功能— 支持 Node.js 18 、Node.js 20 运行时
从2024年2月起,函数计算正式发布 Node.js 18 运行时和 Nodejs.20 运行时,函数计算2.0和函数计算3.0都支持新的运行时,目前新运行时处在公测状态,欢迎大家来体验。
738 0
|
2月前
|
JavaScript
NodeJs的安装
文章介绍了Node.js的安装步骤和如何创建第一个Node.js应用。包括从官网下载安装包、安装过程、验证安装是否成功,以及使用Node.js监听端口构建简单服务器的示例代码。
NodeJs的安装
|
1月前
|
JavaScript 开发工具 git
已安装nodejs但是安装hexo报错
已安装nodejs但是安装hexo报错
26 2

热门文章

最新文章

相关产品

  • 函数计算