欧美日操-欧美日韩91-欧美日韩99-欧美日韩ay在线观看-xxxx色-xxxx视频在线

嗶哩嗶哩(B站)的前端之路

2018-03-12 16:12:17 大云網  點擊量: 評論 (0)
過去的開發模式中,我們采用了以后端為主的 MVC 架構方式。具體來說,每次項目評審后,前后端會先一起約定好接口,之后分別進行開發,開

過去的開發模式中,我們采用了以后端為主的 MVC 架構方式。具體來說,每次項目評審后,前后端會先一起約定好接口,之后分別進行開發,開發完,前端需要把頁面提供給后端,后端配置上數據,然后返回出來。正式基于這樣的開發模式,導致了總工作量的增加,同時溝通和聯調成本的消耗也十分顯著。

 

前后端分離

 

為了擺脫這種前后端過分依賴的情況,(其實前端也不想每次修改或者發布都要后端這邊發布,后端也不想每次前端只改個標題,都要發布一下,影響服務的穩定性),那么先從前后端分離開始吧~

 

前后端分離,最基本的兩種模式,有中間層和沒有中間層。

 

第一種,沒有web中間層就很簡單,提供一個html模板放到靜態資源機上面,html模板里面引用了所需的js和css,訪問頁面的時候 把這個靜態模板返回給用戶,然后執行js 在瀏覽器端通過ajax請求api拿到數據,渲染頁面。

 

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

(前后端分離)

 

第二種,有node中間層,隨著2009年,Node的橫空出世,把前端慢慢的推向了后端,有了node之后,JavaScript可以做更多的事情。

 

B站,一開始做前后端分離的時候,也確實按照第一種方式去做的,現在還有一些頁面仍然是這種模式,例如:https://www.bilibili.com/account/history (可查看網頁源代碼)。對于不需要seo的頁面來說,是一個不錯的方式。前端開發完成之后,通過webpack打包出對應的js和css 上傳到cdn上面,然后將webpack打包出來的 引用了對應的資源的html文件 上傳到一臺專門的靜態機上面,然后運維配置路由 將頁面流量導過去就好了。后端的同學只需要提供對應的api接口就可以。前后端分開維護,自己按照自己的節奏走,降低了頁面與服務的耦合度

 

這種方式確實是一種很快能夠進行前后端分離的方法。我們花了一段時間,在pc端使用vue 進行重構,移動端H5端 用react進行了重構。 進度很快,但是也慢慢展現出了弊端。

 

首屏的時候,因為他要等待資源加載完成,然后再進行渲染,會導致了首屏有白屏,如果是單頁面還好,如果是spa應用 那么 他的加載時間就會變得很長,白屏時間會很影響用戶體驗,再有就是由于國內的搜索公司 對于spa 應用沒有很好的兼容,導致了客戶端渲染會對seo非常的不友好,有seo 需求的頁面就很迫切的需要服務端渲染。

 

0?wx_fmt=jpeg

(B站的首頁,右邊模塊做了服務端渲染,左邊模塊沒有做服務端渲染)

 

那么,依賴node 進行服務端渲染就被提上了日程。

 

選型

 

首先進行node 框架的選型,市面上主流框架有三種,hapi express koa ,還有一些是經過一些封裝和定制的框架,例如:eggjs等。

 

一開始我就把eggjs 排除在外了,第一因為eggjs,的功能很強大,有很多功能,多到有些根本用不著,從而導致了他會重 不輕量級,第二,eggjs對于我來說是個黑盒,如果有什么問題,我解決起來將會花費很長的時間。(但是有很多地方 我還是借鑒了eggjs的,畢竟 很強大)

 

然后剩下的三種框架,express的使用相對簡單,文檔也比較多,比較全面,所以我就選擇了express(后來還是重構掉了 = =!)

 

