淺談移動前端性能優化(轉)

隨着Html5的正式定稿,移動前端步入APP世界的步伐也隨之加速。目前主流的兩大手機系統廠商(google、蘋果)都是Html5的參與 者,因此這兩大系統在對html5的支持上基本是沒什麼問題的。然而對於不少開發者來講,也許僅僅是由於使用前的一番可行性分析便放棄這種方案。由於不少 資料都敘述着Html5相比原生App的各類不足。其中最尷尬的一條莫過於「性能」問題。由於這個問題,剛開始接觸的時候我也有很強的抵觸情緒。但後來慢 慢的發現,其實不少時候性能本就不是問題。適當的調整Html和Css,咱們的網頁一樣能夠無限接近原生程序。並且我的認爲,大多數時候程序是否流暢並不是 取決於某種編程語言,而是取決於寫程序的人。相比經過各類代碼填充來完成目標任務,我更喜歡把技術當作藝術,寫代碼也應該有所追求。(扯淡扯遠了。)css

  其實,Html5相比原生App的開發有不少誘人的方面。html

  其一:可快速迭代。 最簡單最直接的一個:IOS程序每次上傳都須要經過漫長的審覈時間,若是趕時間的話這是個問題,並且耐心等待以後未必就能獲得一個咱們想要的結果,審覈不 通也不是不可能。Html5開發完成以後也不用再次上傳審覈。(若與原生程序有交互變動,此項無效)前端

  其二:跨平臺。Html跨平臺的特性早已不是一天兩天的事了。IOS開發完成的同時,Android也基本完成。開發效率和成本上相比原生應用確實有較明顯的優點。html5

  其三:轉發率高。如今打開微信朋友圈就能看到各類分享。如:文章分享,產品分享,XX店鋪等。經過鏈接轉發能夠實現快速分享,提升流量。css3

  談完優點,再說說自身經歷。本是一名老老實實的C#程序員,沒事就學習各類程序優化(sql爲主)的我在幾個月前忽然轉向移動網頁開發。在一個 不算小的團隊裏前端工程師是一枚傳統前端工程師。除能完成簡單的手機佈局外其餘一竅不通,因而乎關於JavaScript、前端性能優化等各類重擔都落到 了我這裏。因爲前端所完成的僅僅是以html的形式展示出效果圖的模樣,不多涉及到性能問題。因而漫長的學習之路由此開始了。程序員

  

  究竟什麼樣的頁面是須要優化的頁面?web

    一、頁面上下滑動時感受卡頓不流暢或是基本不動;sql

    二、動畫效果卡頓,看上去感受一幀一幀的跳動;chrome

  簡單點說,就是感受卡。也許iphone6不卡可是iphone4上會卡,也許iphone上不卡三星上感受卡、魅族、小米、華爲、聯想?國內屌絲機各有個的長相各有各的特點,好比魅族的MX,其餘手機都很正常的時候它就卡。Html兼容一直都不是一件容易的事。編程

  上述問題該如何破?

   解決問題的關鍵在於找到問題的所在。砍柴還得有裝備,工具很重要。之前用chrome,是由於感受這貨比較好使(直到放棄多年來一直鍾愛的IE)。幾個月 前才發現這是一個調試工具也很好使的瀏覽器(簡直就是神器)。其實關於html性能問題,不少博客上都有解釋重繪這個事。下面主要談談如何用chrome 鑑別重繪元素。

    打開chrome,開啓開發者工具(F12)。打開模擬器,並選擇須要模擬的設備,在Console中選擇Rendering 選中第一條(Show paint rectangles)。若打開開發者工具後沒看見下方Console這塊能夠按下Esc。

   完成上述操做後,請將視線移動到左側網頁上的綠色矩形框上。

   

   ps:一直都很喜歡淘寶的廣告,創意從未間斷過。

   這個綠色框就是瀏覽器重繪的部分。這個框越大,說明重繪的區域也就越大。重繪並沒什麼問題,這很正常,不正常的是大面積重繪,好比上圖中的時 間跳動,若是僅僅是時間那個區域重繪並無什麼問題,要是整個頁面都一直閃着個綠框框那就完蛋了。爲什麼大面積重繪會出現性能問題,這個還得從瀏覽器渲染上 談起。那是一個很長的故事,有興趣的朋友能夠找些資料看看。簡單的舉例就是,瀏覽器把html文檔解析成網頁展示到咱們面前,其中間是一個「漫長」的過 程。再載入文檔以後須要對html進行分割、讀取並計算其樣式大小、而後進行圖層繪製、合併圖層等一系列操做。整個過程其實使用最多的部件是CPU和 GPU。

   重繪的面積大小和迴流(reflows)有關,關於迴流其實能夠這樣理解,當改變一個元素後對其它節點元素產生影響。就如同可石子投入水中引 起的波紋同樣,波紋所到之處基本都會有所影響。而在Html中子節點的變化會引發祖先的迴流,同時也會影響到部分兄弟節點,大部分的迴流將致使頁面的從新 渲染。那麼如何下降回流,減少重繪面積呢?淘寶時間不也只更新了一小塊麼!這裏提供兩種方法:

  一、使用 position 屬性的 fixed 值或 absolute 值。

  二、建立獨立的Layer(層)(爲避免和div(層)產生混淆文中儘可能同一使用Layer)。

 

 繼續看淘寶:

   

 

   第一種方法已經很明顯了就再也不贅述。說說第二種方法吧。首先說說在Chrome中如何查看獨立的Layer呢。如上圖,選擇Show composited layer borders後在頁面上獨立的Layer上回顯示一個橘黃色邊框。那麼又要如何才能創建獨立的Layer呢?

   在Chrome中建立獨立的Layer僅須要符合下述條件之一:

    1. 有3D元素的屬性;
    2. video標籤並使用加速視頻解碼;
    3. canvas元素並啓用3D;
    4. 插件,好比flash;
    5. CSS動畫;
    6. CSS濾鏡;
    7. 有一個後代元素是獨立的layer;
    8. 元素的相鄰元素是獨立layer。

   看上去挺多挺複雜的,其實最簡單、最容易理解、也最容易濫用的是第一條。實現第一條僅須要在元素的樣式里加 上:transform:translateZ(0);-webkit-transform:translateZ(0);就能夠了。咱們將淘寶往下滑動 一點,找一個元素試試看。

   仍是看淘寶:

 

 

   當加上css樣式後對應的元素上出現了橘黃色邊框,事實證實這招是有效的。而在Chrome中這樣作能夠啓用GPU硬件加速。初次看到加速兩個字讓人以爲無比興奮,彷彿找到了克敵制勝的無敵神招。但是,首先這是在chrome下,其次大量使用真的好嗎?

   其實就算是在chrome下GPU也未必能排上用場,首先須要肯定你的GPU驅動程序不在chromium的黑名單中。由於某些GPU驅動程序存在錯誤, 可能會影響瀏覽器穩定,因此會被加入到黑名單裏。在chrome地址欄裏輸入about:gpu能夠查看相關的GPU信息。如今再說說GPU加速的事情 吧,簡單點解釋就是經過GPU渲染的Layer,GPU會將圖層信息緩存起來,到下次改變的時候就只須要從新渲染修改過的部分。這樣當然是快,可是會加大 系統RAM和GPU的內存開銷。在配置良莠不齊的移動設備上,過多的層不只不能加速,反而會嚴重影響性能。不少時候咱們在感受到移動網頁較卡的時候不防試 試減小頁面上的Layer試試。

   經過Chrome咱們還能夠鑑別一些其餘影響性能的方面。好比:

  

  上面兩幅圖,左邊一幅是百度.新聞的移動網頁版,箭頭指向的是這個頁面的loading效果(就是一種一直一直轉動的感受)。右邊是之前最經常使用 的一種loading。在效果上兩種方式都同樣,一直不停的轉動。而區別在於右邊的loading是一個帶有背景圖片的div,經過css3使其產生轉動 效果;而右邊則是一張Gif動態圖片。雖然效果上同樣,但在瀏覽其中咱們能夠看到右邊的loading會有一個不停閃動的綠色框(頻率至關高)。gif動 畫會致使瀏覽器不斷的進行繪製、柵格化、合成,整個過程至關影響性能,因此最好乾掉它。

   簡而言之言而簡之:

    一、減小重繪,減少重繪面積(改良佈局,建立獨立的Layer),下降重繪頻率。

    二、合理使用GPU加速,避免過分依賴GPU而致使性能降低。

 

  說完佈局,再簡單談談動畫吧。

   經常使用的JavaScript動畫在移動web上不少時候都顯得愛莫能助(不給力啊)。這個緣由不少,JavaScript動畫一般是經過定時改變元 素樣式屬性的方式來實現,JavaScript的運行是在一個獨立線程裏完成的,做爲單線程程序,JavaScript會由於某個耗時動做而影響下一幀動 畫的執行。並且,JavaScript的定時也並無想象中的那麼守時,如在setinterval中設置每毫秒輸出一個數,當輸出到2000次的時候, 當真就只須要2秒鐘嗎?相比之下更加推薦使用CSS3來完成相關動畫效果。首先Css由獨立線程完成,它和JavaScript的運行並不衝突,其次 Css3不少屬性不會觸發重繪(固然JavaScript裏也能夠是改變的css3的屬性)。從流暢度上來說的話Css3基本上完勝JavaScript,並且操做較容易。關於Css3相關知識就再也不贅述。

  然而Css3的動畫也並無想象中那般完美。

    首先,在動畫控制上不夠靈活,整動畫過程不太好監控。

    其次,其兼容性不太好。僅移動端而言,位移動畫一般使用transform,但在某些瀏覽器中須要使用-webkit-transform(如微信裏的瀏覽器)。

 

  雖然Css3並不是完美解決方案,但實際使用中大多數時候是徹底能夠解決咱們所遇到的問題(遇到複雜問題再解決吧,事在人爲嘛,解決問題也是一種樂趣)。 且目前的移動應用上並不推薦過於複雜的效果設計。

相關文章
相關標籤/搜索