本篇是GMTC的前端的性能優(yōu)化與監(jiān)控,最火爆的場之一,因為沒去過其他的場,也可能是沒有之一。有圖有真相,反正人是冒出去了,門口全是人,這個圖是我聽了第三節(jié)課后才混到了門口的座位。

這場是第一天下午的場,一共分為四個分享課,分別是LinkedIn移動應(yīng)用的性能優(yōu)化之道、大前端時代前端監(jiān)控的最佳實踐、愛奇藝APP極致體驗之路、美團客戶端監(jiān)控與異常排查實踐。各家有各家的特長,有各家的方法,不過看起來究極之路的思路方法都差不多,下面我們一起看看他們說了些什么,附大會的PPT下載網(wǎng)址,可能沒多久會失效:https://gmtc.geekbang.org/schedule。
LinkedIn移動應(yīng)用的性能優(yōu)化之道
大會首先提到了為什么要做性能優(yōu)化,引出了LinkedIn的價值觀是用戶第一,姑且我們認(rèn)為這句話也是干貨。接著說道項目的規(guī)模,5億月活,200人團隊,20業(yè)務(wù)線,400W代碼行數(shù)。當(dāng)項目復(fù)雜體量很大的時候,需要進行架構(gòu)的變更,合理的架構(gòu)能夠解決很多問題,也會避免很多問題,能夠化繁為簡。
項目組件化應(yīng)該算是任何項目架構(gòu)變更的必經(jīng)之路,將不同的模塊分離出來,拆成獨立的組件,可以獨立的運行。一般來說都是進行業(yè)務(wù)拆分,而通用的無業(yè)務(wù)相關(guān)性的都會下沉到基礎(chǔ)組件庫,比如網(wǎng)絡(luò)層、持久層、公共類、工具類等等。在iOS平臺上進行組件的拆分,可以利用Pods將拆分后的組件進行集成,能夠很好解決項目的復(fù)雜性和耦合性,也方便多組協(xié)作,好處不言而喻。組件之間可以用不同的語言開發(fā)也互不影響。

有了合理的架構(gòu),也要有一個針對性能的監(jiān)控方案,下圖是監(jiān)控的地方和監(jiān)控的鏈路,講師提到了他們會在鏈路中的每個地方都會打點,從網(wǎng)絡(luò)初始化,到網(wǎng)絡(luò)握手,到發(fā)送第一個字節(jié),接收到第一個字節(jié),以及數(shù)據(jù)的解析,到UI的展示,都進行了打點計時,為此做了一個專用的網(wǎng)絡(luò)庫。


對于數(shù)據(jù)采集的方式也給出了幾點建議
1.對于通用的性能數(shù)據(jù)采集,盡量做到避免讓業(yè)務(wù)層感知,避免侵入業(yè)務(wù)層代碼。做到面向切面的編程方式,以iOS為例可以利用runtime來做這個事情。?
2.采集的數(shù)據(jù)不僅僅是包括性能指標(biāo)的數(shù)據(jù),還需要發(fā)生性能問題的時候的上下文采集下來,上下文可能是當(dāng)時發(fā)生問題頁面的某一個文字, 根據(jù)這個來指定業(yè)務(wù)線和責(zé)任人。
3.采集到數(shù)據(jù)后最終都是要上傳到服務(wù)器上, 什么時候上傳呢?如果上傳的太快就會對服務(wù)器造成太大的壓力,而且會對主業(yè)務(wù)的流量淹沒掉,太慢又可能對問題的修復(fù)不能及時。是一個對服務(wù)器的壓力和實效性的選擇。
4.實踐過程中就是對不同類型的日志做了一個優(yōu)先級的選擇。對實效性要求比較高的,像crash,實時推薦的一些自定義事件, 就希望很快的上傳到服務(wù)器。 不重要的就存在客戶端,最后經(jīng)過壓縮批量上傳。
數(shù)據(jù)采集之后,會經(jīng)過前段的api作為數(shù)據(jù)的生產(chǎn)者,寫入到Kafka,然后會把數(shù)據(jù)分發(fā)到下游的訂閱者,Samza 實時任務(wù)主要是流式處理,主要是實時性比較高的。另外一個下游是hdfs,是一個每天或者每個小時的一個定時任務(wù)處理,這 是一個離線批量的操作,他能夠處理的數(shù)據(jù)量會很大,實效性會差一些。當(dāng)處理完成之后,會把數(shù)據(jù)寫入到數(shù)據(jù)庫里,然后經(jīng)過數(shù)據(jù)的可視化,就能看到各種各樣的表格。有了數(shù)據(jù)就可以進行性能的報警,針對不同的業(yè)務(wù)種類,就可以制定不同的報警閥門。

