成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

那些年,我們一起做過的性能優化

開發 測試
一直以來,性能都是技術層面不可避開的話題,尤其在中大型復雜項目中。猶如汽車整車性能,追求極速的同時,還要保障舒適性和實用性,而在汽車制造的每個環節、零件整合情況、發動機調校等等,都會最終影響用戶體感以及商業達成。

一直以來,性能都是技術層面不可避開的話題,尤其在中大型復雜項目中。猶如汽車整車性能,追求極速的同時,還要保障舒適性和實用性,而在汽車制造的每個環節、零件整合情況、發動機調校等等,都會最終影響用戶體感以及商業達成,如下圖性能對收益的影響。

性能優化是一個體系化、整體性的事情,印刻在項目開發環節的各個細節中,也是體現技術深度的大的戰場。下面我將以Quick BI的復雜系統為背景,深扒整個性能優化的思路和手段,以及體系化的思考。

如何定位性能問題?

通常來講,我們對動畫的幀率是比較敏感的(16ms內),但如果出現性能問題,我們的實際體感可能就一個字:“慢”,但這并不能為我們解決問題提供任何幫助,由此我們需要剖析這個字背后的整條鏈路。

上圖是瀏覽器通用的處理流程,結合我們的場景,我這里抽象成以下幾個步驟:

可以看出,主要的耗時階段分為兩個:

階段一:資源包下載(Download Code)

階段二:執行 & 取數(Script Execution & Fetch Data)

如何深入這兩個階段,我們一般會用以下幾個主要的工具來分析:

Network

首先我們要使用的一個工具是Chrome的Network,它能幫助我們初步定位瓶頸所在的環節:

如圖示例,在Network中可以一目了然看到整個頁面的:加載時間(Finish)、加載資源大小、請求數量、每個請求耗時及耗時點、資源優先級等等。上面示例可以很明顯看出:整個頁面加載的資源很大,接近了30MB。

Coverage(代碼覆蓋率)

對于復雜的前端工程,其工程構建的產物一般會存在冗余甚至未被使用的情況,這些無效加載的代碼可以通過Coverage工具來實時分析:

如上圖示例可以看到:整個頁面28.3MB,其中19.5MB都未被使用(執行),其中engine-style.css文件的使用率只有不到0.7%

資源大圖

剛才我們已經知道前端資源的利用率非常低,那么具體是哪些無效代碼被引入進來了?這時候我們要借助webpack-bundle-analyzer來分析整個的構建產物(產物stats可以通過webpack --profile --json=stats.json輸出):

如上例,結合我們當前業務可以看到構建產物的問題:

第一,初始包過大(common.js)

第二,存在多個重復包(momentjs等)

第三,依賴的第三方包體積過大

模塊依賴關系

有了資源構建大圖,我們也大概知道了可優化的點,但在一個系統中,成百上千的模塊一般都是通過互相引用的方式組織在一起,打包工具再通過依賴關系將其構建在一起(比如打成common.js單個文件),想要直接移除掉某個模塊代碼或依賴可能并非易事,由此我們可能需要一定程度抽絲剝繭,借助工具理清系統中模塊的依賴關系,再通過調整依賴或加載方式來作優化:

上圖我們使用到的是webpack官方的analyse工具(其他工具還有:webpack-xray,Madge),只需要將資源大圖stats.json上傳即可得到整個依賴關系大圖

Performance

前面講到的都是和資源加載相關的工具,那么在分析 “執行 & 取數” 環節我們使用什么,Chrome提供了非常強大的工具:Performance:

如上圖示例,我們可以至少發現幾個點:主流程串化、長任務、高頻任務。

如何優化性能?

結合剛才提到的分析工具,剛才提到的 “資源包下載”、“執行 & 取數” 兩個大的階段我們基本上已經覆蓋到,其根本問題和解法也在不斷的分析中逐步有了思路,這里我將結合我們這里的場景,給出一些不錯的優化思路和效果

大包按需加載

要知道,前端工程構建打包(如webpack)一般是從entry出發,去尋找整棵依賴樹(直接依賴),從而根據這棵樹產出多個js和css文件bundle或trunk,而一個模塊一旦出現在依賴樹中,那么當頁面加載entry的時候,同時也會加載該模塊。

所以我們的思路是打破這種直接依賴,針對末端的模塊改用異步依賴方式,如下:

將同步的import { Marker } from '@antv/l7'改為異步,這樣在構建時,被依賴的Marker會形成一個chunk,僅在此段代碼執行時(按需),該thunk才被加載,從而減少了首屏包的體積。

然而上面方案會存在一個問題,構建會將整個@antv/l7作為一個chunk,而非Marker部分代碼,導致該chunk的TreeShaking失效,體積很大。我們可以使用構建分片方式解決:

