B站新版播放頁優(yōu)化總結(jié)報(bào)告

前言

頁面從輸入網(wǎng)址到頁面加載出第一屏的內(nèi)容根穷,我們稱之為首屏數(shù)據(jù)乎芳,從白屏到頁面渲染完成這個(gè)過程是有時(shí)間消耗的,大多數(shù)情況下我們也是壓縮這段時(shí)間來做首屏的性能,時(shí)間越短 頁面呈現(xiàn)的越快 用戶感受到的體驗(yàn)也會(huì)越好劝贸。一般網(wǎng)頁都會(huì)是這樣去做的,但播放頁的“首屏”略有不同栖榨,播放頁是以視頻為主靡挥,頁面的核心是視頻的畫面,所以我們會(huì)重新定義播放頁的“首屏”為視頻的首幀(播放器拉取視頻流到可播放時(shí)間蜈抓,大概在200KB左右)可想而知 這個(gè)定義下的“首屏”參考要比一般網(wǎng)頁的首屏的要嚴(yán)格启绰,不僅僅是視覺上的可見,還有交互上的可播(播放按鈕可以點(diǎn)擊)沟使。

發(fā)個(gè)圖先

截止十月初


image.png

上圖為2018年1月份~10月份的播放頁首幀數(shù)據(jù)優(yōu)化圖(最終指標(biāo)參考藍(lán)色線條)委可。從圖上可以看到有意思的一點(diǎn),在優(yōu)化過程中數(shù)據(jù)忽高忽低腊嗡,但整體是下降趨勢(shì)着倾,最終還是下降到1.5s一下,完成Q3優(yōu)化任務(wù)燕少。這個(gè)也反映了 我們?cè)谧鲰撁鎯?yōu)化的時(shí)候不一定所有的想法都會(huì)是正確的卡者,也是通過不斷的嘗試、試驗(yàn)客们,最終留下可行方案崇决。

網(wǎng)上有很多網(wǎng)頁性能優(yōu)化方案一搜一大堆,一些基礎(chǔ)常用的優(yōu)化我就不在這里贅述了底挫,下面說的是我們覺得收益不錯(cuò)且有針對(duì)性的一些優(yōu)化恒傻。


首屏直出

雖然前后端分離給開發(fā)體驗(yàn)和職責(zé)分離上來了很多的好處,但是在頁面渲染和用戶體驗(yàn)上卻有著天然的劣勢(shì)建邓,模板和數(shù)據(jù)分開處理了盈厘,請(qǐng)求頁面得到的只是一個(gè)HTML容器,還要異步去請(qǐng)求接口涝缝,數(shù)據(jù)成功返回了才能做處理扑庞,硬是吧一個(gè)同步的邏輯變成了異步譬重,最后還要走一遍業(yè)務(wù)邏輯+生成DOM然后插入到容器里渲染,整個(gè)過程會(huì)有長時(shí)間的白屏等待時(shí)間罐氨,體驗(yàn)很差臀规。

為了第一時(shí)間讓頁面上有東西呈現(xiàn)出來,優(yōu)化方案里首屏直出一定是第一要做的栅隐,直接輸出HTML和數(shù)據(jù)(INITIAL_STATE) 讓頁面同步渲染塔嬉,極致的做法可以只輸出首屏需要的DOM和CSS,這個(gè)時(shí)候整個(gè)頁面的骨架等都已經(jīng)出來租悄,用戶體驗(yàn)上省去了等待白屏?xí)r間或旋轉(zhuǎn)不停的Loading圖谨究。

在Node介入之前,播放器頁面的組件也是基于vue來做的泣棋,所以在選型上用的是Node+Vuejs+Memcached(MC)這樣一套組合來實(shí)現(xiàn)的SSR胶哲,完成了首屏直出需求的同時(shí)也實(shí)現(xiàn)了前后端同構(gòu)的目的。也正是有了這些能力潭辈,后面我們很多的優(yōu)化都基于node服務(wù)端來做的鸯屿。(這里主要講頁面優(yōu)化,后面如果有機(jī)會(huì)在新起一篇單獨(dú)說下SSR和緩存之類的)

請(qǐng)求合并 特殊的頁面特殊處理

