首頁 >web前端 >css教學 >關於CSS中的動畫屬性效能的圖文代碼介紹

關於CSS中的動畫屬性效能的圖文代碼介紹

黄舟
黄舟原創
2017-07-18 13:39:361501瀏覽


CSS動畫屬性會觸發整個頁面的重排relayout、重繪repaint、重組recomposite

Paint通常是其中最花費效能的,盡可能避免使用觸發paint的CSS動畫屬性,這也是為什麼我們推薦在CSS動畫中使用 webkit-transform: translateX(3em) 的方案代替使用 left: 3em ,因為left會額外觸發layout與paint,而webkit-transform則只觸發整個頁面composite

    p {
      -webkit-animation-duration: 5s;
      -webkit-animation-name: move;
      -webkit-animation-iteration-count: infinite;
      -webkit-animation-direction: alternate;
      width: 200px;
      height: 200px;
      margin: 100px;
      background-color: #808080;
      position: absolute;
    }


    @-webkit-keyframes move{
        from {
            left: 100px;
        }
        to {
            left: 200px;
        }
    }

    如下圖使用left將持續觸發頁面重繪,表現為紅色邊框:

    關於CSS中的動畫屬性效能的圖文代碼介紹

    @-webkit-keyframes move{
        from {
            -webkit-transform: translateX(100px);
        }
        to {
            -webkit-transform: translateX(200px);
        }
    }

    如下圖使用-webkit-transform頁面只會發生重組,表現為橘色邊框:

    關於CSS中的動畫屬性效能的圖文代碼介紹

  • #CSS屬性在CSS動畫中行為表

  • 關於CSS中的動畫屬性效能的圖文代碼介紹

    高效能CSS3 動畫

    高效能行動Web相較PC的場景需要考慮的因素也相對更多更複雜,我們總結為以下幾點: 流量、功耗與流暢度。 在PC時代我們更多的是考慮體驗上的流暢度,而在Mobile端本身豐富的場景下,需要額外關注對用戶基地台網路流量使用的情況,設備耗電量的情況。

    關於流暢度,主要體現在前端動畫中,在現有的前端動畫體系中,通常有兩種模式:JS動畫與CSS3動畫。 JS動畫是透過JS動態改寫樣式實現動畫能力的一種方案,在PC端相容低端瀏覽器中不失為一種推薦方案。 而在行動端,我們選擇效能更優瀏覽器原生實作方案:CSS3動畫。

    然而,CSS3動畫在行動多終端裝置場景下,相較於PC會面對更多的效能問題,主要體現在動畫的卡頓與閃爍。

    目前對提升行動端CSS3動畫體驗的主要方法有幾點:

    盡可能多的利用硬體能力,如使用3D變形來開啟GPU加速

    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    -ms-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);

    #如動畫過程有閃爍(通常發生在動畫開始的時候),可以嘗試下面的Hack:

    -webkit-backface-visibility: hidden;
    -moz-backface-visibility: hidden;
    -ms-backface-visibility: hidden;
    backface-visibility: hidden;
     
    -webkit-perspective: 1000;
    -moz-perspective: 1000;
    -ms-perspective: 1000;
    perspective: 1000;

     如下面一個元素通過translate3d右移500px的動畫流暢度會明顯優於使用left屬性:

    #ball-1 {
      transition: -webkit-transform .5s ease;
      -webkit-transform: translate3d(0, 0, 0);
    }
    #ball-1.slidein {
      -webkit-transform: translate3d(500px, 0, 0);
    }
     
     
    #ball-2 {
      transition: left .5s ease;
      left: 0;
    }
    #ball-2.slidein {
      left: 500px;
    }

    註:3D變形會消耗更多的記憶體與功耗,應確實有效能問題時才去使用它,兼在權衡

    盡可能少的使用box- shadows與gradients

    box-shadows與gradients往往都是頁面的效能殺手,尤其是在一個元素同時都使用了它們,所以擁抱扁平化設計吧。

    盡可能的讓動畫元素不在文件流中,以減少重排

    position: fixed;
    position: absolute;

    優化DOM layout 效能

    我們從實例開始描述這個主題:

    var newWidth = ap.offsetWidth + 10;
    ap.style.width = newWidth + 'px';
    var newHeight = ap.offsetHeight + 10;
    ap.style.height = newHeight + 'px';
     
    var newWidth = ap.offsetWidth + 10;
    var newHeight = ap.offsetHeight + 10;
    ap.style.width = newWidth + 'px';
    ap.style.height = newHeight + 'px';

     這是兩段能力上完全等同的程式碼,顯式的差異如我們所見,只有執行順序的差異。但真是如此嗎?以下是加了說明註解的程式碼版本,很好的闡述了其中的進一步差異:

    // 触发两次 layout
    var newWidth = ap.offsetWidth + 10;   // Read
    ap.style.width = newWidth + 'px';     // Write
    var newHeight = ap.offsetHeight + 10; // Read
    ap.style.height = newHeight + 'px';   // Write
     
    // 只触发一次 layout
    var newWidth = ap.offsetWidth + 10;   // Read
    var newHeight = ap.offsetHeight + 10; // Read
    ap.style.width = newWidth + 'px';     // Write
    ap.style.height = newHeight + 'px';   // Write

     從註解中可找到規律,連續的讀取offsetWidth/Height屬性與連續的設定width/height屬性,相較於分別讀取設定單一屬性可少觸發一次layout。

    從結論看似乎跟執行佇列有關,沒錯,這是瀏覽器的最佳化策略。所有可觸發layout的操作都會被暫時放入 layout-queue 中,等到必須更新的時候,再計算整個隊列中所有操作影響的結果,如此就可只進行一次的layout,從而提升性能。

    關鍵一,可觸發layout的操作,哪些操作下會layout的更新(也稱為reflow或relayout)?

    我們從瀏覽器的原始碼實現入手,以開源Webkit/Blink為例, 對layout的更新,Webkit 主要透過 Document::updateLayout 與Document::updateLayoutIgnorePendingStylesheetsheets#rrr##o#o#rrr# # 從 updateLayoutIgnorePendingStylesheets 方法的內部實現可知,其也是對 updateLayout 方法的擴展,並且在現有的layout 更新模式中,大部分場景都是調用layout的更新。

以上是關於CSS中的動畫屬性效能的圖文代碼介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn