转载

c站主站重构总结,fre强力驱动

halo,大家好,我是 132,今天给大家打来一篇关于c站重构的总结文章

c站是去年成立的弹幕网站,今年暑假流量暴增,如今已经是【中国第三弹幕网站】了

c站所有代码开源,涉及到很多语言和技术栈,除了一些业务层面的最佳实践,还有一些业务轮子,如 celty,eplayer 等都是来自 c站 的积累产出

c站主站重构总结,fre强力驱动

毫不夸张的说,这种开源力度,业界找不到任何一家网站啦

c站 github 地址: github.com/cliclitv

重构背景

shi 就一个字,shi 山就两个字,c站经过一年半的业务积累,中间不断的删减需求,导致 shi 山已经很高

加上流量暴涨,导致 vue ssr 性能瓶颈越发明显

长时间的需求总结,pc 主站扮演的角色与以前大不相同,我们发现大部分用户还是移动端为主,pc 端应该尽可能的减少维护量,但应该更具品牌性

重构目标

  1. 减少维护量

是的你没有看错,减少维护量是重构的重中之重,我们最大程度的删除了主站的需求,最终首页只保留五个模块,内页只保留视频播放和弹幕,去掉搜索页,个人页,ugc页等页面

与此同时,隔壁b站更不断地增加需求:漫画,轻小说,音频,英雄联盟……

  1. 增强品牌性

pc 端的职能虽然变少了,但是它仍然是非常重要的角色没有之一,我们还叫它——主站

它更多的是用来担当【c站】这一品牌的,我们和其他网站一样,确立了c站品牌色

emmm 就是那个,基佬。紫。

c站主站重构总结,fre强力驱动

因为其他颜色都被用了,蓝(b站),红(a站),绿(爱奇艺),黄(太阿里)……

所以我们使用了基佬紫,也确定了性向:女性向

总得来说,这次重构,也正式宣告我们和b站的不同:

  • 不做中国版youtube,只做视频领域,不做大而全,只做小而美
  • 女性向为主,二次元为主

代码重构

因为 pc 主站变得小而美了,代码也会变得超级小而美,哈哈,以下:

fre

首先,就应该使用小而美的前端框架,fre,哈哈哈

这可能是 c站的一个优势,就是有自己出品的前端框架,这在其他网站是很少有的,这样的好处就是我们真的可以做的 0 依赖,0 第三方库

fre 是我写的纯 hooks 的 react-like 前端框架,它只有 600 行,却复现了 react Fiber 架构(Concurrent 和 Suspense),它拥有相同的 hooks API 的表现,但它也有一些不同:

  1. 不同但更简单的链表 diff 算法
  2. 和 vue 类似的精确更新

由于 fre 经过一年的迭代,它几乎所有行为都是可预测的,测试覆盖率 90+

github 地址: github.com/yisar/fre

已经是时候用在生产环境啦,积累一些业务 bug

  1. 异步更新队列和批量更新

这是我在业务中遇到的第一个坑,什么意思呢?

如果 A 和 B 两个组件,同时 setState,同时更新组件的话,那 fre 应该将 A 和 B 放到一个队列里,更新完 A 然后更新 B

如果 A 同步 setState 两次,则 A 只能进入队列一次,批量进行更新

以上,是异步更新队列的两条规则,这在 fre 之前是没有的,直到写了 c站,才暴露出来

偏偏还很重要,所以啊,有时候测试未必可信,业务才是大千世界

  1. 精确更新

有如下代码:

function App () {
  const [state, setState] = useState(0)
  return (
    <div>
      {state}
      <A count={1}/>
      <button onClick={() => setState(state+1)}>+</button>
    </div>
  )
}

function A(props){
  const [state] = useState(new Array(100000))
  return <div>{props.count}</div>
}
复制代码

以上代码,重点在于,A 组件初始化了一个 10000 的数组,只要 App 组件 rerender 那么 A 组件一定会 rerender,每次 rerender 都会初始化一个长度很大的数组,偏偏其实 rerender 的时候又用不到

这就引来了一个重复渲染的问题

这也是 vuer 一直黑 react 的地方

我觉得吧,很少有人会在这次 rerender 里面写大量 hook,所以其实从优化角度,可能不明显

但是我看了 vue-next 的源码,发现只是内置了 shouldComponentUpdate 而已,这对我而言非常简单,所以我也实现了一个

目的嘛,能减少一点算一点吧,同时以后不用被黑了,哈哈哈

以上,是关于 fre 在这次 c站业务中的一些重构

use-routes

use-routes 是我当时为了 hooks 写的前端路由,hooks 说起来好奇怪,一直没有一个广泛流传的路由,虽然有 wouter 这种新星,但是其实国内用的还是少

import { h, render } from 'fre'
import { useRoutes, push } from 'use-routes'

const routes = {
  '/': () => (
    <div>
      <p>home</p>
      <button onClick={() => push('/home/jack')}>Go jack</button>
    </div>
  ),
  '/home/:id': ({ id }) => (
    <div>
      <p>{id}</p>
      <button onClick={() => push('/')}>Go home</button>
    </div>
  ),
}

const App = () => useRoutes(routes)

render(<App />, document.getElementById('root'))
复制代码

use-routes github 地址: github.com/frejs/use-r…

为什么我要用 use-routes 而不是 wouter 呢?

首先,我写 use-routes 的适合,wouter 还没出现,然后,其实很大的一个原因是,fre 没有 context stack,而 wouter 依赖了它

这一点其实很重要,context stack 是 react 很冗余的一部分,虽然它不适合 hooks,但是其实它被用到很多地方

这应该是 fre2 要搞的,立个 flag 先

eplayer

ep 是c站御用播放器,它很好看,这次重构的同时,也对他进行了更改

将默认配色改为基佬紫,哈哈哈

c站主站重构总结,fre强力驱动

其他

其实一开始打算使用 vue3 的,但是 vue3 现在真的没法用,我一边改代码一边用都非常痛苦

原因是没有 vue-loader,而 vue 对 jsx 支持太简陋了,我还提了 pr,结果他们说他们有自己的 jsx 解析器

然后就是 celty 了

这最初也是我为了搞定 hooks 路由问题,而写的微前端原型框架,但是感觉不太好搞,先弃坑吧

UI 截图

最后放一下截图哈

c站主站重构总结,fre强力驱动
c站主站重构总结,fre强力驱动

总结

其实总结的话,其实这次的业务代码很少,很快就写完了

但是对于 fre 来说,因为这次业务重构,fre 重构的也真的不小

测试用例也全部重新写了::>_<::感谢在这个过程中提供帮助的小伙伴啦!

原文  https://juejin.im/post/5def9b49f265da33f9794ba6
正文到此结束
Loading...