先看下播放頁的頁面數(shù)據(jù)組成部分(除播放器相關(guān))
接口:稿件信息(view) 把敢、推薦列表(related)寄摆、up主信息(card)、視頻標(biāo)簽(tag)修赞、熱門評(píng)論(comment)

根據(jù)業(yè)務(wù)需要播放頁承擔(dān)了很大的SEO的職責(zé)婶恼,所以上面的接口信息基本是要在模板里面帶出來的(給爬蟲) 那么這時(shí)候就有個(gè)很明顯的問題,多個(gè)接口的情況下而且接口之間可能還有依賴關(guān)系柏副,很難保證這些接口返回的效率勾邦,如果返回的太慢 QPS一定會(huì)很低,所以聚合接口也是我們的首選割择,但又擔(dān)心一個(gè)問題是后端會(huì)幫我們?nèi)ズ喜⒔涌趩? 雖然我們的后端同學(xué)都很好溝通 后面才覺得 對(duì)于公司的重點(diǎn)核心項(xiàng)目來說检痰,做的再多也不為過,因?yàn)橐磺械呐ο峭疲芤娴氖怯脩簟?/strong> 很順利五個(gè)接口合五為一,由于后端走的是內(nèi)網(wǎng)請(qǐng)求且做了一些緩存優(yōu)化公壤,聚合后的接口也是非常的快换可,前端node拿到接口大概控制在20ms以內(nèi)。

跳出框架

vuejs是個(gè)好東西厦幅,提升開發(fā)效率同時(shí)沾鳄、又是面向組件化模塊化開發(fā)、數(shù)據(jù)驅(qū)動(dòng)确憨、生命周期等译荞,給開發(fā)帶來很多的便利瓤的。這么完美的一個(gè)框架,我實(shí)在想不出或不愿意去想它有哪些“劣勢(shì)”吞歼。直到我們?cè)诮o頁面做優(yōu)化的時(shí)候圈膏,你就會(huì)發(fā)現(xiàn)它原先的一些優(yōu)勢(shì)會(huì)在這個(gè)問題(極致優(yōu)化)下可能是一個(gè)劣勢(shì)。

簡單的列一下播放頁中碰到的“劣勢(shì)”:
一篙骡、在做服務(wù)端渲染(ssr)的時(shí)候稽坤,我們?cè)阡秩窘M件的時(shí)候發(fā)現(xiàn)是在太弱了,與常見的服務(wù)端模板(ejs,pug...)簡直不能比 (如圖:壓測)


image.png

我們先對(duì)node單點(diǎn)做了一次壓測糯俗,測試的頁面是真實(shí)的播放頁尿褪。發(fā)現(xiàn)渲染的耗時(shí)是隨著并發(fā)數(shù)量的增長,而增加得湘。如果想使渲染時(shí)間保持在 1秒以內(nèi)杖玲,那么并發(fā)數(shù)的極限是 40個(gè),難道只能無限堆機(jī)器淘正?這肯定不是個(gè)辦法摆马。
40個(gè)開什么玩笑,要知道播放頁每天的訪問請(qǐng)求是億級(jí)的跪帝,有時(shí)候來個(gè)搜索爬蟲今膊,那還不直接癱瘓。(后面當(dāng)然解決了伞剑,在這個(gè)標(biāo)題下就不詳細(xì)說了斑唬。)

二、用了vue那肯定是按照產(chǎn)品模塊一個(gè)個(gè)的開發(fā)組件黎泣,那播放器那塊肯定是一個(gè)單獨(dú)的如VideoPlayer.vue恕刘,頁面接入播放器是以SDK的形式接入 代碼應(yīng)該如下:

<template lang="html">
  <div id="bofqi" ref="bofqi"></div>
</template>
<script>
  export default {
    props: {
      aid: {
        type: Number,
        default: null
      },
      cid: {
        type: Number,
        default: null
      }
    },
    mounted(){
      // 初始化播放器
      new EmbedPlayer("player", `cid=${this.cid}&aid=${this.aid}&autoplay=true`)
    }
  }
</script>

