如何提高Web前端性能?

什麼是WEB前端呢?就是用戶電腦的瀏覽器所作的一切事情。咱們來看看用戶訪問網站,瀏覽器都作了哪些事情:輸入網址 –> 解析域名 -> 請求頁面 -> 解析頁面併發送頁面中的資源請求 -> 渲染資源 -> 輸出頁面 -> 監聽用戶操做 -> 從新渲染。

經過上面的路徑能夠看出瀏覽器分爲請求、傳輸、渲染三部分來實現用戶的訪問,本文就從這三個部分來淺析如何提高WEB前端性能。javascript

請求css

瀏覽器爲了減小請求傳輸,實現了本身的緩存機制。瀏覽器緩存就是把一個已經請求過的Web資源拷貝一份副本存儲在瀏覽器中,當再次請求相同的URL時,先去查看緩存,若是有本地緩存,瀏覽器緩存機制會根據驗證機制(Etag)和過時機制(Last-Modified)進行判斷是使用緩存,仍是從服務器傳輸資源文件。具體流程以下圖所示:html

如何提高Web前端性能?如何提高Web前端性能?

如何從請求、傳輸、渲染3個方面提高Web前端性能前端

瀏覽器的請求有些是併發的,有些是阻塞的,好比:圖片、CSS、接口的請求是併發;JS文件是阻塞的。請求JS的時候,瀏覽器會中斷渲染進程,等待JS文件加載解析完畢,再從新渲染。因此要把JS文件放在頁面的最後。java

JS也能夠經過兩種方式由阻塞改爲並行:一種是經過建立script標籤,插入DOM中;另外一種是在Script標籤中增長async屬性。jquery

每種瀏覽器對同一域名併發的數量有限制,IE6/7是2,IE9是10,其餘常見的瀏覽器是6,因此減小資源請求數量和使用多域名配置資源文件,能大大提升網站性能。ajax

減小資源請求數量的方法,大體有如下幾種:express

一、經過打包工具,合併資源,減小資源數量。就是開發版本是不少個資源文件,部署的時候,按類合併成幾個文件來輸出。在實現模塊管理的同時,實現統一輸出。promise

二、CSS中,使用css sprite減小圖片請求數量。瀏覽器

三、經過延遲加載技術,在用戶無感知的狀況下請求資源。

四、經過服務器配置,實現一次請求,返回多個資源文件,如淘寶CDN那樣。

除了減小請求數量,也可使用CDN鏡像,來減小網絡節點,實現快速響應。使用了CDN的請求,會根據用戶所處的地理位置,找尋最近的CDN節點,若是請求是新的,則從資源服務器拷貝到節點,而後再返回給客戶端。若是請求已經存在,則直接從節點返回客戶端。

經過上面咱們瞭解的緩存機制,若是咱們部署上線的時候,是須要刷新緩存的。普通緩存經過強刷就能改過來,而CDN緩存則須要經過改變URL來實現。同時咱們不可能要求用戶按着Ctrl來刷新,因此經過打包工具,在部署的時候,統一更改URL是最有效的方式。而不常變動的庫文件,好比echart、jquery,則不建議更改。

傳輸

從服務器往客戶端傳輸,能夠開啓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之類的邊距屬性。

重排是最耗能的,減小重排的方法有:

一、若是須要屢次改變DOM,則先在內存中改變,最後一次性的插入到DOM中。

二、同上一條,若是屢次改變樣式,合成一條,再插入DOM中。

三、因爲position的值爲absoute和fixed時候,是脫離文檔流的,操做此類DOM節點,不會引發整頁重排。因此動畫元素設置position使其脫離文檔流。

四、當DOM節點的display等於none的時候,是不會存在於渲染樹的,因此若是有比較複雜的操做,先使其display等於none,等待全部操做完畢後,再將display設成block,這樣就只重排兩次。

五、獲取會致使重排的屬性值時,存入變量,再次使用時就不會再次重排。獲取這些屬性會致使重排:offsetTop、offsetLeft、offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

以上就是瀏覽器如何把資源變成肉眼所見的頁面的,除了上述根據瀏覽器流程而總結出來的性能優化,咱們還須要看看javascript做爲程序,須要的優化。先來看看javascript的垃圾回收機制。

Javascript的引擎會在固定的時間間隔,將再也不使用的局部變量註銷掉,釋放其所佔的內存。而閉包的存在,將使引用一直存在,沒法被釋放掉。全局變量的生命週期直至瀏覽器卸載頁面纔會結束。因此通常來說,內存溢出就是因爲全局變量的不釋放和閉包引發。爲了防止內存溢出,咱們能夠作的方法有:

一、業務代碼放在匿名當即執行函數裏面,執行完畢會當即釋放掉。

二、少用全局變量,同時用完的變量手動註銷掉。

三、使用回調來代替閉包訪問內部屬性

四、當不可避免使用閉包時,慎重的對待其中的細節。不用的時候註銷掉。

五、經過瀏覽器自帶的工具profiles,來檢查內存活動狀況。若是是波浪型的,說明正常。若是是傾斜式漸進上漲的,說明有內存不會被釋放,須要檢查相應的函數。

最後再說一點,函數裏返回異步取的值,常常有人這麼:

 Var getList = function(){ $.ajax().then(function(data){

   Return data;

}) };

Var users = getList();

毫無疑問,因爲函數內的返回是異步的,因此返回只能是undefined,而不是想要的data。因而爲了實現返回data,就把ajax的async屬性設置成了false,由異步改成同步,來獲取到data。然而最大的問題來了,同步是會中斷渲染進程的,也就是請求返回的等待中,整個頁面是卡死的,用戶操做也不會有響應。這個問題真正的解決方案是返回promise對象,而不是把異步改爲同步。

相關文章
相關標籤/搜索