淺談web前端優化

72.png

開篇

優化網站是一個系統性和持續性的過程。很多人認爲優化網站的性能只需要合併圖片啦,減小HTTP請求啦,部署CDN啦就行,實際上這都是見木不見林的做法。以上的做法經常會被面試者提起,在被問到自己在網頁優化的經驗和技巧時,大多數人都是例舉出以上的這些方法。無可否認,上面這方法都可以在某種程度上提高網頁的加載性能,然而僅僅知道幾種方法,顯然還遠遠不夠。就好像我們學習一門新語言,如果只是知道的零散的一些單詞,我們是無法完整地、自由地表達自己的思想的。我們需要的是方法論,用系統性的思維來解決系統性的問題。所以,本篇博文不會帶你去細究哪一種方法會帶給你優化性能,這些細節在文中提供的鏈接中的博文中都有非常詳盡的介紹,本篇博文的重點是告訴你如何自頂而下地解決這類問題。

知識儲備

追本溯源

一般來說,我們認爲網站性能大概分爲兩種:加載性能交互性能。加載時間的長短以及交互的反饋是否及時能反應到界面上會提供給用戶直接的預期感受。

加載瓶頸

加載性能指的是指用戶從輸入URL或者進入你的網站一直到可以與用戶可以持續進行交互的這段時間。這段時間決定了用戶的對網頁的整體評價。通常,越快的網頁加載性能,會提升用戶的留存概率,而較長的白屏時間讓用戶等待,會降低用戶的留存率,畢竟大家都這麼忙,很少人會對着白色的屏幕發呆十幾秒鐘。造成網頁加載的性能有很多:網絡速度,硬件性能,代碼的執行效率,資源的大小等都會影響我們看到完整界面的時間。你需要清晰地知道瀏覽器是怎麼樣呈現一張網頁的,然後在順着這條線去發現問題。

交互瓶頸

交互性能指的是,用戶在網頁可以完全交互後,在交互的過程當中,界面的流暢程度。交互性能一般與渲染幀數以及界面對用戶的反饋有關係。人的眼睛能看到60幀(FPS)的動畫爲流暢,因此,如果界面的持續變化維持在60FPS會給用戶的感覺提供很好的反饋。其次是對輸入行爲的時間響應,如果事件延遲執行100~300ms用戶就會感覺到響應延遲,從而給帶來流暢性不佳的體驗。

瀏覽器

瀏覽器是Web應用的主要載體,自誕生以來它已經走過了30多個春秋了,從最初的只渲染簡單的HTML標籤,到現在的萬花筒式的繽紛世界,瀏覽器的進化速度已經超過我們這個時代了。前端工程師的主要戰場就是瀏覽器,因此對瀏覽器的足夠認知有助於我們開發出更好的應用和產品。瀏覽器的技術底層細節非常複雜,如果要細細研究會花費不少的時間,然而對其渲染流程的有一些基礎的瞭解確是必不可少的。例如:瀏覽器是如何渲染出網頁的,以及它是怎麼執行腳本的,還有它在整個程序運行中的結構是如何的。我在這篇文章中大致的分析了在地址欄中輸入URL到網頁展示的全過程,你可以查看幫助你更好了解瀏覽器原理。自從08年chrome誕生以來,瀏覽器就不再是一個黑盒子,google對技術開源以及持續的改進,使得我們現在用的瀏覽器已經完全可以媲美一個操作系統了。在這篇文章中更加詳細的介紹了瀏覽器的細節,瞭解他們有助於你開發自己的應用,從底層開始構建自己的知識體系。
另外利用好瀏覽器提供給我們的工具能夠極大地提高我們找到性能瓶頸的速度。google提供了非常專業的瀏覽器開發工具dev tools,非常契合我們開發人員的開發習慣。通過Performance或者Lighthouse等面板,我們可以找到一些在Lab環境下的優化點。總之,瀏覽器不管作爲終端或者開發端,都是前端工程師必須深入的一個知識領域。

HTTP