上面是一段偽代碼 初始化播放器需要傳入aid和cid 并且頁面上必須要有一個(gè)id為#bofqi的容器 這樣播放器就會(huì)正確的被實(shí)例化
emmm 看著很正常沒毛病的一段, but!初始化播放器是在vue的mounted生命鉤子里面(也只有這里才能拿到#bofqi的容器) 那意味著要等組件完全渲染完成后才能初始化播放器抒倚『肿牛可怕~ 看圖:
這樣的話,播放器要在很后面才能去初始化托呕,后面還有請(qǐng)求接口含蓉、拉視頻流等畫面出來那就很后面了,花都謝了~

image.png

所以這里需要改進(jìn)優(yōu)化下项郊,最直觀就是盡快初始化播放器最好是和模板頁面同步執(zhí)行馅扣。這里我們嘗試了兩種優(yōu)化方式:
一、把#bofqi容器提出來放到html模板里着降,然后在容器的dom注入一段初始化播放器的代碼差油,事實(shí)上我們有幾個(gè)版本上的優(yōu)化就是這么做的。如下(偽代碼):

<body>
...
<div id="app"></div>
<script src="http://s1.hdslb.com/bfs/static/player/main/video.js"></script>
<div id="bofqi"></div>
<script>new EmbedPlayer("player", `cid=${cid}&aid=${aid}&autoplay=true`)</script>
...
</body>

這里有個(gè)小問題任洞,就是播放器這個(gè)容器的定位蓄喇,因?yàn)槊撾x了了文檔流发侵,是懸浮在整個(gè)頁面之上的,在前面的幾個(gè)版本當(dāng)中播放頁只有寬窄兩個(gè)屏幕的定位 所以兼容上還好妆偏,固定寫死兩個(gè)尺寸下的CSS就好了刃鳄。大大提前了初始化的時(shí)機(jī),上線后效果很好楼眷,基本上SDK下載完成就開始初始化了铲汪,不用等頁面渲染。

image.png

但隨著產(chǎn)品需求的迭代罐柳,要求播放器尺寸自適應(yīng)掌腰,這就麻煩了,很明顯上面這個(gè)方案行不通张吉,再也不能寫死尺寸來適應(yīng)定位了齿梁,那就只能把#bofqi容器再放回vue組件里,這個(gè)問題當(dāng)時(shí)確實(shí)糾結(jié)過一陣肮蛹,不過最后還是和架構(gòu)的同學(xué)一起討論想出了個(gè)黑科技勺择,用過vue的同學(xué)都知道在template里面是無法插入script標(biāo)簽的。但是為了滿足自適應(yīng)只能把容器放回文檔流中伦忠,同時(shí)還需要插入一段初始化播放器的js代碼省核。解決方法如下:

App.vue

<template>
...
  <div class="player-wrap">
    <!-- bofqi容器放回到組件中 -->
    <div id="bofqi"></div>
    <div v-html="innerScript"></div>
  </div>
...
</template>
<script>
export default {
  data() {
    return {
      innerScript: ''
    }
  },
  created() {
      // created 鉤子會(huì)在服務(wù)端執(zhí)行 所以這需要判斷
     if(typeof window === 'undefined') {
        this.innerScript = `<script type="text/javascript">
          new EmbedPlayer("player", `cid=${cid}&aid=${aid}&autoplay=true`)
        <\/script>`
     }
  }
}
</script>

利用created鉤子和v-html的特性在服務(wù)端給template注入一段腳本。目的達(dá)到昆码,而且在客戶端vue對(duì)比的時(shí)候也會(huì)通過驗(yàn)證气忠。 完美解決~
總結(jié):框架是個(gè)好東西,可以解決我們?cè)陂_發(fā)中面臨的大部分問題赋咽,但不是所有問題旧噪。
注意:注入代碼最后script的格式<\/script>

加載和執(zhí)行避讓 控制每一個(gè)請(qǐng)求

任何一個(gè)頁面都是由很多個(gè)模塊組合而成的,這里面可以把所有模塊做個(gè)分類脓匿,挑出核心的淘钟、重要的、一般的陪毡,然后排個(gè)優(yōu)先級(jí)米母,這個(gè)標(biāo)準(zhǔn)的衡量可以站在用戶的角度出發(fā),視頻播放頁的核心當(dāng)然是播放器模塊毡琉,除此之外其他的都可以算是修飾的爱咬,視頻信息、up信息绊起、評(píng)論、tag燎斩、推薦列表等之類的都可以排在后面一個(gè)級(jí)別虱歪。

