前端極限性能優(yōu)化合集
性能優(yōu)化是老生常談了悲幅,從雅虎的N條軍規(guī),前端各種優(yōu)化準(zhǔn)則,到2010年Google IO上Steven提出的高性能建站指南,都在告訴開(kāi)發(fā)者聊品,一個(gè)站點(diǎn)的性能非常重要,如何在有限的帶寬條件下几苍,達(dá)到極限的訪問(wèn)性能翻屈,如何讓訪問(wèn)者,無(wú)論是從響應(yīng)速度妻坝,視覺(jué)感官伸眶,操作流暢度都達(dá)到最佳體驗(yàn),是目前Web技術(shù)上的一個(gè)至關(guān)重要的挑戰(zhàn).
相較于前端,后端的性能優(yōu)化手段非常多刽宪。這里前端的放在后面討論赚抡,先從Back-End開(kāi)始.
1.使用Nginx做轉(zhuǎn)發(fā)
Nginx作為一個(gè)開(kāi)源的高性能負(fù)載均衡的HTTP和反向代理服務(wù)器, 是開(kāi)源界的業(yè)界標(biāo)桿之作纠屋, 一般來(lái)說(shuō)涂臣,通過(guò)后臺(tái)程序啟動(dòng)的服務(wù), 通過(guò)Nginx作轉(zhuǎn)發(fā)可以輕松的做到:
·負(fù)載均衡
·限制對(duì)于資源路徑的訪問(wèn)
·對(duì)靜態(tài)資源自動(dòng)開(kāi)啟Gzip壓縮
·配合分布式服務(wù)器架構(gòu)
2.Redis, Varnish做緩存
使用緩存中間層可以極大程度上的減少對(duì)于數(shù)據(jù)庫(kù)的重復(fù)讀寫操作次數(shù)售担,減小服務(wù)器的壓力赁遗。極限配置過(guò)的Varnish緩存層面可以自動(dòng)檢測(cè)到已經(jīng)修改的文件,沒(méi)有改變的文件則告訴客戶端使用緩存族铆,而改變過(guò)的文件會(huì)自動(dòng)返回新的文件岩四,這種技術(shù)詳情請(qǐng)見(jiàn)Github IO站點(diǎn),非常適合靜態(tài)資源
·減少對(duì)于數(shù)據(jù)庫(kù)層面的讀寫操作
·緩存靜態(tài)數(shù)據(jù)哥攘,配置剖煌,資源
·并發(fā)量大時(shí),減小服務(wù)器壓力
3.字段加密,字段壓縮
從后端的開(kāi)發(fā)角度來(lái)說(shuō)逝淹,直接讀寫數(shù)據(jù)庫(kù)之后耕姊,原樣返回?cái)?shù)據(jù)庫(kù)對(duì)應(yīng)字段作為響應(yīng)數(shù)據(jù)是一種極其懶惰愚蠢的行為,這樣的做法不單是告訴攻擊者數(shù)據(jù)庫(kù)的字段就是這樣的栅葡,更是讓有經(jīng)驗(yàn)的人容易的揣測(cè)到數(shù)據(jù)庫(kù)的表結(jié)構(gòu)茉兰。所以字段的加密,字段的壓縮欣簇,就變得極其的重要.
字段的加密,壓縮意思是指规脸,從數(shù)據(jù)庫(kù)中拿出的對(duì)應(yīng)數(shù)據(jù)自動(dòng)轉(zhuǎn)化成非邏輯形態(tài)數(shù)據(jù)
id: 201293???????????????????a : 201293
name: "Sam"??????-> ?????????z : 88
score: 88????????????????????n : "U2Ft"
配合前端的filter的層面坯约,將數(shù)據(jù)轉(zhuǎn)化成視圖對(duì)應(yīng)所需要的平行話格式
4.靜態(tài)資源分離,發(fā)布自動(dòng)化
運(yùn)維當(dāng)然是必不可少的莫鸭,將靜態(tài)資源自動(dòng)抽離闹丐,通過(guò)Python,或者Shell腳本自動(dòng)化將靜態(tài)資源分布到CDN服務(wù)器被因,替換對(duì)應(yīng)的文本等操作卿拴, 內(nèi)存監(jiān)控等一系列的task,當(dāng)然氏身,中小公司很少有這么專業(yè)的干活巍棱。
1.jsCSS極簡(jiǎn)化,減少文件大小
從帶寬能力的角度上來(lái)說(shuō)惑畴,一個(gè)站點(diǎn)的訪問(wèn)速度蛋欣,最直觀的其實(shí)是從文件的大小入手,而不是執(zhí)行效率如贷。當(dāng)并發(fā)量變得極其龐大時(shí)(Google首頁(yè)陷虎,百度首頁(yè)),減少css和js的文件大小就變得相當(dāng)?shù)闹匾芨ぃ僭O(shè)每秒一個(gè)訪問(wèn)者每次訪問(wèn)該站點(diǎn)可以少加載2KB大小的資源的加載尚猿, 那么100個(gè)訪問(wèn)者會(huì)怎么樣?1000個(gè)訪問(wèn)者楣富,1000萬(wàn)個(gè)訪問(wèn)者呢凿掂?這就是為什么 騰訊QQ空間項(xiàng)目組,減少CSS JS文件大小10KB就有豐厚的年終獎(jiǎng)的原因了.
至于減少字節(jié)的各種奇技淫巧我就不展示那么詳細(xì)了纹蝴,舉個(gè)幾個(gè)例子
Css
// 減少1字節(jié)
font-weight: bold ?-> ?font-weight:700
// 組合寫法// 減少n字節(jié)
margin-top:**
margin-left: **
margin-right: **
margin-bottom: **
-> ?margin : ** ** ** **;
var?str = "abcd"
if(str.indexOf("d") === -1)
...
// 使用取反運(yùn)算// 減少3字節(jié)if(!~str.indexOf("d"))
...
2.真正意義上將樣式庄萎,配置邏輯embed到頁(yè)面中,從而減少http請(qǐng)求
CSS放在頭部加載塘安,JS放在尾部加載這種調(diào)調(diào)聽(tīng)的太多了糠涛,人云亦云,123456789兼犯,跟著一起喊忍捡,實(shí)際情況并不是這樣,現(xiàn)代瀏覽器越來(lái)越快切黔,多線程并行加載CSS的能力得到了巨幅提升砸脊,很多人沒(méi)有真正去理解Steven在2010年Google IO大會(huì)上論述的:“減少http請(qǐng)求”
通過(guò)觀察Google的首頁(yè)我們發(fā)現(xiàn),居然沒(méi)有CSS請(qǐng)求纬霞?查看頁(yè)面源碼時(shí)發(fā)現(xiàn)脓规,Google將樣式embed到了頁(yè)面中一起加載過(guò)來(lái) 。
這樣的做法有4個(gè)好處
·瀏覽器預(yù)先加載CSS不會(huì)執(zhí)行并行加載CSS文件险领,減少http請(qǐng)求
·隨頁(yè)面享受Gzip壓縮侨舆,并且隨時(shí)可以解決緩存問(wèn)題
·?embed在頁(yè)面中秒紧,瀏覽器預(yù)解析,不會(huì)造成并行下載css同時(shí)解析html時(shí)出現(xiàn)的回流或者重繪等問(wèn)題
·讓觀察者無(wú)法輕松調(diào)試挨下,定位熔恢,甚至修改。
3.圖片的壓縮,靜態(tài)資源CDN化
主要是將圖片臭笆,CSS叙淌,JS等資源,CDN化愁铺,從而很大程度上減少主服務(wù)器的壓力.圖片壓縮鹰霍,WebP格式可以說(shuō)是Web圖片格式的未來(lái)趨勢(shì),壓縮算法真心屌,不過(guò)只有Chrome和Opera支持的最好茵乱, 其他瀏覽器都不太Care茂洒,希望Chrome趕緊一統(tǒng)江湖吧.
一般的JPG其實(shí)只需要70%的質(zhì)量就差不多了.但是,它仍然不是最理想的狀態(tài)瓶竭,圖片的除了壓縮質(zhì)量以外督勺,還需要移除掉圖片的其他信息,壓縮最好是在后端完成斤贰,而不是用前端的Canvas(需要考慮Base64碼比原圖片要大的問(wèn)題)
4.視圖層使用js模版智哀,或者完整的View框架(React),以Lazyload的形式分塊加載
看看淘寶和天貓首頁(yè)是怎么做的就知道了荧恍,將視圖模版化瓷叫,訪問(wèn)者滾動(dòng)時(shí)才加載對(duì)應(yīng)的數(shù)據(jù),從而很大程度上減少一次性數(shù)據(jù)的傳輸量.
5. CSS JS選擇器ID化
這一點(diǎn)可能很多人不相信送巡,而一段時(shí)間的總結(jié)和實(shí)踐后我發(fā)現(xiàn)摹菠,ID選擇器是最快的,主業(yè)務(wù)邏輯的元素綁定ID是一種非常不錯(cuò)的做法授艰,而給ID寫樣式辨嗽,也不是一種糟糕的實(shí)踐,而可以一定程度上加快解析淮腾,渲染的速度糟需。詳情可以參見(jiàn)Google首頁(yè)的樣式,非常多的ID寫法.
YouTube作為全球最大的視頻網(wǎng)站谷朝,每天都承載了數(shù)億級(jí)別的PV洲押,自然YouTube的前端必須要做到極致,為了加快渲染速度圆凰,除了Embed CSS和JS之外杈帐,CSS大部分使用了ID的寫法,更多細(xì)節(jié)請(qǐng)科學(xué)上網(wǎng):
6. PC站點(diǎn)和移動(dòng)端完全分開(kāi),拒絕響應(yīng)式
2011年前后掀起的響應(yīng)式站點(diǎn)浪潮,其中最著名的CSS框架相信大家絕對(duì)不會(huì)陌生挑童,BootStrap,也是Github上少有的可以突破10萬(wàn)Star的項(xiàng)目累铅, 一個(gè)站點(diǎn),多屏幕站叼,多設(shè)備適配娃兽,通過(guò)編寫不同的Media Query CSS就可以做到,但是從性能角度來(lái)講確是一個(gè)非常糟糕的實(shí)踐.所以基本上沒(méi)有大公司搞響應(yīng)式(國(guó)內(nèi))
其缺點(diǎn)如下:
·多余的HTML結(jié)構(gòu)和CSS樣式尽楔,在media query下不同屏幕要對(duì)css進(jìn)行重寫或者增強(qiáng)
·同樣的圖片可能需要兩套(小屏幕投储,大屏幕)
·?Sprite IMG無(wú)法得到充分的利用,Background Size阔馋,Position微小像素差等問(wèn)題
·其實(shí)根本沒(méi)有人會(huì)閑的蛋疼的去不停的縮放屏幕
·兩套事件綁定(Click玛荞,Tap) 偷懶的話只用Click事件,導(dǎo)致點(diǎn)擊觸控方面體驗(yàn)極差
·資源文件體積過(guò)大呕寝,不利于優(yōu)化,手機(jī)加載解析速度慢
7.活用LocalStorage,存儲(chǔ)用戶狀態(tài),組件狀態(tài)勋眯,而非JS或者模板
之前看到有文章說(shuō)“利用LocalStorage存儲(chǔ)JS”, 當(dāng)然這種做法是錯(cuò)誤的壁涎,極其不靠譜凡恍,問(wèn)題就在于把JS存在LocalStorage中很容易遭到XSS攻擊志秃,另外怔球,存儲(chǔ)模板也不靠譜,模板最好是直接輸出在頁(yè)面后直接進(jìn)行編譯浮还,不要存儲(chǔ)在LocalStorage中竟坛,會(huì)涉及到模板緩存,占用空間钧舌, 暴露視圖邏輯等問(wèn)題.同時(shí)担汤,存儲(chǔ)時(shí)最好進(jìn)行加密(關(guān)鍵字段)
經(jīng)過(guò)長(zhǎng)時(shí)間的實(shí)踐,LocalStorage最適合存儲(chǔ)用戶狀態(tài)洼冻, 組件狀態(tài)(和業(yè)務(wù)邏輯崭歧,數(shù)據(jù)邏輯無(wú)半毛錢關(guān)系的狀態(tài)),等不涉及到業(yè)務(wù)數(shù)據(jù)存儲(chǔ)的字段 比如:
·用戶的搜索記錄
·用戶的名稱撞牢,ID率碾,上一次訪問(wèn)的URL地址
·組件的使用記錄(狀態(tài))
·用戶的UA
·后臺(tái)輸出的固定數(shù)據(jù),需要在請(qǐng)求時(shí)帶回去的字段
8.給視圖根元素定義固定的Height和Width
一直以來(lái)屋彪,重繪和回流都是前端很討厭的問(wèn)題所宰,很多網(wǎng)站,加載之后畜挥,布局樣式會(huì)出現(xiàn)“抖” 一下的情況,甚至整個(gè)頁(yè)面“閃一下“,”跳一下” 躯泰? 其實(shí)都是出現(xiàn)了嚴(yán)重的重繪谭羔,為了防止出現(xiàn)這種情況,我們給每一個(gè)可以預(yù)測(cè)板式的元素都定義固定的高度和寬度麦向,保證內(nèi)部的元素在懶加載(LazyLoad)或者直接渲染時(shí),不會(huì)造成視圖根元素的抖動(dòng)口糕,從而間接的影響到周圍元素的排版,詳情你可以參考一下天貓首頁(yè)樣式
9. DNS網(wǎng)絡(luò)解析加速,并且利用好站長(zhǎng)工具
此優(yōu)化屬于網(wǎng)絡(luò)層面磕蛇,當(dāng)然也是值得一提的景描,具體這里不闡述,提一下.
利用好站長(zhǎng)工具秀撇,這里不是指提高訪問(wèn)量或者SEO超棺。