大前端性能優化總結

客戶端優化

靜態資源優化

網絡請求優化:

  • 使用get進行請求,get會緩存請求,比起post,只發送一個tcp包,效率更好。

  • 合併請求數量,減小http請求次數,節省網絡請求時間。

接口合併(一個頁面須要多個並行或串行的接口實屬正常,網絡很差的狀況下,最好的辦法就是經過接口合併的方式提升接口訪問速度)。

  • 屢次請求和關閉會形成服務了壓力,瀏覽器對每次請求的數量都有限制,通常是每次只能3次左右,合併請求將加快速度。

瀏覽器支持http並行請求數量有限,因此合併資源文件,能夠加快請求,減小延遲 下載一個100kb的js文件比下載4個25kb的js更快。

  • 拋開無用cookie,減小帶寬佔用,http協議每次發送請求都會自動帶上該域名及父級域名下的cookie

瀏覽器緩存

強緩存,協商緩存(根據相應的header內容來決定的)

瀏覽器在請求某一資源時,會先獲取該資源緩存的header信息,判斷是否命中強緩存(cache-controlexpires信息)

若命中直接從緩存中獲取資源信息,包括緩存header信息;本次請求根本就不會與服務器進行通訊

若是沒有命中強緩存,瀏覽器會發送請求到服務器,請求會攜帶第一次請求返回的有關緩存的header字段信息(Lase-Modified/If-Modified-SinceEtag/If-Node-Match),由 服務器根據請求中的相關header信息來比對結果是否協商緩存命中;

若命中,則服務器返回新的響應header信息更新緩存中的對應header信息,可是並不返回資源內容,它會告知瀏覽器能夠直接從緩存獲取,不然返回最新的資源內容。

緩存參考文章

juejin.im/post/5b3c87…

頁面渲染速度優化(用戶體驗優化)

  • css放在頂部,優先渲染。
  • js放在底部,避免堵塞,減小白屏時間和首頁渲染時間。
  • 減小DOM數量,減小重排重繪。
  • Virtual Dom。
  • 預加載和懶加載。
  • 骨架屏。

避免JS堵塞

使用async和defer,async不支持ie9,因此首推薦使用defer,若是使用defer或async請將script標籤放到head標籤中,以便讓瀏覽器更早地發現資源並在後臺線程中解析並加載JS

重排重繪

  1. 重排(reflow):渲染層內的元素佈局發生修改,都會致使頁面從新排列,好比窗口的尺寸發生變化,刪除或添加DOM元素,修改了影響元素盒子大小的css屬性(width,height,padding)

  2. 重繪(repain):因此對元素的視覺表現屬性的修改,都會引起重繪

不論是重排仍是重繪,都會堵塞瀏覽器。要提升網頁性能,就要下降重排和重繪的頻率和成本,儘量少的觸發從新渲染。

重排是CPU處理,重繪是GPU處理,CPU的處理效率遠不及GPU,而且重排必定會引起重繪,而重繪不必定會引起重排

避免重排重繪:

css複用class去批量操做元素樣式

圖片在渲染前指定大小:由於img元素是內聯元素,因此在加載圖片後會改變寬高,嚴重的狀況會致使整個頁面重排,因此最後砸渲染前就指定其大小,或者讓其脫離文檔流

Virtual Dom

Virtual Dom使用高效的diff算法,避免對整棵DOM樹進行變動,而是進行鍼對性的視圖變動,將效率作到最優化。

步驟:

1.生成Virtual Dom樹

2.對比兩顆樹的差別

比較兩顆DOM樹的差別是Virtual Dom算法最核心的部分,這也是咱們常說的Virtual Dom的diff算法,但在比較的過程當中,咱們只比較同級的節點,非同級的節點再也不咱們的比較範圍內,這樣既能夠知足咱們的需求,又能夠簡化算法實現

比較樹的差別,首先是對樹進行遍歷,經常使用的又兩種遍歷算法,分別是深度優先遍歷和廣度優先遍歷,通常的diff算法中都採用的是深度優先遍歷。

對新舊兩顆樹進行一次深度優先的變量,這樣每一個節點都會惟一的標記。在遍歷的時候,每遍歷到一個節點,就把該節點和新的樹的同一個位置的節點進行對比,若是有差別的話就記錄到一個對象裏面。

在差別對象中記錄了有改變的節點,每個發生改變的內容也不盡相同,但也是有跡可循,常見的差別包括四種,分別是: 替換節點

增長/刪除子節點

修改節點屬性

改變文本內容

因此在記錄差別的時候要根據不一樣的差別類型,記錄不一樣的內容。

3.更新視圖

在第二步獲得整顆樹的差別以後,就能夠根據這些差別的不一樣類型,對DOM進行鍼對性的更新。與四中差別類型相對應的,是更新視圖時具體的更新方法,分別是:

replaceChild()

appendChild()/removeChild()

setAttribute()/removeAttribute()

textContent

服務器優化

  • 使用內容分發網絡CDN 客戶端能夠經過最佳的網絡鏈路加載靜態資源。
  • 開啓Gzip壓縮文件內容。
  • 爲文件頭指定expires和cache-control。
  • 對於靜態內容,設置文件頭過時事件,expires的值爲永不過期(never expire)。
  • 對於動態內容,使用恰當的cache-control文件頭來幫助瀏覽器進行有條件的請求。
  • 升級到HTTPS,才能開啓http2和PWA功能。

