• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
    問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
    當前位置: 首頁 - 科技 - 知識百科 - 正文

    高性能CSS3動畫-1565783227

    來源:懂視網 責編:小采 時間:2020-11-27 16:43:59
    文檔

    高性能CSS3動畫-1565783227

    高性能CSS3動畫-1565783227:注:本文出自騰訊AlloyTeam的元彥,文章也可以在github上瀏覽。請尊重版權,轉載請注明來源,多謝~~ 高性能移動Web相較PC的場景需要考慮的因素也相對更多更復雜,我們總結為以下幾點: 流量、功耗與流暢度。 在PC時代我們更多的是考慮體驗上的流暢度,而在
    推薦度:
    導讀高性能CSS3動畫-1565783227:注:本文出自騰訊AlloyTeam的元彥,文章也可以在github上瀏覽。請尊重版權,轉載請注明來源,多謝~~ 高性能移動Web相較PC的場景需要考慮的因素也相對更多更復雜,我們總結為以下幾點: 流量、功耗與流暢度。 在PC時代我們更多的是考慮體驗上的流暢度,而在

    注:本文出自騰訊AlloyTeam的元彥,文章也可以在github上瀏覽。請尊重版權,轉載請注明來源,多謝~~


    高性能移動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-shadowsgradients

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

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

    position: fixed; 
    position: absolute; 
    

    優化 DOM layout 性能

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

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

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

    // 觸發兩次 layout
    var newWidth = aDiv.offsetWidth + 10; // Read 
    aDiv.style.width = newWidth + 'px'; // Write 
    var newHeight = aDiv.offsetHeight + 10; // Read 
    aDiv.style.height = newHeight + 'px'; // Write
    
    // 只觸發一次 layout
    var newWidth = aDiv.offsetWidth + 10; // Read 
    var newHeight = aDiv.offsetHeight + 10; // Read 
    aDiv.style.width = newWidth + 'px'; // Write 
    aDiv.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::updateLayoutIgnorePendingStylesheets 兩個方法:

    void Document::updateLayout() 
    {
     ASSERT(isMainThread());
    
     FrameView* frameView = view();
     if (frameView && frameView->isInLayout()) {
     ASSERT_NOT_REACHED();
     return;
     }
    
     if (Element* oe = ownerElement())
     oe->document()->updateLayout();
    
     updateStyleIfNeeded();
    
     StackStats::LayoutCheckPoint layoutCheckPoint;
    
     if (frameView && renderer() && (frameView->layoutPending() || renderer()->needsLayout()))
     frameView->layout();
    
     if (m_focusedNode && !m_didPostCheckFocusedNodeTask) {
     postTask(CheckFocusedNodeTask::create());
     m_didPostCheckFocusedNodeTask = true;
     }
    }
    
    
    void Document::updateLayoutIgnorePendingStylesheets() 
    {
     bool oldIgnore = m_ignorePendingStylesheets;
    
     if (!haveStylesheetsLoaded()) {
     m_ignorePendingStylesheets = true;
    
     HTMLElement* bodyElement = body();
     if (bodyElement && !bodyElement->renderer() && m_pendingSheetLayout == NoLayoutWithPendingSheets) {
     m_pendingSheetLayout = DidLayoutWithPendingSheets;
     styleResolverChanged(RecalcStyleImmediately);
     } else if (m_hasNodesWithPlaceholderStyle)
     recalcStyle(Force);
     }
    
     updateLayout();
    
     m_ignorePendingStylesheets = oldIgnore;
    }

    updateLayoutIgnorePendingStylesheets 方法的內部實現可知,其也是對 updateLayout 方法的擴展,并且在現有的 layout 更新模式中,大部分場景都是調用 updateLayoutIgnorePendingStylesheets 來進行layout的更新。

    搜索 Webkit 實現中調用 updateLayoutIgnorePendingStylesheets 方法的代碼, 得到以下可導致觸發 layout 的操作:

    ======================================
    http://www.100sucai.com/code/2227.html
    http://www.100sucai.com/code/2226.html
    http://www.100sucai.com/code/2225.html
    http://www.100sucai.com/code/2224.html
    ======================================
  • Element: clientHeight, clientLeft, clientTop, clientWidth, focus(), getBoundingClientRect(), getClientRects(), innerText, offsetHeight, offsetLeft, offsetParent, offsetTop, offsetWidth, outerText, scrollByLines(), scrollByPages(), scrollHeight, scrollIntoView(), scrollIntoViewIfNeeded(), scrollLeft, scrollTop, scrollWidth

  • Frame, HTMLImageElement: height, width

  • Range: getBoundingClientRect(), getClientRects()

  • SVGLocatable: computeCTM(), getBBox()

  • SVGTextContent: getCharNumAtPosition(), getComputedTextLength(), getEndPositionOfChar(), getExtentOfChar(), getNumberOfChars(), getRotationOfChar(), getStartPositionOfChar(), getSubStringLength(), selectSubString()

  • SVGUse: instanceRoot

  • window: getComputedStyle(), scrollBy(), scrollTo(), scrollX, scrollY, webkitConvertPointFromNodeToPage(), webkitConvertPointFromPageToNode()

  • 進一步深入Layout,那上文中必須更新的必要條件是什么? 在 Stoyan Stefanov 的 Rendering: repaint, reflow/relayout, restyle 一文中已做比較詳細的解答,可移步了解~

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    高性能CSS3動畫-1565783227

    高性能CSS3動畫-1565783227:注:本文出自騰訊AlloyTeam的元彥,文章也可以在github上瀏覽。請尊重版權,轉載請注明來源,多謝~~ 高性能移動Web相較PC的場景需要考慮的因素也相對更多更復雜,我們總結為以下幾點: 流量、功耗與流暢度。 在PC時代我們更多的是考慮體驗上的流暢度,而在
    推薦度:
    標簽: 動畫 性能 css
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 精品国产自在在线在线观看| 成人国产精品日本在线观看| 真实国产乱子伦精品免费| 亚洲综合无码精品一区二区三区| 亚洲精品福利视频| 日韩精品一区二区三区色欲AV| 精品一久久香蕉国产线看播放| 亚洲精品高清国产一久久| 国产精品三级在线| 国产午夜福利精品一区二区三区| 亚洲av永久无码精品古装片| 全国精品一区二区在线观看| 国产精品无码DVD在线观看| 欧美精品亚洲精品日韩专区va| 精品福利视频一区二区三区| 中文国产成人精品久久不卡| 亚洲国产综合精品中文字幕| 欧美精品亚洲精品日韩专区| 精品国产一级在线观看| 国产午夜精品理论片| 亚洲国产精品久久久久网站| 国产午夜精品理论片久久影视| 第一福利永久视频精品| 国产精品无码AV一区二区三区| 欧美精品v国产精品v日韩精品| 午夜精品久久久久久久| 亚洲中文久久精品无码ww16 | 亚洲国产精品尤物YW在线观看| 久久久精品无码专区不卡| 久久99精品久久久久久9蜜桃| 国产精品福利区一区二区三区四区| 亚洲国产精品久久久久| 99久久精品无码一区二区毛片 | 国产午夜精品理论片免费观看 | 99re8这里有精品热视频免费| 囯产精品一品二区三区| 97久久综合精品久久久综合| 国产精品视频久久久| 亚洲天堂久久精品| 国产乱人伦偷精品视频| 久久无码精品一区二区三区|