我們都知道JS是單線程的蜂绎,是一件一件的來處理事情,放在最前面的優(yōu)先處理笋鄙。所以在店里只有一個(gè)服務(wù)員的時(shí)候师枣,排隊(duì)往往是最高效的,那么同理在頁面加載資源和JS執(zhí)行的時(shí)候也可以這樣去給它們排個(gè)隊(duì)萧落。

資源加載上雖然瀏覽器里面可以同時(shí)發(fā)出多個(gè)請(qǐng)求 同步操作践美,但是要考慮到80分位以上偏后的用戶可能他們的電腦性能和帶寬的情況下,請(qǐng)求的并發(fā)可能會(huì)帶來更糟糕的體驗(yàn)找岖,同時(shí)處理多個(gè)任務(wù)陨倡,電腦會(huì)更加卡頓,在這里同步并沒有優(yōu)勢(shì)许布,所以讓資源的加載也來排個(gè)隊(duì)是很有必要的兴革。另外如果JS模塊沒有特意去設(shè)計(jì)的時(shí)候,大多數(shù)js文件在下載下來的瞬間其實(shí)就自執(zhí)行了比如manifest/vendor等蜜唾,在不影響開發(fā)的體驗(yàn)上很難改變js的執(zhí)行時(shí)機(jī)杂曲,基于以上我們想到的是用鉤子函數(shù)去回調(diào),然后把要控制的部分做成串行執(zhí)行袁余,這樣就能控制這個(gè)時(shí)間段的所有資源的下載和執(zhí)行了擎勘。流程圖如下:

image.png

上圖中可以看到,頁面的第一個(gè)請(qǐng)求HTML模板下載 在解析過程中遇到播放器的SDK js資源然后同步下載 下載完成后 立即初始化播放器 播放器內(nèi)開始發(fā)送請(qǐng)求視頻流颖榜,第一幀回來后觸發(fā)鉤子(PlayerMediaLoaded頁面和播放器約定好的) 下載頁面其他資源棚饵,因?yàn)槭欠?wù)端渲染所以這里不用擔(dān)心頁面上什么都沒有,骨架和一些必要的信息都已經(jīng)出來了朱转。為了確保頁面的完整性蟹地,這里做了個(gè)兜底,及時(shí)鉤子沒有生效 4秒后也會(huì)觸發(fā)下一步操作藤为。 這樣一來就把所有不需要第一時(shí)間的請(qǐng)求和執(zhí)行延后處理了怪与,優(yōu)先保證了播放器視頻首幀先出來。

細(xì)節(jié)處理缅疟,為了讓播放器相關(guān)的資源優(yōu)先和真正控制好這個(gè)時(shí)間段內(nèi)的每個(gè)請(qǐng)求分别,應(yīng)盡量避免模板里面帶出來資源加載比如 圖片 小圖標(biāo)之類,除非這些是SEO必需的或者是首屏關(guān)鍵用到的CSS背景圖之類存淫,能沒有就沒有耘斩,否則就不好真正控制到每一個(gè)請(qǐng)求的發(fā)出。

資源腳本延后加載執(zhí)行

這個(gè)優(yōu)化其實(shí)也是控制好每個(gè)資源加載和執(zhí)行的時(shí)機(jī)桅咆,單獨(dú)拎出來說是想舉兩個(gè)例子括授。

第一個(gè),在做優(yōu)化的過程中,也有其他的任務(wù)混進(jìn)來荚虚,由于我司的PV上報(bào)收集是基于前端的JS腳本來做的上報(bào)薛夜,有一段時(shí)間PV的數(shù)據(jù)波動(dòng)較大,懷疑是上報(bào)腳本出了什么問題版述,所以就在線上埋了個(gè)204請(qǐng)求來校驗(yàn)和上報(bào)腳本PV的差值來對(duì)比梯澜,當(dāng)時(shí)想一個(gè)204請(qǐng)求是很快的而且不需要返回,結(jié)果上了第二天看數(shù)據(jù)渴析,整個(gè)80分位播放頁首屏數(shù)據(jù)增加了近100ms晚伙,但50分位基本上沒什么變化,204下了數(shù)據(jù)就回復(fù)了俭茧。這個(gè)結(jié)果告訴我們?cè)?0分位+的段位上咆疗,任何風(fēng)吹草動(dòng)對(duì)首幀數(shù)據(jù)的影響來說都有可能被放大