當(dāng)手機了數(shù)據(jù)日志之后,要怎么分析定位問題呢?首先通過上下文操作盡量去復(fù)現(xiàn)應(yīng)用的場景。 另外還有一些線程堆棧,這是獲取線程的重要信息。此外還做了一些數(shù)據(jù)的洞察,因為很多問題都是一個局部的問題, 可能只有北京的用戶只有這個問題,通過這個數(shù)據(jù)洞察,就可以發(fā)現(xiàn)背后的一個規(guī)律。每上線一個feature的時候,有做服務(wù)端的開關(guān)來做灰度發(fā)布和AB的實驗,開關(guān)也是線上問題的一個保障。當(dāng)發(fā)現(xiàn)性能問題的時候,把服務(wù)端的每個開關(guān)的狀態(tài)控制存儲上來,通過數(shù)據(jù)聚合定位到具體是幾個開關(guān)打開的狀態(tài)下定位到具體的feature.還有一些分析定位的工具,客戶端也有一些診斷日志,發(fā)生問題時候,會把診斷日志拉出來。
定位到問題,首先用了服務(wù)端開關(guān)控制問題的出現(xiàn),熱修復(fù)也能夠解決問題,但是現(xiàn)在蘋果并不能使用這個功能,最后實在沒辦法只能通過發(fā)布新版本解決。
每上線一個feature,都會有AB的實驗。性能優(yōu)化也是一樣,都會做一個AB。原理比較簡單,把用戶分成兩撥,一撥是能看到新的功能,另一撥不能看到。通過數(shù)據(jù)的對比分析,就可以看到實驗對我們帶來哪些影響。主要是通過工具來進行AB實驗,Lix&XLNT是一個創(chuàng)建和維護AB的平臺,預(yù)先定義了一些豐富的規(guī)則,針對用戶的身份或者應(yīng)用的版本。

性能優(yōu)化實踐:

1.首先針對網(wǎng)絡(luò)的優(yōu)化,以前用的是mux,會有多個HTTP Request走到server,增加了一層應(yīng)用層面的多路復(fù)用。

在2017年的時候已經(jīng)全面的接入到http2.0,因為這個天然的支持多個http請求復(fù)用一個連接。在連接上分為多個二進制的流,這些流可以并行的處理數(shù)據(jù)。頭部壓縮也進行了改進,對傳送的數(shù)據(jù)也變得小一些。切換到http2.0后,頁面加載時間縮短 ~7.5%。
最近也在嘗試Google的QUIC,為此針對web和iOS做了寫改進。

2.數(shù)據(jù)簡化。

數(shù)據(jù)的精簡這里也做了工具來優(yōu)化,這里使用了Frontend Deco。首先定義一個data model,有abcde五個字段,在頁面上用到了abc是哪個字段,而通過Frontend Deco來獲取指定的只有abc的一個輕量化的data model。這個的思想跟上一文中提到的GraphQL是一樣的。
3.布局優(yōu)化
針對布局優(yōu)化,做了一個layoutkit框架,經(jīng)過統(tǒng)計要比aotolayout性能高出很多。LayoutKit的思路主要借鑒于flexbox,把布局的計算局限于在一個軸上,使布局計算的復(fù)雜度能夠大大下降。Layoutkit是一個swift框架已經(jīng)開源,附github地址:https://github.com/linkedin/LayoutKit
最后總結(jié):
