前端性能優化 —— 移動端瀏覽器優化策略

: 前端性能優化是一個很寬泛的概念,本書前面的部分也多多少少提到一些前端優化方法,這也是咱們一直在關注的一件重要事情。配合各類方式、手段、輔助系統,前端優化的最終目的都是提高用戶體驗,改善頁面性能,咱們經常不遺餘力進行前端頁面優化,但卻忽略了這樣作的效果和意義。先不急於探究前端優化具體能夠怎樣去作,先看看什麼是前端性能,應該怎樣去了解和評價前端頁面的性能。html

 

相對於桌面端瀏覽器,移動端Web瀏覽器上有一些較爲明顯的特色:設備屏幕較小、新特性兼容性較好、支持一些較新的HTML5和CSS3特性、須要與Native應用交互等。但移動端瀏覽器可用的CPU計算資源和網絡資源極爲有限,所以要作好移動端Web上的優化每每須要作更多的事情。前端

 

首先,在移動端Web的前端頁面渲染中,桌面瀏覽器端上的優化規則一樣適用,此外針對移動端也要作一些極致的優化來達到更好的效果。須要注意的是,並非移動端的優化原則在桌面瀏覽器端就不適用,而是因爲兼容性和差別性的緣由,一些優化原則在移動端更具表明性。web

 

1、網絡加載類

 

1.首屏數據請求提早,避免JavaScript文件加載後才請求數據編程

 

爲了進一步提高頁面加載速度,能夠考慮將頁面的數據請求儘量提早,避免在JavaScript加載完成後纔去請求數據。一般數據請求是頁面內容渲染中關鍵路徑最長的部分,並且不能並行,因此若是能將數據請求提早,能夠極大程度上縮短頁面內容的渲染完成時間。後端

 

2.首屏加載和按需加載,非首屏內容滾屏加載,保證首屏內容最小化瀏覽器

 

因爲移動端網絡速度相對較慢,網絡資源有限,所以爲了儘快完成頁面內容的加載,須要保證首屏加載資源最小化,非首屏內容使用滾動的方式異步加載。通常推薦移動端頁面首屏數據展現延時最長不超過3秒。目前中國聯通3G的網絡速度爲338KB/s(2.71Mb/s),因此推薦首屏全部資源大小不超過1014KB,即大約不超過1MB。緩存

 

3.模塊化資源並行下載安全

 

在移動端資源加載中,儘可能保證JavaScript資源並行加載,主要指的是模塊化JavaScript資源的異步加載,例如AMD的異步模塊,使用並行的加載方式可以縮短多個文件資源的加載時間。性能優化

 

4.inline首屏必備的CSS和JavaScript網絡

 

一般爲了在HTML加載完成時能使瀏覽器中有基本的樣式,須要將頁面渲染時必備的CSS和JavaScript經過<script>或<style>內聯到頁面中,避免頁面HTML載入完成到頁面內容展現這段過程當中頁面出現空白。

 

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <title>樣例</title>

    <meta name="viewport" content="width=device-width,minimum-scale=1.0, maximum-scale=1.0,user-scalable=no">

    <style>

    /* 必備的首屏CSS */

    html, body{

        margin: 0;

        padding: 0;

       

    }

    </style>

</head>

<body>

</body>

 

5.meta dns prefetch設置DNS預解析

 

設置文件資源的DNS預解析,讓瀏覽器提早解析獲取靜態資源的主機IP,避免等到請求時才發起DNS解析請求。一般在移動端HTML中能夠採用以下方式完成。

 

<!-- cdn域名預解析 -->

<meta http-equiv="x-dns-prefetch-control" content="on">

<link rel="dns-prefetch" href="//cdn.domain.com">

 

6.資源預加載

 

對於移動端首屏加載後可能會被使用的資源,須要在首屏完成加載後儘快進行加載,保證在用戶須要瀏覽時已經加載完成,這時候若是再去異步請求就顯得很慢。

 

7.合理利用MTU策略

 