另外一個(gè),由于播放頁里有些其他模塊(廣告恢恼、評(píng)論等)需要用到j(luò)Query,所以一直沒有去掉民傻,默認(rèn)情況下也是放在head標(biāo)簽里面比較靠前的位子,感覺這個(gè)可以把它后置到首屏完成以后再加載场斑,所以我們花了一些時(shí)間改造漓踢,關(guān)鍵模塊不在依賴JQ,做了后置處理漏隐,第二天的數(shù)據(jù)大概下降了70ms左右喧半。

文件體積優(yōu)化

減少文件體積是一個(gè)通用的優(yōu)化,體積的大小直接影響到網(wǎng)絡(luò)下載的時(shí)長青责,減少控制文件大小的方式也有很多挺据,比如服務(wù)端常用的文件壓縮(gzip、br...)脖隶,前端去不必要的依賴扁耐、框架等,很多JS框架也是盡量精簡來獲得市場優(yōu)勢(shì)产阱,文件體積的影響對(duì)于PC上的影響還算可以婉称,如果是H5那是必須嚴(yán)格控制的,網(wǎng)絡(luò)環(huán)境的差異也直接反應(yīng)到頁面加載速度的體驗(yàn)构蹬,同樣在極限優(yōu)化的情況下王暗,不管是H5還是PC那肯定是盡量精簡。

最初的播放器js的sdk核心庫大概在1M左右庄敛,里面不僅是視頻初始化還有彈幕俗壹、高級(jí)彈幕、解碼藻烤、各種設(shè)置等等绷雏,其實(shí)完全沒必要头滔,后來播放器組的同學(xué)也給播放器做優(yōu)先級(jí)劃分,把功能拆開涎显,做了很多工作大幅度精簡核心庫最后優(yōu)化至200K左右拙毫,體積小了好多倍,80分位速度提升明顯棺禾。

還有HTML模板,這是第一個(gè)請(qǐng)求峭跳,后面發(fā)生所有的資源請(qǐng)求都基于它膘婶,所以它的體積也尤為重要,所以在這個(gè)里面我們除了該有的骨架蛀醉、數(shù)據(jù)和SEO需要的部分盡量精簡悬襟,包括把頂導(dǎo)做成后置SDK引入的方式,也是為了減少體積拯刁,SSR的時(shí)候頁面上會(huì)輸出大量的數(shù)據(jù)(INITIAL_STATE)脊岳,其實(shí)有些字段用不上,所以在服務(wù)端渲染的時(shí)候要清洗一下垛玻,能刪的地方都刪了割捅,最終從幾十K 優(yōu)化到 十幾K。

前置playurl(Node)

正如前面所說帚桩,播放頁是基于node服務(wù)做的ssr亿驾,node這一層也是我們前端負(fù)責(zé)的,所以可以很好的利用這個(gè)點(diǎn)去做一些事情账嚎。先看下播放器從初始化到出現(xiàn)首幀有哪些關(guān)鍵步驟莫瞬。如下圖:


image.png

從圖上可以看到,把一個(gè)前端請(qǐng)求的接口后置到后端去處理郭蕉,這樣播放器去請(qǐng)求視頻流的時(shí)候直接從模板里拿到了地址疼邀,不用再去發(fā)異步。一個(gè)前端異步請(qǐng)求的接口一般情況在幾十到上百毫秒召锈,放到后端去處理走的還是內(nèi)網(wǎng)接口(后端對(duì)內(nèi)網(wǎng)接口返回時(shí)長控制在20ms以內(nèi)) 又更快了旁振。

這個(gè)優(yōu)化有個(gè)注意的點(diǎn),因?yàn)椴シ彭撌莝sr同構(gòu)的方案烟勋,在頁面降級(jí)的情況下服務(wù)端是不會(huì)輸出數(shù)據(jù)的规求,頁面會(huì)走客戶端渲染,這時(shí)候playurl就拿不到了卵惦,所以還是會(huì)和播放器本身配合的去做阻肿,播放器之前的邏輯還是不能去掉,需要做個(gè)判斷沮尿,如果頁面上能獲取到視頻流的地址就直接用丛塌,否則自己發(fā)個(gè)請(qǐng)求去獲取较解。

