作者 | 阿里文娱前端技术专家 狼叔

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

本文将对这一技术演进之路进行总结和展望,有 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 开源,截止 2020 年 1 月底已有 657 star,具体使用方式和源码请查看 egg-react-ssr 项目地址:

https://github.com/ykfe/egg-react-ssr

第一版:Bigpipe + JQuery

1. 原理:

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

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

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

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

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

2) 性能

2. 当前:React SSR

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

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

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

3. 组件级同构: 支持 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 数据兜底进行页面容灾。

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

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

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

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

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

下面是发布的流程图:

6. 性能对比

以预发版本播放页为例,使用 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)可扩展。

在 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 个阶段。

  • 在 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 环境下,希望前端更加简单、高效。

1. 规范

上图的最小示例代码中描述了一个页面如何进行数据获取和展示,其中 render(必选)、getInitialProps(可选) 均为方法,在 SSR 模式下页面数据传输模式可以为简单模式和 Bigpipe 模式。

2. 实现

实现上基于 FaaS 规范,使用 React 同构写法,构建后的目录结构如上图,最终通过调用 ssrRender 方法进行服务端渲染,将页面 HTML 返回客户端。

3. 生态

目前集团沉淀的前端生态已经被开发者大量使用,从 React 的组件库、框架、多端方案, 到 Node.js 的 WEB 框架,相信在未来的 Serverless 环境下,会有更多优秀的方案或框架加入到集团生态,使前端开发更加的快捷、高效。

三、致敬所有多端坚守者

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

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

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

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

活动推荐

随着大前端的发展,Node.js 也已经发布到 v13,其应用场景从脚手架、辅助前端开发(比如 SSR、PWA 等)的快速开发实践,到 API 中间层、代理层,甚至到后端开发都有非常成熟的经验。

GMTC 全球大前端技术大会(北京站)设置“Node.js 2020”专题。本专场将重点邀请一线专家给大家带来他们在各自领域的实战经验。

疫情期间,大会也会为大家送上 3 月福利,大会门票限时 5 折起,还有极客时间企业版年卡免费送!活动截止 3 月 31 日,还没有参与的你抓紧喽!

联系票务经理鱼丸:13269078023(同微信)

可以扫描下图二维码或者点击【阅读原文】,查看官网了解更多详情!

性能提升三倍!优酷Node.js重构之路相关推荐

  1. 10+倍性能提升全过程--优酷账号绑定淘宝账号的TPS从500到5400的优化历程

    10+倍性能提升全过程--优酷账号绑定淘宝账号的TPS从500到5400的优化历程 摘要: # 10+倍性能提升全过程--优酷账号绑定淘宝账号的TPS从500到5400的优化历程 ## 背景说明 &g ...

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

    在2017年底,优酷只有Passport和土豆的部分页面用Node.js,PC和H5核心页面还都是PHP模板渲染.而最近2年,基于阿里巴巴的技术体系,我们对PC.H5多端进行了技术改造.在2019年, ...

  3. node.js学习之路(1)

    node.js 属于后台语言,后台语言还有php,java等. 优势:1.性能好   node.js VS php   86倍 2.跟前台JS配合方便 3.node.js便于前端学习 https:// ...

  4. Node.js学习之路24——Express框架的app对象

    1.express() 基于Node.js平台,快速.开放.极简的web开发框架. 创建一个Express应用.express()是一个由express模块导出的入口top-level函数. cons ...

  5. Node.js学习之路09——Path基本介绍

    Path 1. normalize()将非标准路径字符串转换为标准路径字符串 解析路径字符串中的..和.字符串,返回解析后的标准路径 将多个斜杠字符串转换为一个斜杠字符串,例如将\\转换为\ 将win ...

  6. Node.js学习之路--npm包管理工具操作汇总

    因为在学习使用Express(第三方Web开发框架)时需要下载这个包,所以使用npm包管理工具这个相关的操作,现在将其相关的操作进行汇总. npm命令在cmd或者powershell中进行;注意:使用 ...

  7. 提升 Node.js 应用性能的 5 个技巧

    "如果nginx没有在你的节点服务器之前,那么你可能就错了."Bryan Hughes在Twitter上说 Node.js是全球领先的用JavaScript--世界上最流行的编程语 ...

  8. Node.js 应用故障排查手册 —— Node.js 性能平台使用指南

    楔子 前一节中我们借助于 Chrome devtools 实现了对线上 Node.js 应用的 CPU/Memory 问题的排查定位,但是在实际生产实践中,大家会发现 Chrome devtools ...

  9. 优酷全自研跨平台动态模板引擎重磅开源啦!

    动态模板引擎大大提升了优酷的线上用户体验,同时也大大减少了研发门槛.为了和大家交流以及让更多的人享受这一技术,优酷已经将其开源.通过和社区合作,动态模板引擎将会发展的越来越好,实现多赢. 前言 优酷客 ...

最新文章

  1. 维基链连续3日暴涨接近100%,能否延续夏日神话?
  2. php zend框架入门,Zend Framework 入门——快速上手
  3. ndk use of undeclared identifier #39malloc#39
  4. 【知识发现】隐语义模型LFM算法python实现(一)
  5. 安裝TA-Lib到想要罵髒話
  6. python3.5链接SQL2017,读取数据库中的数据
  7. RunJs使用评测(IE9)
  8. 后缀的形容词_高三语法总复习:名词形容词变名词的后缀
  9. 计算机支持协同工作不是多媒体应用,计算机支持的协同工作概观.PDF
  10. 智能网联车初现规模 360 Sky-Go团队“把脉”安全风口
  11. LeetCode 98. 验证二叉搜索树(递归)(迭代)
  12. CAN和CANFD的区别总结
  13. 外观模式(Facade模式)详解
  14. mysql(多级分销)无限极数据库设计方法
  15. SF中对象发出消息后在chatter上显示名字的问题
  16. ASP.NET MVC 支付宝sdk 查询订单状态 填坑攻略
  17. 用python做软件_女友闹别扭不用担心,Python做个软件轻松哄好
  18. 限制guest账号访问硬盘权限
  19. firefox常见问题解答
  20. Mac 解决 gyp: No Xcode or CLT version detected! 报错

热门文章

  1. Window10 JDK8安装与配置详细步骤
  2. 《南京零距离》主持人孟非的打拼故事
  3. 分享一个java写的中国象棋代码以及相关视频
  4. web 项目 连接mycat 读写分离失效问题
  5. kk录像机怎么剪辑视频 kk录像机视频剪辑教程
  6. 【第57题】输入、输出系列5-文件锁定功能
  7. 基于51单片机的无线智能家居设计
  8. 路由传参的几种方式(含params、query)
  9. iOS字体号数与像素对应关系
  10. ORA-27104,ORA-01565,ORA-27077,ORA-00093,ORA-01012,ORA-32001,SP2-0714,ORA-12547,sqlplus /nolog 连接不上