一般狀況下,咱們認爲TCP網絡傳輸的最大傳輸單元(Maximum Transmission Unit,MTU)爲1500B,即網絡一個RTT(Round-Trip Time,網絡請求往返時間)時間內能夠傳輸的數據量最大爲1500字節。所以,在先後端分離的開發模式中,儘可能保證頁面的HTML內容在1KB之內,這樣整個HTML的內容請求就能夠在一個RTT時間內請求完成,最大限度地提升HTML載入速度。

 

2、緩存類

 

1.合理利用瀏覽器緩存

 

除了上面說到的使用Cache-Control、Expires、Etag和Last-Modified來設置HTTP緩存外,在移動端還可使用localStorage等來保存AJAX返回的數據,或者使用localStorage保存CSS或JavaScript靜態資源內容,實現移動端的離線應用,儘量減小網絡請求,保證靜態資源內容的快速加載。

 

2.靜態資源離線方案

 

對於移動端或Hybrid應用,能夠設置離線文件或離線包機制讓靜態資源請求從本地讀取,加快資源載入速度,並實現離線更新。關於這塊內容,咱們會在後面的章節中重點講解。

 

3.嘗試使用AMP HTML

 

AMP HTML能夠做爲優化前端頁面性能的一個解決方案,使用AMP Component中的元素來代替原始的頁面元素進行直接渲染。

 

<!-- 不推薦 -->

<video width="400" height="300" src="http://www.domain.com/videos/myvideo.mp4" poster="path/poster.jpg">

    <div fallback>

        <p>Your browser doesn’t support HTML5 video</p>

    </div>

    <source type="video/mp4" src="foo.mp4">

    <source type="video/webm" src="foo.webm">

</video>

 

 

<!-- 推薦 -->

<amp-video width="400" height="300" src="http://www.domain.com/videos/myvideo.mp4" poster= "path/poster.jpg">

    <div fallback>

        <p>Your browser doesn’t support HTML5 video</p>

    </div>

    <source type="video/mp4" src="foo.mp4">

    <source type="video/webm" src="foo.webm">

</amp-video>

 

3、圖片類

 

1.圖片壓縮處理

 

在移動端,一般要保證頁面中一切用到的圖片都是通過壓縮優化處理的,而不是以原圖的形式直接使用的,由於那樣很消耗流量,並且加載時間更長。

 

2.使用較小的圖片,合理使用base64內嵌圖片

 

在頁面使用的背景圖片很少且較小的狀況下,能夠將圖片轉化成base64編碼嵌入到HTML頁面或CSS文件中,這樣能夠減小頁面的HTTP請求數。須要注意的是,要保證圖片較小,通常圖片大小超過2KB就不推薦使用base64嵌入顯示了。

 

.class-name {

       background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAALCAMAAABxsOwqAAAAYFBMVEWnxwusyQukxQudwQyZvgyhxAyfwgyxzAsUHQGOuA0aJAERGAFIXwSTugyEqgtqhghQZgUwQQIpOQKbuguVtQuKrAuCowp2kQlheghTbQZHWQU7SwVAVgQ6TgQlLwMeKwFOemyQAAAAVElEQVQI1y3JVRaAIAAF0UconXbvf5ei8HfPDIQQhBAAFE10iKig3SLRNN4SP/p+N08VC0YnfIlNWtqIkhg/TPYbCvhqdHAWRXPZSp3g3CWZvVLXC6OJA3ukv0AaAAAAAElFTkSuQmCC');

}

 

3.使用更高壓縮比格式的圖片

 

使用具備較高壓縮比格式的圖片,如webp等。在同等圖片畫質的狀況下,高壓縮比格式的圖片體積更小,可以更快完成文件傳輸,節省網絡流量。

 

<img src="//cdn.domain.com/path/photo.webp" alt="webp格式圖片">

 

4.圖片懶加載

 

爲了保證頁面內容的最小化,加速頁面的渲染,儘量節省移動端網絡流量,頁面中的圖片資源推薦使用懶加載實現,在頁面滾動時動態載入圖片。

 

<img data-src="//cdn.domain.com/path/photo.jpg" alt="懶加載圖片">

 