然后是前端框架的選型 因為前端框架主流的有很多,ng r v 等等,我站在用的是react和vue, 他們有個優勢就是可以進行前后端同構,一樣的邏輯不用寫兩份,很棒。

 

0?wx_fmt=jpeg

(同構邏輯大概如此吧)

 

由于之前前后端分離的時候,pc上面已經再用vue 進行了重構,所以自然,這次服務端渲染也建立在vue上面 用的是vue ssr (這也為我后面的一個想法埋下了伏筆)

 

首先 我們選擇一個簡單的頁面來做打樣,就用tag頁吧(被神選中的孩子:https://www.bilibili.com/tag/3503159 

 

開發

 

目錄結構

 

- client 【客戶端代碼 同構代碼】

- build 【構建相關】

- PC 【pc 端 vue項目】

- package.json

- config

- config.local.js 【本地開發配置】

- dist 【構建目錄 掛載資源目錄】

- server 【服務端代碼】

- controller 【控制器】

- PC

- route.js

- core [核心代碼庫]

- service [方法庫]

- view [視圖]

- PC [vue 構建后文件]

- tag.html [構建后的模板]

- tag.json [構建后的bundle]

- manifest.json

- apps.js [啟動項]

 

在一開始設計的時候,客戶端代碼和服務端代碼放在同一個git庫里面,client里面是vue的代碼和webpack的打包邏輯。Server里是服務端的代碼,用的是類mvc結構。

 

Client里面的vue的開發代碼,參照的就是vue ssr 官方給的例子來做的,用的是 createBundleRender方法

 

const { createBundleRenderer } = require('vue-server-renderer')
const renderer = createBundleRenderer(serverBundle, {
... })

 

構建配置也是用的推薦的配置(參考:https://ssr.vuejs.org/zh/build-config.html

 

簡單來說,就是提供兩個入口,一個entry-client.js,主要是客戶端的執行入口, 打包出來的是客戶端的引用代碼集合(manifest),另外一個是entry-server.js 打包出來的是服務端運行的邏輯,整合到了bundle.json里面。然后傳給上面的createBundleRender方法就可以了

 

對于server文件夾里面的邏輯就非常簡單了,core里面是啟動項目的一些express的核心代碼 路由注冊什么的邏輯,值得一說的是,這邊的路由,借鑒了eggjs的路由注冊方式,稍微做了一點修改,用的是配置化的方式

 

0?wx_fmt=jpeg

 

配置優于代碼,將訪問地址和對應的controller 做了關聯。

 

這邊還有一個filter 其實就是在執行controller之前 注冊進一個middlewares 優先執行(其實這邊有點局限性,后處理沒法做)。

 

這邊我忽略了壓力測試,壓力測試我后面再說吧。

 

上線部署

 

上線部署用的是docker來部署的,配置是1C 4G的配置,用了兩個實例來運行,(之前的構建鏡像邏輯什么的 就不具體介紹了)

 

上線之后 每天的訪問量大概在100W左右,服務表現挺穩定,期間出現了一個bug,就是 這邊有一個狀態與用戶的登陸狀態有關,所以在服務端請求接口的時候,需要帶上cookie去請求,當時忘記加了 后來加上,發現這個有點弊端比較麻煩。

 

需要在調用vuesssr的時候帶在context 里面,然后asyncData方法里面都要一層一層的傳遞,最后在action 里面拿到,帶給api。

 

這時候 我們再來看下tag頁。

 

0?wx_fmt=jpegssr html

(不錯 把數據都帶上了)

 

重構

 

其實也沒過多久,大概三個月吧,node的版本漲的很快,在7.6版本之后,node 就支持了async/await語法糖,不需要再用yield 和*函數了,那么 無疑 koa 是對于await/async 支持最好的,我們果斷放棄了express,選擇了koa2 進行重構。

 

其實不單單是koa2對于async的支持,另外一個原因在于,我們koa 是洋蔥式的執行方式,這樣就解決了上面我說的,只有controller的前處理,沒有后處理,這樣子我就可以很方便的去執行前后處理。Koa的執行效率也要好于express.

 

上面我說過,選擇vue 對后面重構埋下了一個伏筆就在這里

 

首先,我給項目接入了配置中心,配置中心是干嘛用的呢? 用來記錄腳本的版本號,這樣子我就可以很輕松的通過配置中心來控制前端頁面使用什么版本的腳本。而不用因為改了個腳本的版本號,就需要進行一次服務的重啟更新。

 

然后,我對vue的打包組件進行了魔改,將他打包出來的文件帶上了對應的版本號(版本號為hash值)。

 

這樣子我就可以通過配置中心來控制,到底我需要使用什么版本的vue 構建產物,vue 前端邏輯更新了,我也只需要通過配置中心去分發給服務端,而不需要重啟服務了。一舉兩得。

0?wx_fmt=jpeg配置托管

 

圖中 conf 就是配置中心,我們的server 會與conf進行一個長連接,如果conf中的配置更新了,就會通知到服務,然后服務去拉去新的bundle和manifest 來進行渲染。Ok 很棒

 

全民SSR

 

重構完,那么再接入一個項目試試吧

 

首頁,好,就首頁吧

 

首頁跟tag 頁

 

其實也都差不多,沒有什么特別的地方,唯一不同的就是 量比較大,可能一天有1000W的訪問量左右。那么我們就在CDN上面加上一層緩存,然后在我們服務上面也加上一層緩存。破費(perfect)!~

 

服務端的緩存是通過文件落地來的,就是在第一個請求進來的時候 在渲染完成之后,寫一個文件到本地,然后下次訪問的時候就可以直接用這個丟這個本地文件出去,不用再次渲染了,然后通過過期時間去控制。

 

這里發現了一個問題,就是每次更新 我都會將tag 和index 都進行打包,而我需要的是對項目進行單獨的打包,單獨的更新,能不能通過參數來控制我打包哪個呢,可以啊,首先先把webpack.config.js 重寫,公用部分整合,然后私有的分開寫成多個,通過package.json里面來多配置幾個script就好啦

 

這樣子每次更新項目的時候,我就只需要打包對應的項目就可以了,不會因為項目接入了很多之后,打包和開發時候的熱加載變得很慢很慢。

大云網官方微信售電那點事兒

責任編輯:售電衡衡

免責聲明:本文僅代表作者個人觀點,與本站無關。其原創性以及文中陳述文字和內容未經本站證實,對本文以及其中全部或者部分內容、文字的真實性、完整性、及時性本站不作任何保證或承諾,請讀者僅作參考,并請自行核實相關內容。
我要收藏
個贊
?
主站蜘蛛池模板: 婷婷 色天使| 午夜视频国产| 亚洲欧美日韩精品永久在线| 日本人成年视频在线观看| 日韩一区二区三区在线播放| 色欧美亚洲| 天天干狠狠干| 亚洲a毛片| 午夜看片| 亚洲免费观看在线视频| 欧美日韩一区二区在线观看视频| 手机国产日韩高清免费看片| 人人干狠狠干| 一级毛片看一个| 四虎在线播放免费永久视频| 手机看片三级| 一级风流片a级国产| 小h片在线观看| 日本精品久久久久久久| 青草免费在线观看| 欧美日b视频| 日韩 国产 在线| 一本大道道无香蕉综合在线| 天天影视综合色| 特级a毛片| 亚洲国产精品嫩草影院久久| 视频在线观看h| 欧美日本综合一区二区三区| 天天操天天弄| 午夜伊人网| 小h片在线播放| 亚洲精品中文字幕久久久久久| 四虎永久在线精品| 一级毛片免费在线播放| 日本在线观看a| 欧美亚洲福利| 色综合久久88一加勒比| 欧美日韩国产最新一区二区| 青青干视频| 婷婷狠狠操| 色综网|