如上,先創建Marker的分片文件,使之具備TreeShaking的能力,再在此基礎上作異步引入。

下方是我們優化后的流程對比結果:

這一步,我們通過按需拆包,異步加載,節省了資源下載時間和部分執行時間

資源預加載

其實我們在分析階段已經發現一個“主流程串化”的問題,js的執行是單線程,但瀏覽器實際上是多線程運行的,這里面就包括異步請求(fetch等),所以我們進一步的思路是把取數(Fetch Data)與資源下載通過多線程并行。

按照當前現狀,接口取數的邏輯一般是耦合在業務邏輯或數據處理邏輯中的,所以解耦(與UI、業務模塊等解耦)的步驟必不可少,將純粹的fetch請求(及少量處理邏輯)剝離出來,放到優先級更高的階段來發起請求。那么放到什么地方呢?我們知道,瀏覽器對資源的處理是有優先級的,正常按如下順序:

HTML/CSS/FONT

Preload/SCRIPT/XHR

Image/Audio/Video

Prefetch

要做到資源拉取 和 發起取數并行,就有必要把取數提前到第1優先級(HTML解析完畢后立即執行,而非等待SCRIPT標簽資源加載執行過程中發起請求),我們的流程會變成如下:

需要特別注意一點:由于JS的執行是串行,發起取數的那段邏輯必須要先于主流程邏輯執行,并且不能放到nextTick(如使用setTimeout(() => doFetch())),否則主流程會一直占用CPU時間使得請求無法發出

主動任務調度

瀏覽器對資源也有優先級策略,但它并不知道業務層面的我們,到底想要哪些資源先加載/執行,哪些資源后加載/執行,所以我們跳出來看,若把整個業務層面的資源加載+執行/取數流程拆成一個一個小的任務,這些任務全權由我們自己來控制其:打包粒度、加載時機、執行時機,是不是意味著能最大化利用CPU時間和網絡資源了?

答案是肯定的,不過一般對于簡單的項目,瀏覽器本身的調度優先級策略已經足夠滿足需要,但如果針對大型復雜項目,要做的相對極致的優化,就有必要引入“自定義任務調度”方案了。

以Quick BI為例,我們的前期目標是:讓首屏主要內容展現更加快速。那么從資源加載、代碼執行、取數層面是應該根據我們業務優先級作CPU/網絡分配的,比如:我希望“卡片的下拉菜單”,在首屏主要內容展示完畢后或CPU空閑時,才開始加載(即降低優先級,更甚至在用戶鼠標移入卡片中時,又希望它提高優先級立即開始加載并展示)。如下:

這里我們封裝了一個任務調度器,其目的是可以聲明一段邏輯,在其某個依賴(Promise)完成后開始執行。我們的流程圖變化如下:

黃色區塊代表 作優先級降級處理的部分模塊,其幫助減少了整個首屏時間

TreeShaking

上面講方法大多從優先級出發,其實在前端工程化日益復雜的時代(中大型項目已超幾十萬行代碼),誕生了一個較為智能的優化方案用于減少包大小,其思想很簡單:工具化分析依賴關系,將沒有被引用到的代碼從最終產物中剔除掉。

聽起來很酷,實際用起來也非常不錯,但這里想講一些很多其官網也不會提到的點 --- TreeShaking經常失效的情況:

副作用

副作用(Side Effects)通常表達的是對全局(如window對象等)或環境會產生影響的代碼。

如圖示例,b代碼看似未被使用,但其文件中存在console.log(b(1))這樣的代碼,webpack等打包工具不敢輕易移除它,所以它會被照常打入。

解決方法