5.使用Media Query或srcset根據不一樣屏幕加載不一樣大小圖片

 

在介紹響應式的章節中咱們瞭解到,針對不一樣的移動端屏幕尺寸和分辨率,輸出不一樣大小的圖片或背景圖能保證在用戶體驗不下降的前提下節省網絡流量,加快部分機型的圖片加載速度,這在移動端很是值得推薦。

 

6.使用iconfont代替圖片圖標

 

在頁面中儘量使用iconfont來代替圖片圖標,這樣作的好處有如下幾個:使用iconfont體積較小,並且是矢量圖,所以縮放時不會失真;能夠方便地修改圖片大小尺寸和呈現顏色。可是須要注意的是,iconfont引用不一樣webfont格式時的兼容性寫法,根據經驗推薦儘可能按照如下順序書寫,不然不容易兼容到全部的瀏覽器上。

 

@font-face {

    font-family: iconfont;

    src: url("./iconfont.eot");

    src: url("./iconfont.eot?#iefix") format("eot"),

         url("./iconfont.woff") format("woff"),

         url("./iconfont.ttf") format("truetype");

}

 

7.定義圖片大小限制

 

加載的單張圖片通常建議不超過30KB,避免大圖片加載時間長而阻塞頁面其餘資源的下載,所以推薦在10KB之內。若是用戶上傳的圖片過大,建議設置告警系統,幫助咱們觀察瞭解整個網站的圖片流量狀況,作出進一步的改善。

 

4、腳本類

 

1.儘可能使用id選擇器

 

選擇頁面DOM元素時儘可能使用id選擇器,由於id選擇器速度最快。

 

2.合理緩存DOM對象

 

對於須要重複使用的DOM對象,要優先設置緩存變量,避免每次使用時都要從整個DOM樹中從新查找。

 

// 不推薦

$('#mod .active').remove('active');

$('#mod .not-active').addClass('active');

 

// 推薦

let $mod = $('#mod');

$mod.find('.active').remove('active');

$mod.find('.not-active').addClass('active');

 

3.頁面元素儘可能使用事件代理,避免直接事件綁定

 

使用事件代理能夠避免對每一個元素都進行綁定,而且能夠避免出現內存泄露及須要動態添加元素的事件綁定問題,因此儘可能不要直接使用事件綁定。

 

// 不推薦

$('.btn').on('click', function(e){

    console.log(this);

});

 

// 推薦

$('body').on('click', '.btn', function(e){

    console.log(this);

});

 

4.使用touchstart代替click

 

因爲移動端屏幕的設計,touchstart事件和click事件觸發時間之間存在300毫秒的延時,因此在頁面中沒有實現touchmove滾動處理的狀況下,可使用touchstart事件來代替元素的click事件,加快頁面點擊的響應速度,提升用戶體驗。但同時咱們也要注意頁面重疊元素touch動做的點擊穿透問題。

 

// 不推薦

$('body').on('click', '.btn', function(e){

    console.log(this);

});

 

// 推薦

$('body').on('touchstart', '.btn', function(e){

    console.log(this);

});

 

5.避免touchmove、scroll連續事件處理

 

須要對touchmove、scroll這類可能連續觸發回調的事件設置事件節流,例如設置每隔16ms(60幀的幀間隔爲16.7ms,所以能夠合理地設置爲16ms)才進行一次事件處理,避免頻繁的事件調用致使移動端頁面卡頓。

 

// 不推薦

$('.scroller').on('touchmove', '.btn', function(e){

    console.log(this);

});

 

// 推薦

$('.scroller').on('touchmove', '.btn', function(e){

    let self = this;

    setTimeout(function(){

        console.log(self);

    }, 16);

});

 

6.避免使用eval、with,使用join代替鏈接符+,推薦使用ECMAScript 6的字符串模板

 

這些都是一些基礎的安全腳本編寫問題,儘量使用較高效率的特性來完成這些操做,避免不規範或不安全的寫法。

 

7.儘可能使用ECMAScript 6+的特性來編程

 

ECMAScript 6+必定程度上更加安全高效,並且部分特性執行速度更快,也是將來規範的須要,因此推薦使用ECMAScript 6+的新特性來完成後面的開發。

 

5、渲染類

 

1.使用Viewport固定屏幕渲染,能夠加速頁面渲染內容

 

通常認爲,在移動端設置Viewport能夠加速頁面的渲染,同時能夠避免縮放致使頁面重排重繪。在移動端固定Viewport設置的方法以下。

 

<!-- 設置viewport不縮放 -->

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

 

2.避免各類形式重排重繪

 

頁面的重排重繪很耗性能,因此必定要儘量減小頁面的重排重繪,例如頁面圖片大小變化、元素位置變化等這些狀況都會致使重排重繪。

 

3.使用CSS3動畫,開啓GPU加速

 

使用CSS3動畫時能夠設置transform: translateZ(0)來開啓移動設備瀏覽器的GPU圖形處理加速,讓動畫過程更加流暢。

 

-webkit-transform: translateZ(0);

-ms-transform: translateZ(0);

-o-transform: translateZ(0);

transform: translateZ(0);

 

4.合理使用Canvas和requestAnimationFrame

 

選擇Canvas或requestAnimationFrame等更高效的動畫實現方式,儘可能避免使用setTimeout、setInterval等方式來直接處理連續動畫。

 

5.SVG代替圖片

 

部分狀況下能夠考慮使用SVG代替圖片實現動畫,由於使用SVG格式內容更小,並且SVG DOM結構方便調整。

 

6.不濫用float

 

在DOM渲染樹生成後的佈局渲染階段,使用float的元素佈局計算比較耗性能,因此儘可能減小float的使用,推薦使用固定佈局或flex-box彈性佈局的方式來實現頁面元素佈局。

 

7.不濫用web字體或過多font-size聲明

 

過多的font-size聲明會增長字體的大小計算,並且也沒有必要的。

 

6、架構協議類

 

1.嘗試使用SPDY和HTTP 2

 

在條件容許的狀況下能夠考慮使用SPDY協議來進行文件資源傳輸,利用鏈接複用加快傳輸過程,縮短資源加載時間。HTTP 2在將來也是能夠考慮嘗試的。

 

2.使用後端數據渲染

 

使用後端數據渲染的方式能夠加快頁面內容的渲染展現,避免空白頁面的出現,同時能夠解決移動端頁面SEO的問題。若是條件容許,後端數據渲染是一個很不錯的實踐思路。後面的章節會詳細介紹後端數據渲染的相關內容。

 

3.使用Native View代替DOM的性能劣勢

 

能夠嘗試使用Native View的MNV開發模式來避免HTML DOM性能慢的問題,目前使用MNV的開發模式已經能夠將頁面內容渲染體驗作到接近客戶端Native應用的體驗了。

 

關於頁面優化的經常使用技術手段和思路主要包括以上這些,儘管列舉出不少,但仍可能有少數遺漏,可見前端性能優化不是一件簡簡單單的事情,其涉及的內容不少。你們能夠根據實際狀況將這些方法應用到本身的項目當中,要想所有作到幾乎是不可能的,但作到用戶可接受的原則仍是很容易實現的。

 

於此同時咱們要清楚的是,在咱們作到了極致優化的同時也付出了很大的代價,這也是前端優化的一個問題。理論上這些優化都是能夠實現的,可是做爲工程師咱們也要明白懂得權衡。優化提高了用戶體驗,使數據加載更快,可是項目代碼卻可能打亂,異步內容要拆分出來,首屏的一個雪碧圖可能要分紅兩個,頁面項目代碼維護成本成倍增長,項目結構也可能變得混亂。

 

因此前期在設計構建、組件的解決方案時要解決好異步的自動處理問題。任何一部分優化均可以作得很深刻,但不必定都值得,在優化的同時也要儘可能考慮性價比,這纔是咱們做爲一名前端工程師處理前端優化時應該具備的正確思惟。

相關文章
相關標籤/搜索