Gzip壓縮

不要對圖片文件進行Gzip壓縮,對圖片進行壓縮不但會佔用後臺大量資源,壓縮效果其實並不可觀,能夠 說"弊大於利",請在gzip_types把圖片相關項去掉。

CDN(內容分發網絡)

用戶和服務器之間距離越遠,通過的路由器越多,延遲也就越高。 CDN系統會遵循Cache-Control和Expires HTTP頭標準對改請求返回的內容進行緩存,便於後面的請求再也不回源,起到加速功能。

HTTPS VS HTTP

咱們對HTTP和HTTPS常規的理解就是,HTTPS比HTTP多了一層SSL(安全套接層),SSL須要對數據進行加密和解密,http使用tcp三次握手創建鏈接,客戶端和服務器端須要交換3個包。

https除了tcp三個包,還要加上ssl握手的9個包,因此一共是12個包。

因此http比https效率更高,https更安全

可是(此處是重點)

升級到https後,服務器能夠開啓http2.0版本,對比http1.x性能和緩存各方面要更好,還有其餘新特性, 能夠啓動service work功能,更好的進行離線緩存,更好的離線體驗。

HTTPS證書能夠免費申請,阿里雲跟騰訊雲均可以申請,按照文檔指示進行申請下載,而後將下載的證書上傳到服務器,配置服務器的內容,就能夠開啓https、http2.0、service work等功能了。

HTTP2新特性

1.新的二進制格式

http1.x解析的是基於文本,基於文本協議的格式解析存在自然缺陷,文本的表現形式有多樣性, 要作到健壯性考慮的是場景必然不少,二進制則不一樣,只認0和1的組合。 基於這種考慮http2.0的協議解析決 定採用二進制合適,實現方便且健狀。

2.多路複用

即鏈接共享,每個request都是用做鏈接共享機制的。 一個request對應一個id,這樣一個鏈接上能夠有多個request, 每一個鏈接的request能夠隨機的混雜在一塊兒,接收方能夠根據request的id將request再歸屬到各自不一樣的服務器請求裏。

3.header壓縮

http1.x的header帶有大量信息,並且每次都要重複發送,http2.0使用encoder來減小須要傳輸的header大小,通信雙方各自cache一份header fields表,即避免了重複header的傳輸,又減少了須要傳輸的大小。

4.服務器推送 server push

是http2協議裏面,惟一一個須要開發者本身配置的功能嗎,其餘功能都是服務器和瀏覽器自動實現,不須要開發者擔憂 概念:尚未收到瀏覽器請求,服務器就把各類資源推送給瀏覽器 好比:瀏覽器只請求了index.html,可是服務器把index.html,style.css,example.png所有發送給瀏覽器。這樣的話,只須要一輪http通訊,瀏覽器就獲得了所有資源,提升了性能.

代碼優化

流程控制

  • 避免使用for...in(它能枚舉到原型,因此很慢)

  • 使用Map表代替大量的if-else和switch會提高性能和代碼可閱讀和維護性。

  • 函數的防抖節流

    justclear.github.io/throttle-an…

  • 事件委託的有點

    1.減小內存消耗

    有一個列表,列表之中有大量的列表項,咱們須要在點擊列表項的時候相應一個事件:

    若是給每一個列表項一一都綁定一個函數,那對於內存消耗是很是大的,效率上須要消耗不少性能;

    所以,比較好的方法就是把這個點擊事件綁定到他的父層,也就是ul上,而後再執行事件的時候再去匹配目標元素

    因此事件委託能夠減小大量的內存小號,節約效率

    2.動態綁定事件

    事件是綁定在父層的,和目標元素的增減是沒有關係的,執行到目標元素是在真正響應執行事件函數的過程當中去匹配的

    因此使用事件在動態綁定事件的狀況下是能夠減小不少重複工做的。

  • hidden

    無論怎樣,你是否曾經爲了隱藏某個元素而使用過myElement.style.display = 'none‘這種方法呢?若是是的話,請別再這麼作了!只須要調用myElement.hidden = true便可實現元素隱藏的功能。

效率優化

  • 易拓展,易維護,易維護的代碼(函數式編程),快速定位Bug。

    flow靜態類型檢查,ESLint

    模塊化變化才能,封裝共用的組件

  • 引入Webpack,Rollup,Parcel等自動化構建工具

    Webpack構建優化

    區分開發環境和生產環境,自動提取公共代碼,壓縮代碼,開啓熱更新、自動保存刷新功能等。

    使用ES6,引入babel-loader,並開啓緩存,解決兼容性。

    引入Less,Sass等CSS預處理器,提升編碼效率和瀏覽器兼容性。

線上環境優化

錯誤監控

sentry(國外開源的錯誤監控,有線上環境也能夠自行部署)

sentry官網

sentry跟Vue搭配

自動化構建、持續集成

Travis CI(對Github支持很友好)

阮一峯Travis CI教程

相關文章
相關標籤/搜索