推薦列表預(yù)取playurl

當(dāng)你能提前知道用戶在頁面上的瀏覽行為的時(shí)候,其實(shí)你也可也以做點(diǎn)事情赴邻,比如播放頁的右側(cè)視頻推薦列表就是個(gè)很好的場景印衔。通過數(shù)據(jù)發(fā)現(xiàn)播放頁內(nèi)部跳轉(zhuǎn)的點(diǎn)擊流量很大,大部分來自于推薦列表位 如圖:

image.png

上圖為播放頁推薦列表的點(diǎn)擊熱力圖姥敛,從圖上可以清晰的看到靠在前面的視頻卡片點(diǎn)擊量很大(和它在第一屏有直接關(guān)系) 奸焙。利用這個(gè)點(diǎn) 我們可以給這些點(diǎn)擊量大的卡片去預(yù)取視頻地址,這里我們是取了前4位的地址彤敛。
細(xì)節(jié)點(diǎn):在預(yù)期地址發(fā)請(qǐng)求的時(shí)候需要判斷下當(dāng)前視頻和頁面的狀態(tài)与帆,最佳時(shí)間是頁面空閑狀態(tài)下,避免和其他任務(wù)并行墨榄,影響其他正常模塊的性能玄糟。

SPA重載優(yōu)化

與之前的版本(17年之前)相比,新版播放頁已經(jīng)是一個(gè)單頁應(yīng)用了袄秩,點(diǎn)擊視頻推薦列表阵翎,所有模塊局部更新,不用跳新窗口再走一套了之剧,最重要的是播放器不用重新初始化和資源不用重新加載了郭卫。這樣一來整個(gè)頁面就能省下很多前置的耗時(shí)。

雖然說頁面已經(jīng)SPA了猪狈,但是在不注意的情況下也會(huì)有一些性能上的問題箱沦,如圖:


image.png

上圖分為兩個(gè)部分,優(yōu)化前和優(yōu)化后雇庙,在優(yōu)化前 每次用戶點(diǎn)擊推薦列表后路由先切換谓形,因?yàn)轫撁嫔系哪K的更新基本上都是基于watch路由上aid來做改變的,再由aid去請(qǐng)求播放頁信息接口疆前,獲取到對(duì)應(yīng)的cid 然后傳給播放器重載視頻寒跳。這里會(huì)有個(gè)問題每次都會(huì)消耗一個(gè)接口請(qǐng)求的時(shí)間來獲取播放器重載必要的aid和cid。其實(shí)我們?cè)谕扑]列表里面是能直接獲取到視頻的aid和cid的竹椒。

我們故技重施優(yōu)化了一波童太。直接把a(bǔ)id、cid傳到播放器 先實(shí)現(xiàn)重載胸完,在首幀回來之前我們頁面上所有需要更新模塊不觸發(fā)更新书释,等待播放器鉤子通知再去做各自組件的更新。所以組件里之前的watch aid的方法都變成了事件的方式來通知赊窥。

這里主要還是用到了上面說的資源加載和執(zhí)行的避讓以及一些邏輯處理上的優(yōu)化爆惧,最終給重載事件帶來了100多毫秒的收益。

靜態(tài)資源Prefetch

預(yù)加載靜態(tài)資源已經(jīng)是優(yōu)化中常見的一種優(yōu)化手段了锨能,通過流量較大的入口頁面給需要優(yōu)化的頁面帶資源緩存扯再,這樣在用戶訪問播放頁的時(shí)候就不需要重新請(qǐng)求資源而是從本地獲取(from disk cache)芍耘,由于prefetch的優(yōu)先級(jí)比較低,(network -> priority: Lowest),所以不用太擔(dān)心當(dāng)前頁面的加載帶來的性能問題熄阻。也可以通過多個(gè)頁面一起來做斋竞,首頁、搜索秃殉、空間這些頁面都是PC上的大流量頁面而且有大量的視頻開片往播放頁跳轉(zhuǎn)坝初,所以非常適合。代碼:

<link rel="prefetch" as="script" >