HTTP協議是互聯網的基石,我們看到的所有的資源,都是通過tcp/ip協議從遠程的另外一臺機器上交換過來的。事實上,http在首頁性能優化上佔據了很大一部分。在日常開發中,我們往往遇到的網絡或者服務問題會比其他瀏覽器相關的問題要多。在瀏覽器飛速發展的時代,基於tcp的http協議在幾十年的進化過程中也不斷的完善自身,例如http1.x,http2以及未來的http3都時時刻刻在改進着我們交換信息的方式。http的系統知識非常多,也非常廣,你需要平時不斷的積累,觀察,到底你的網站在網絡這塊還有多少的改進空間。具體的問題例如:http的重傳機制,http的快速恢復,滑動窗口等。另外,瞭解和部署以及觀察http緩存在前端開發來說幾乎可以說是一個硬技能。我在這篇文章中較爲深入的探討了http緩存。與瀏覽器不一樣,http的差異體現在服務器的部署和網絡傳輸上面,較瀏覽器更少的依賴於客戶端設備性能,因此在針對http優化是需要考慮的角度與瀏覽器不同。
最後,雖然我們的信息在光纖中傳播的速度非常快,但是對於日益增長的需求來上來說,還不夠快。考慮到現實世界上兩地的距離以及物理條件,我們可以確定,在http在物理層面很多地方還存在優化的可能。部署CDN是一個一舉多得的舉措,當然還有其他種種的措施。瞭解http將對你進行網站優化提供一個全面的知識體系的指導。這篇專欄對http進行了非常詳盡的講解,我推薦你去把它看完。

性能指標

雖然性能體驗有部分是主觀上,但是對於普遍的體驗來說,我們還是可以通過一些客觀的標準來對其進行衡量和評估。Google團隊在一直在標準的制定上扮演着重要的角色。爲了幫助開發者評估自己的網頁的性能,他們提出了一些列的指標,這些指標大多數都建立在用戶的視覺的反饋上,從白屏到可完整地持續性的交互,包含了複雜的算法邏輯,爲的就是儘可能的反映網站的的性能,你可以通過他們提供的工具來檢測自己的網頁性能。另外我在這篇博客中比較全面蒐羅了這些指標的介紹,以及我對他們優劣的一些看法。最後要確定的是,如果我們的性能已經到了被感官感受到“慢”的時候,我們網頁的內在問題其實就已經非常嚴重了。通過這些指標,我們可以更加細微客觀的知道自己應用的短處。

工具

古人云,工欲善其事必先利其器。開發工具,測試工具,調試工具以及監控工具在前端的領域都有是不可不用的。時至今日,我們早已經不是使用IE6用alert來調試開發的時代了,當年的設計軟件Dreamweaver也被大部分程序員淘汰了。靠着豐富開發的社區生態,我們可以站在巨人的肩膀上,搭建自己的工具鏈條。我在下面列出幾種在開發中常見的性能調試工具,來幫助定位網頁的性能:

1.Dev tools

相信任何做前端的工程師都離不開這個工具,它是集成到谷歌瀏覽器中的工具面板(在其他的瀏覽器中也有相關的工具,例如firefox的firebug等。我們對他們的統稱爲dev tools),提供給開發者專業全面的信息。其中功能非常豐富,你甚至可以在裏面發現一些彩蛋。我在這個系列中比較全面地介紹了chrome的開發者工具一些用法,你感興趣的話可以去看看。

這篇文章寫成時間較早,相對於Chrome瀏覽器如今兩個禮拜一個版本的速度來說顯然有些落伍了。

2.Lighthouse

Lighthouse是一種基於web的網頁測試性能的系統,你只需要在輸入框中輸入測試網站的地址,它就會給出我們之前提到過的各種指標。當然,這些指標只是基於特定的環境(網絡,機器,瀏覽器)下進行評估的,不具備普遍性。Lighthouse集成在chrome瀏覽器中,你可以很方便地使用它對網頁進行整體的性能評估。

