c站主站重構總結,fre強力驅動

NO IMAGE

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 重構的也真的不小

測試用例也全部重新寫了::>_<::感謝在這個過程中提供幫助的小夥伴啦!

最後發一下前端群群號:813783512

相關文章

HTMLEmail的編寫

「從模板消息改版訂閱消息」小程序推送

【Oracle學習06】DML與併發性,UNDO,死鎖

瀏覽器進程架構的演化