之前查過一段播放頁的數(shù)據(jù)钾军,結(jié)果顯示帶有這些頁面reffer的播放頁要比其他的請(qǐng)求快200ms左右脖卖。

階段總結(jié)

在技術(shù)沒有本質(zhì)變化的情況下,優(yōu)化并不是什么特別高深的技術(shù)巧颈,大多數(shù)情況都是你愿不愿意去想且去做的事情,有很多非常細(xì)節(jié)的地方可以去做優(yōu)化袖扛,有時(shí)候我們猶豫不決砸泛,經(jīng)常會(huì)感覺收益不確定、或者是這個(gè)優(yōu)化可能會(huì)對(duì)現(xiàn)有代碼的整潔性造成很大破壞蛆封,后面不好維護(hù)等等唇礁,不太想去做。其實(shí)這個(gè)時(shí)候可以通過實(shí)驗(yàn)的方式來驗(yàn)證惨篱,最終你會(huì)得到一個(gè)收益值和付出成本衡量來決定是否需要采用這個(gè)方案盏筐。從本質(zhì)上講作為一個(gè)前端開發(fā) 凡是對(duì)頁面性能有提升、對(duì)用戶體驗(yàn)優(yōu)化的事砸讳,我們應(yīng)該盡全力去做琢融,特別是這種流量巨大的頁面,可能我們優(yōu)化了一點(diǎn)點(diǎn)簿寂,但收益是千千萬漾抬。在一些重要的頁面上,代碼的維護(hù)性常遂、擴(kuò)展性都不是我們首要考慮的纳令,我們?cè)诤醯闹刂兄貞?yīng)該是頁面的性能和用戶的體驗(yàn)。

先分享這么多 完結(jié)撒花~

嗶哩嗶哩 (゜-゜)つロ 干杯~ 2233

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末克胳,一起剝皮案震驚了整個(gè)濱河市平绩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌漠另,老刑警劉巖捏雌,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異酗钞,居然都是意外死亡腹忽,警方通過查閱死者的電腦和手機(jī)来累,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來窘奏,“玉大人嘹锁,你說我怎么就攤上這事∽殴” “怎么了领猾?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長骇扇。 經(jīng)常有香客問我摔竿,道長,這世上最難降的妖魔是什么少孝? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任继低,我火速辦了婚禮,結(jié)果婚禮上稍走,老公的妹妹穿的比我還像新娘袁翁。我一直安慰自己,他們只是感情好婿脸,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布粱胜。 她就那樣靜靜地躺著,像睡著了一般狐树。 火紅的嫁衣襯著肌膚如雪焙压。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天抑钟,我揣著相機(jī)與錄音涯曲,去河邊找鬼。 笑死在塔,一個(gè)胖子當(dāng)著我的面吹牛掀抹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播心俗,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼傲武,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了城榛?” 一聲冷哼從身側(cè)響起揪利,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎狠持,沒想到半個(gè)月后疟位,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喘垂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年甜刻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绍撞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡得院,死狀恐怖傻铣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情祥绞,我是刑警寧澤非洲,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蜕径,受9級(jí)特大地震影響两踏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜兜喻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一梦染、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧朴皆,春花似錦弓坞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戚扳。三九已至忧便,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間帽借,已是汗流浹背珠增。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砍艾,地道東北人蒂教。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像脆荷,于是被迫代替她去往敵國和親凝垛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1蜓谋、通過CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,981評(píng)論 3 119
  • 班主任對(duì)我們?nèi)?2個(gè)學(xué)員分成了五個(gè)組梦皮,要求每個(gè)組在半個(gè)小時(shí)之內(nèi)設(shè)計(jì)出組徽、組名桃焕,并要求各組成員到臺(tái)上進(jìn)行設(shè)計(jì)展示剑肯。
    甜蜜荔枝閱讀 466評(píng)論 1 2
  • spring MVC 中使用 MessageConverter 在遇到 @RequestBody 時(shí),將請(qǐng)求體中的...
    hyrijk閱讀 10,365評(píng)論 1 5
  • 年輕的時(shí)候观堂,我是個(gè)理想主義者让网。每天抬頭看著自己的生活呀忧,整日坐在電腦前,看著眼前這不屬于自已的方寸之地溃睹,迷茫...
    行者琴閱讀 291評(píng)論 0 0