3.Fiddler & Charles & Wirmsharp

FiddlerCharles分別是一款在window上和ios上的抓包工具。他們的功能都是非常豐富,提供了抓包,替換,監控請求的諸多功能。相對於前兩者來說,wirmsharp在更深層次的信息上展示更加詳細。但對於我們日常開發來說,選擇前兩者就足夠了。抓包工具無論在開發還是在測試的過程中都非常有用,它不僅可以快速地定位問題的根源,而且在線上調試上有很好的輔助作用。

4.WebpageTest

Lighthouse一樣,webpagetest也是基於網頁的性能測試系統,同樣是輸入測試網站地址,它會給出結果,只不過它側重http的方面的,而且在網絡細度上具備豐富的可調節性,例如,可以測試某個地方的網頁加載速度,可以在地圖上選擇即可。對CDN的應用的效果測試十分重要。

5.PageSpeed Insights

PageSpeed Insight也是google的一些性能服務報告。你只需要提供一個原始的url鏈接,它會幫助你分析你的網頁性能。PSI與之前的工具不一樣的是,它是基於谷歌爬蟲的歷史數據的,並非時時的對當前這次訪問做各項性能數據統計。這對我們的性能評估工作有非常大的作用。PSI的缺點就是並非所有的網頁都被google爬蟲爬取,因此,在針對特定的應用來說,它的作用就顯得比較小了。

6.Chrome User Experience Report

CUER是一項google的性能檢測計劃,通過引入google提供的腳本,將我們的客戶端數據上報google,從而統計你的網頁的性能報告和評估。開發者可通過查詢該數據集來了解使用不同硬件、軟件和網絡的實際 Chrome 用戶的上網體驗。分析很多網絡原點可幫助網站開發者和網絡社區瞭解它們的表現出色之處,發現需要改進的領域。

7.Eruda

Eruda是在移動端開啓調試的利器。它通過模擬PC端的devtools,提供給我們移動端的一個類似的dev tools的調試界面。在調試網絡和緩存方面尤其有用。缺點就是功能遠遠不如桌面版真實的dev tools強大。這是一個閹割版本的調試工具,功能非常有限。

資源準備

You can't optimise what you don't measure。我們很多時候憑自己的感覺來判斷一個網頁的性能,然而往往人的感覺並不可靠。而且我們在判斷一個網頁的性能是隻是單獨的在一個特定的條件下做判斷,這種判斷其實是孤立的,不可靠的。當性能已經能被人的感觀捕獲的話,事情往往就已經太遲了。
在一個網站上線後我們需要對它進行持續的,全面的,廣泛的性能檢測。而這樣一種工作的前提條件就是搭建一套性能監控系統。我在這篇文章裏面講到過如何去搭建一個性能監控系統。搭建一個監控系統並不容易,需要的人力和物力資源不在少數。在大型一點的公司,都有資源和人力控制自己的額團隊搭建一套完善的系統,在中小公司,我建議還是使用第三方的別人的優秀開源作品。

所以你在開始動手幹大事之前,請確保你的資源協調能力,安排人員和資源,預估好時間,以免因爲客觀的因素半途而廢。尤其是打算自己動手搭建監控系統的時候,往往需要統籌全局的權力去安排協調各個部門的人力。所以,對你的資源進行評估後再開始做這件事,做到未雨綢繆。

錙銖必較

預算

在搭建一個網頁應用之前制定預算並不是天方夜譚。在一開始對網站應用的體積進行合理的預測,能夠知道你後續在開發新功能和接受新需求時變得謹慎。合理地制定預算方式是需要一定的經驗,而最終的預算值也並非一定要十分精確,只需要給出合理的預期即可。一般最好能夠有參照的標準:例如你的競爭對手的應用,或者行業內做的最好,體驗最好的那家企業的應用。通常隨着功能的完善和豐富,我們的代碼數量也會越來越多,時時刻刻對照着我們最初安排的那張“預算表”去完成搭建過程。另外,提前制定預算也可以在面對產品不合理的訴求時當擋箭牌(到時候加載慢可不能怨我哦)。

資源

web應用的豐富發展使得我們需要從服務器上加載的東西越來越多,尤其是圖片,視頻和字體等媒體資源,我們在一開始的時候就需要對他們進行一些處理。例如,壓縮圖片和視頻使得體積更小巧,還有選擇不同格式的圖片可以有效的減小體積。Google developer上的一系列文章詳盡的講明白了圖片以及視頻的優化處理方式,以及如何找到合適的策略構建自己的資源。

積沙成塔

性能優化不是一蹴而就的,需要長時間的,反覆的去實踐。有可能我們發一次版本也就是解決一個很小的優化點。但是這些點經過時間的積累,最終會反饋到整體的網頁性能上。保守的策略是逐步的解決性能問題。不論是優化一段代碼,還是減少一條http請求,只要長期地,充滿幹勁的去朝着一個方向做優化工作,性能肯定得到有效的改進。

整體思維

預見未來

如果你是從頭開始做一個項目,那麼在某種程度上來說你的未來是由你自己的決定的。但事實是很多項目,我們接手過來時倒騰了好幾手的,這些項目不幸現在落在了你的頭上,你的老闆於是叫你優化項目,這時候你一定要小心翼翼,以免掉到了別人給你的坑。而如果是個全新開始的新項目,那麼你就能放手一搏了,不不不,在面臨一個新的項目的時候,你同樣需要小心翼翼的,這種小心是在預見上,而不同於之前的是在放手去做上。你在你選擇某個功能的時候你需要仔細它思考,尤其在底層一些設計上,更需要兼顧功能和性能。

前期架構

前期架構多網站來說十分鐘重要。我認爲在架構方面的工作直接或者間接影響了我們在後面一些列的開發和優化的細節打方向。架構其實是屬於選方向的。古語有云:“條條道路通羅馬”。我們的一個產品,在功能上的接口是統一的,但是實現的方式確實有很多種。例如,架構師在前期就需要根據各項指標評估,決定這個產品用什麼樣的方式去完成選用什麼語言,以及何種方式監控後續的需求迭代。例如:PWASPA的優化邏輯不一樣,MPASPA的優化也不一樣,REACTVUE或者ANGLAR在細節上以及優化上的邏輯思路也是不一樣的;又比如,我們網頁應用的定位決定了我們是使用高清的圖片還是質量次一點的小格式圖片、字體等。雖然我們都可以用他們去實現統一的目標,但是考慮到人員,這是儲備,維護,擴展等方面,架構師在選擇這些重要的因素時,就應該多方思考,權衡利弊。或者使用APP SHELL或者其他形式承載你的應用。

編寫代碼

前端程序員經常被人戲稱爲API調用工程師,有時候不知道是不是應該感到該無奈?我認爲如今進入前端這一領域已經很低了,而且在可預見未來,門檻會越來越低。如果你用過那種可視化IDE功能強大的web應用,你就應該知道,以後學習前端技術去做一個網頁應用幾乎只需要幾天甚至幾小時的學習時間就可以了。如今框架的興起也方便了開發人員的工作量,而很多交互性能,我們基本上都可以有框架底層來給你解決。我們能做到的只能是在代碼的可維護性上做做文章。(或者是使用for替代forEach提升性能o(╥﹏╥)o)。雖然如此,但這並不是你不去深入研究的原因。我認爲在編寫代碼的過程刻意地使用關注底層CPU的計算性能優化雖然不太可能,但是我們可以通過其他方式提升業務性能,例如:根據業務類型安排還http的請求時序,根據框架提供的異步能力加載JavaScript或者其他資源,在某些複雜的計算上刻意地使用worker或者自己的算法能力等。只要你願意學習進步,任何地方做任何事情都能夠讓你大展拳腳。

後期監控