在package.json 或 webpack配置中明確指定哪些代碼具備副作用(例如sideEffects: [“**/*.css”]),無副作用的代碼將被移除

IIFE類代碼

IIFE即會被立即執行的函數表達式(Immediately invoked function expression)

如圖,這類型的代碼,會導致TreeShaking失效

解決方法

三個原則:

[避免]立即執行的函數調用
[避免]立即執行的new操作
[避免]立即影響全局的代碼

懶加載

我們在“按需加載”處提到過異步import來做拆包會導致TreeShaking失效,這里再進一步說明一下另外一個case:

如圖,由于index.ts同步import了bar.ts中的sharedStr,然后在某個地方,又同時異步import('./bar'),這種情況下,會同時導致兩個問題:

TreeShaking失效(unusedStr會被打入)
異步懶加載失效(bar.ts會和index.ts打入到一起)
當代碼量達到一定量級,N個人協同開發就很容易出現這個問題

解決方法

[避免]同步和異步import同個文件
按需策略(Lazy)

其實前面有講到一些按需加載的方案,這里我們適當延伸一下:既然資源包的加載可以做到按需,是否某個組件的渲染可以按需?某個對象實例的使用可以按需?某個數據緩存的生成也可以按需?

懶組件(LazyComponent)

如圖,PieArc.private.ts對應一個復雜的React組件,PieArc通過makeLazyComponent封裝成默認懶加載的組件,只有在代碼執行到此處時,組件才會加載并執行。甚至,還可以通過第二個參數(deps)申明依賴,待依賴(promise)完畢時,才加載和執行。

懶緩存(LazyCache)

懶緩存用于這種場景:需要在任何地方使用到數據流(或其他可訂閱數據)中的某個數據經過轉換后的結果,且僅在使用的那一刻才進行轉換

懶對象(LazyObject)

懶對象意即該對象只有在被使用的時候(屬性/方法被訪問、修改、刪除等等),才會被實例化

如圖,globalRecorder被引入時,其并未實例化,僅當調用globalRecorder.record()時進行實例化

數據流:節流渲染

中大型項目中為了方便狀態管理,通常會使用到數據流的方案,如下流程:

store中存儲的數據通常偏原子化,粒度非常小,比如state中有:a、b、c ...等N個原子屬性,某個組件依賴這N個屬性來作UI渲染,假設N個屬性會在不同的ACTION下被改變,且這些改變均在16ms內發生,那么若N=20,則16ms內(1幀)會有20次View更新:

這顯然會引發非常大的性能問題,由此,我們需要對短時間的ACTION量作一個緩沖節流,待20次ACTION狀態改變完畢后,僅進行1次View更新,如下:

此方案在Quick BI以redux中間件的形式發揮作用,在復雜+頻繁數據更新場景起到了不錯的效果

思考

“君子以思患而豫防之”,當我們回過頭去看看,出現的這些性能問題,在架構設計、編碼階段是可以避免掉80%以上的,20%的則可以“空間<=>時間置換策略”等方式去平衡。所以,最佳的性能優化方案,是在于我們對每一段代碼質量的執著:是否考慮到了這樣的模塊依賴關系,可能帶來的構建產物體積問題?是否考慮到了這段邏輯可能的執行頻次?是否考慮到了隨著數據增長,空間或CPU占用的可控性?等等。性能優化沒有銀彈,作為技術人,需要內修于心(熟知底層原理),把對性能的執念植入本能思考當中,方為銀彈。

原文鏈接:http://click.aliyun.com/m/1000283335/
 

 

責任編輯:梁菲 來源: 阿里云云棲號
相關推薦

2011-12-18 18:32:35

APP

2012-07-27 13:36:00

Office操作系統

2019-06-03 14:43:19

高考數據分析錄取率

2015-05-25 09:53:27

DEMO CHINA

2014-01-23 14:10:02

2024-07-11 08:26:00

2012-02-22 10:48:23

操作系統

2019-04-18 11:43:40

軟件卸載PC端

2012-03-02 09:45:02

Ubuntu操作系統

2012-03-22 09:47:37

服務器操作系統OS

2012-06-06 10:38:32

Windows操作系統

2023-12-29 08:29:15

QPS系統應用

2025-03-13 05:00:00

2025-06-11 02:10:00

2021-07-22 10:04:56

網絡安全工具ClamAV

2024-02-26 00:00:00

Go性能工具

2024-11-04 09:52:19

單例模式性能內存

2013-08-19 09:11:09

2014-05-21 11:20:14

漏洞安全漏洞

2023-07-14 12:28:07

JVM優化操作
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产欧美一级二级三级在线视频 | 一区二区三区在线播放 | 久久9热| 欧美色人 | 中文字幕免费视频 | 欧美日本久久 | 一区二视频 | 久久久久久国产精品久久 | 一色桃子av一区二区 | 国产精品日韩欧美 | 久久久精品日本 | www狠狠干 | 亚洲444kkkk在线观看最新 | av国产精品毛片一区二区小说 | 成人免费网站 | 成人福利在线观看 | 91久久久久 | 欧美伊人| 神马久久久久久久久久 | 精品国产精品三级精品av网址 | 国产午夜精品一区二区 | 中国一级毛片免费 | 一区二区三区亚洲 | 午夜合集 | 在线观看国产wwwa级羞羞视频 | 亚洲va中文字幕 | 国产精品成人一区二区三区 | 久久婷婷国产麻豆91 | 国产精品嫩草影院精东 | 99精品观看 | 日本免费网 | 成人免费观看视频 | 国产免费一区二区 | 欧美aaaaaaaaaa| 福利网址 | 成人免费视频网站在线观看 | 亚洲精品久久久久久久久久久久久 | 久久国产成人午夜av影院武则天 | 久久久999国产精品 中文字幕在线精品 | 天天操天天插天天干 | 欧美一区二 |