如何從請求、傳輸、渲染3個方面提升Web前端效能
什麼是WEB前端呢?就是使用者電腦的瀏覽器所做的一切事情。我們來看看使用者訪問網站,瀏覽器都做了哪些事情:
輸入網址 –> 解析域名 -> 請求頁面 -> 解析頁面併傳送頁面中的資源請求 -> 渲染資源 -> 輸出頁面 -> 監聽使用者操作 -> 重新渲染。
通過上面的路徑可以看出瀏覽器分為請求、傳輸、渲染三部分來實現使用者的訪問,本文就從這三個部分來淺析如何提升WEB前端效能。
請求
瀏覽器為了減少請求傳輸,實現了自己的快取機制。瀏覽器快取就是把一個已經請求過的Web資源拷貝一份副本儲存在瀏覽器中,當再次請求相同的URL時,先去檢視快取,如果有本地快取,瀏覽器快取機制會根據驗證機制(Etag)和過期機制(Last-Modified)進行判斷是使用快取,還是從伺服器傳輸資原始檔。具體流程如下圖所示:
瀏覽器的請求有些是併發的,有些是阻塞的,比如:圖片、CSS、介面的請求是併發;JS檔案是阻塞的。請求JS的時候,瀏覽器會中斷渲染程式,等待JS檔案載入解析完畢,再重新渲染。所以要把JS檔案放在頁面的最後。
JS也可以通過兩種方式由阻塞改成並行:一種是通過建立script標籤,插入DOM中;另一種是在Script標籤中增加async屬性。
每種瀏覽器對同一域名併發的數量有限制,IE6/7是2,IE9是10,其他常見的瀏覽器是6,所以減少資源請求數量和使用多域名配置資原始檔,能大大提高網站效能。
減少資源請求數量的方法,大致有以下幾種:
1、通過打包工具,合併資源,減少資源數量。就是開發版本是很多個資原始檔,部署的時候,按類合併成幾個 檔案來 輸出。在實現模組管理的同時,實現統一輸出。
2、CSS中,使用css sprite減少圖片請求數量。
3、通過延遲載入技術,在使用者無感知的情況下請求資源。
4、通過伺服器配置,實現一次請求,返回多個資原始檔,如淘寶CDN那樣。
除了減少請求數量,也可以使用CDN映象,來減少網路節點,實現快速響應。使用了CDN的請求,會根據使用者所處的地理位置,找尋最近的CDN節點,如果請求是新的,則從資源伺服器拷貝到節點,然後再返回給客戶端。如果請求已經存在,則直接從節點返回客戶端。
通過上面我們瞭解的快取機制,如果我們部署上線的時候,是需要重新整理快取的。普通快取通過強刷就能改過來,而CDN快取則需要通過改變URL來實現。同時我們不可能要求使用者按著Ctrl來重新整理,所以通過打包工具,在部署的時候,統一更改URL是最有效的方式。而不常變更的庫檔案,比如echart、jquery,則不建議更改。
在這裡小編建了一個前端學習交流扣扣群:132667127,我自己整理的最新的前端資料和高階開發教程,如果有想需要的,可以加群一起學習交流
傳輸
從伺服器往客戶端傳輸,可以開啟gzip壓縮來提高傳輸效率。
Gzip有從1-10的十個等級。越高壓縮的越小,但壓縮使用的伺服器硬體資源就越多。根據實踐,等級為5的時候最均衡,此時壓縮效果是100k可以壓縮成20k。
渲染
瀏覽器在載入了html後,就會一邊解析,一邊根據解析出來的結果進行資源請求,並生成DOM樹。而載入完畢的CSS,則被渲染引擎根據生成好的DOM樹,來生成渲染樹。等所有資源解析完畢計算好layout後,向瀏覽器介面繪製。隨著使用者操作,JS會修改DOM節點或樣式,重新繪製和重新排列。重新繪製指的是繪製DOM節點對應的渲染節點,重新排列是指重新計算這些節點在瀏覽器介面的位置。很顯然,重排是非常耗效能的。我們要做的是減少重排的次數。
生成DOM樹的時候,我們可以通過減少DOM節點來優化效能。最初都是用table佈局,節點深度和數量相當複雜,效能很差。同樣CSS作為層疊樣式表,層級也不可太深,不然遍歷的成本很高。另外CSS的expression屬性相當耗效能,能不用則不用。動畫效果能用CSS寫的就不用JS寫,渲染引擎不一樣,效能損耗也不一樣。
上面說的是解析渲染的過程,我們再接著說說使用者互動操作的過程。使用者操作就會導致重繪和重排,重排一定會引起重繪,而重繪不一定會引起重排。到底怎樣會引起重排呢?簡單的定義,DOM結構的變化,以及DOM樣式中幾何屬性的變化,就會導致重排。幾何屬性顧名思義,就是寬、高、邊框、外補丁、內補丁等俗稱盒模型的屬性。同時還有offset之類的邊距屬性。
重排是最耗能的,減少重排的方法有:
1、如果需要多次改變DOM,則先在記憶體中改變,最後一次性的插入到DOM中。
2、同上一條,如果多次改變樣式,合成一條,再插入DOM中。
3、由於position的值為absoute和fixed時候,是脫離文件流的,操作此類DOM節點,不會引起整頁重排。所以動畫元素設定position使其脫離文件流。
4、當DOM節點的display等於none的時候,是不會存在於渲染樹的,所以如果有比較複雜的操作,先使其display等於none,等待所有操作完畢後,再將display設成block,這樣就只重排兩次。
5、獲取會導致重排的屬性值時,存入變數,再次使用時就不會再次重排。獲取這些屬性會導致重排:offsetTop、offsetLeft、offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight
以上就是瀏覽器如何把資源變成肉眼所見的頁面的,除了上述根據瀏覽器流程而總結出來的效能優化,我們還需要看看javascript作為程式,需要的優化。先來看看javascript的垃圾回收機制。
Javascript的引擎會在固定的時間間隔,將不再使用的區域性變數登出掉,釋放其所佔的記憶體。而閉包的存在,將使引用一直存在,無法被釋放掉。全域性變數的生命週期直至瀏覽器解除安裝頁面才會結束。所以一般來講,記憶體溢位就是由於全域性變數的不釋放和閉包引起。為了防止記憶體溢位,我們可以做的方法有:
1、業務程式碼放在匿名立即執行函式裡面,執行完畢會立即釋放掉。
2、少用全域性變數,同時用完的變數手動登出掉。
3、使用回撥來代替閉包訪問內部屬性
4、當不可避免使用閉包時,慎重的對待其中的細節。不用的時候登出掉。
5、通過瀏覽器自帶的工具profiles,來檢查記憶體活動情況。如果是波浪型的,說明正常。如果是傾斜式漸進上漲的,說明有記憶體不會被釋放,需要檢查相應的函式。
最後再說一點,函式裡返回非同步取的值,經常有人這麼:
Var getList = function(){ $.ajax().then(function(data){
Return data;
}) };
Var users = getList();
毫無疑問,由於函式內的返回是非同步的,所以返回只能是undefined,而不是想要的data。於是為了實現返回data,就把ajax的async屬性設定成了false,由非同步改為同步,來獲取到data。然而最大的問題來了,同步是會中斷渲染程式的,也就是請求返回的等待中,整個頁面是卡死的,使用者操作也不會有響應。這個問題真正的解決方案是返回promise物件,而不是把非同步改成同步。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69940844/viewspace-2651480/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何提升Web前端效能?Web前端
- 非科班出身的Web前端程式設計師,從這三個方面來提升自己Web前端程式設計師
- 前端傳送的請求,是如何請求到後端服務的?前端後端
- 從輸入url到傳送請求發生了什麼
- 小白如何入門Web前端?你可以從這幾方面入手Web前端
- SpringMVC中如何傳送GET請求、POST請求、PUT請求、DELETE請求。SpringMVCdelete
- Go Web如何處理Web請求?GoWeb
- 如何提升web前端技術?Web前端
- 我對請求做了個效能小最佳化,提升了50%的頁面效能
- 如何傳送請求以及AJAX
- CRM系統從3個方面幫助銷售人員提升業績
- 如何提升前端基建的效能價值?前端
- web前端圖片上傳(3)–filereaderWeb前端
- nuxt3 同構渲染的資料請求問題UX
- 學習Web前端,如何提升自我價值Web前端
- jQuery裡如何使用ajax傳送請求jQuery
- 如何提升大容量檔案上傳效能
- 如何大幅提升web前端效能之看tengine在大公司架構實踐Web前端架構
- Web請求過程Web
- 從頁面載入到資料請求,前端頁面效能優化實踐分享前端優化
- 前端CORS請求梳理前端CORS
- 呼叫ASP.NET Web API不能傳送PUT/DELETE請求ASP.NETWebAPIdelete
- 如何使用jMeter傳送兩個邏輯上相關的HTTP請求JMeterHTTP
- 在學web前端如何求職就業 Web前端就業前景怎樣Web前端求職就業
- html頁面中如何傳送ajax請求HTML
- 如何在 Go 中傳送表單請求Go
- 在瀏覽器輸入一個地址, 傳送請求, 經歷了哪些過程?瀏覽器
- nginx 如何處理一個請求Nginx
- 說說如何使用 Spring Security 保護 web 請求SpringWeb
- 前端不止:Web效能優化–關鍵渲染路徑以及優化策略前端Web優化
- Web Beacon 重新整理/關閉頁面之前傳送請求Web
- 裸辭兩個月,海投一個月,從Android轉戰Web前端的求職之路AndroidWeb前端求職
- 你真的會用react hooks?看看eslint警告吧!(如何發請求、提升程式碼效能等問題)ReactHookEsLint
- 從瀏覽器傳送請求給SpringBoot後端時,是如何準確找到哪個介面的?(下篇)瀏覽器Spring Boot後端
- 前端專案中如何保證請求時序前端
- Postman傳送Post請求Postman
- java傳送http請求JavaHTTP
- HTTP GET請求傳bodyHTTP