後期監控我已經在很多地方強調過了。好的監控能幫我們發現系統的漏洞,性能的缺陷,我認爲大多數人在功能完成後就很少持續關注現實的代碼運行狀況了,只是在臨時發現了bug或者老闆打電話怒氣衝衝的指責網頁加載速度慢的時候,纔會去線上看看自己的代碼,這種是屬於被動的監控。真正的監控不止防範於未然,而且還能預測未來,對照現在,讓我們在對比中不停的磨練自己寫出更好的代碼。

改革與革命

歷史的教訓

改革,在古代被稱之爲變法。回顧歷史的變法者,功成名就的寥寥無幾,大多數是以失敗告終。而革命又因爲是成功人寫就的歷史,往往是在即成的歷史上對革命者歌功頌德,但實際確實殘酷血腥而成就微小甚至反而不如前代。例如辛亥革命雖然革了大清朝的命,但在面對新中國的現代化等一些列問題時,毫無建樹和改變。只是換了一個國號而已。我本人也不喜歡激進的做法,我比較相信時間能夠撫平一切舊制度的缺陷,激烈的革命帶來的往往是流血戰爭,真正需要轉變的是人的思維和觀念,消滅一個人很簡單,要給人灌輸觀念就需要常年累月的付出。工業革命其實也是從逐步改良的蒸汽機而發展起來的,第二次,第三次的工業革命也是在低限度的、低技術含量的第一次工業革命中的手工業改良而來的。
歷史對改革者都不太公平。我們都知道商鞅也好,王安石也好,還有張居正和闞友偉,變法者的境遇都是十分悲慘。當然一部分原因是因爲既得利益者勢力過於強大,但是另外一部分是他們的錯失太過於強硬和激進。歷史告訴我們,一時的熱情終究會消散,只有對目標有堅定的信仰並且懂得利用時間的人,才能達到自己的目的。偉大的事業不是一天只能完成的,這些道理同樣適用於我們今天的主題。我認爲在面對舊項目或者新項目的優化工作時,只要走對了方向,剩下的還是要交給時間。

環境與現實

如果你都是個性能優化老手,在精通了各項性能要素以及優化性能的方法後,你這時候需要面對一個現實的問題。這個問題也是在我在後續優化的時候遇到的:你的優化方案的現實性。我說的實現性是指公司環境,團隊的技術能力,時間等客觀條件。我曾經天真得以爲如果自己什麼都懂,就能什麼都做。後來我才知道,很多事情並不是自己知道就能做的成功。例如你在搭建監控環境時需要的服務器資源,你在優化時具體到每個項目以及與這些項目負責人的溝通,還需要考慮當前你自己的工作量,排期,最後還需要考慮你這樣做是否符合公司的基本要求,領導是否對你支持,公司環境(軟硬件)限制等等,這時候你就需要給自己一些軟件能,包括溝通能力,分享能力還有一點點小滑頭。如果實在不行,那隻能用腳投票了。

最終的抉擇

性能在不明顯的時候即主觀也客觀,通過數據和指標,我們可以客觀地評估一個網頁應用是否存在性能問題。主觀是因爲每個人對網頁加載或者運行的感官是不一樣的(你在非洲和歐洲上網時對網頁加載速度的預期是不一樣的)。我們即可以通過上面所學知識來達到優化的目的,同時也可以通過一個簡單的loading來反饋給用戶,讓他在主觀意識上減少性能加載緩慢帶來的心理焦慮。或者兩者都同時採用。當然無論你猜用何種方式,最終我可以通過數據來了解在性能這塊上,用戶的感受。例如留存率,留存時間等。

總結

很可惜,這個世界上速成的東西大多數都很廉價。在需要對既有的項目進行優化時你要做的和掌握的知識就得非常系統,並且在細節上有清晰的認識。而且改進性能這件事情上需要持續的投入精力才能逐步看到結果。性能優化其實需要掌握的知識是很廣的,有些知識需要深入理解,但總體上,這些知識學習的成本和難度不高。你需要多方面的知識,需要慢慢的摸索在,掌握,沒有捷徑。

引用文檔

Google Developers Document
Goolge Web Fundamentals

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章