css動畫滑動不流暢的解決方法:1、將圖片縮放中動畫元素改成transform,避免使用height,width,margin或padding等;2、開啟瀏覽器GPU硬體加速。
本教學操作環境:Windows10系統、CSS3版、DELL G3電腦
css動畫滑動不流暢怎麼辦?
CSS3 動畫卡頓解決方案
前端時間用animation 實現H5 頁面中首頁動畫過渡,很簡單的一個效果,首頁載入一個客服頭像,先放大,停留700ms 後再縮小至頂部。程式碼如下
nbsp;html> <meta> <meta> <script></script> <title>首页加载动画</title> <style> .welcome-main{ display: none; padding-bottom: 40px; } .top-info{ width: 100%; position: absolute; left: 0; top: 93px; } .wec-img{ width: 175px; height: 175px; position: relative; padding: 23px; box-sizing: border-box; margin: 0 auto; } .wec-img:before{ content: ''; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background: url("./images/kf-welcome-loading.png"); background-size: 100%; } .wec-img .img-con{ width: 100%; height: 100%; border-radius: 50%; /*box-sizing: border-box;*/ background: url("./images/kf_1.jpg"); background-size: 100%; padding: 1px; } .wec-img .img-con img{ width: 100%; height: 100%; border-radius: 50%; } .loaded .wec-img{ -webkit-transform-origin: center top; } .loading.welcome-main{ display: block; } .loading .wec-img{ -webkit-animation:fadeIn .3s ease both; } .loading .wec-img:before{ -webkit-animation:rotate .6s .2s linear both; } .loaded .top-info{ -webkit-animation:mainpadding 1s 0s ease both; } .loaded .wec-img{ -webkit-animation:imgSmall 1s 0s ease both; } @-webkit-keyframes mainpadding{ 0%{-webkit-transform:translateY(0) } 100%{-webkit-transform:translateY(-87px) } } @-webkit-keyframes imgSmall{ 0%{ width: 175px; height: 175px; padding: 23px; } 100%{ width: 60px; height: 60px; padding: 0; } } @-webkit-keyframes fadeIn{ 0%{opacity:0;-webkit-transform:scale(.3)} 100%{opacity:1;-webkit-transform:scale(1)} } @-webkit-keyframes rotate{ 0%{opacity:0;-webkit-transform:rotate(0deg);} 50%{opacity:1;-webkit-transform:rotate(180deg);} 100%{opacity:0;-webkit-transform:rotate(360deg);} } </style> <div> <div> <div><p><img alt="css動畫滑動不流暢怎麼辦" ></p></div> </div> </div> <script> $('.welcome-main').addClass('loading'); setTimeout(function(){ $('.hi.fst').removeClass('loading'); $('.welcome-main').addClass('loaded'); },700); </script>
在 chrome 上測試 ok,但在提測給 QA 的時候發現部分機型,如華為(系統4.2),oppo(系統5.1)的出現卡頓狀況。
百思不得其解,後來參考文章深入瀏覽器理解CSS animations 和transitions 的效能問題一文,將圖片縮放中動畫元素改成transform#,如下
@-webkit-keyframes imgSmall{ 0%{ -webkit-transform:scale(1); } 100%{ -webkit-transform:scale(.465); } }
果然啊,卡頓問題解決了。
文章深入瀏覽器理解CSS animations 和transitions 的效能問題是這麼解釋的,現代的瀏覽器通常會有兩個重要的執行線程,這2 個線程協同工作來渲染一個網頁:主線程和合成線程。
一般情況下,主執行緒負責:執行 JavaScript;計算 HTML 元素的 CSS 樣式;頁面的佈局;將元素繪製到一個或多個位圖中;將這些位圖交給合成執行緒。
對應地,合成執行緒負責:透過GPU 將點陣圖繪製到螢幕上;通知主執行緒更新頁面中可見或即將變成可見的部分的點陣圖;計算出頁面中哪部分是可見的;計算出當你在滾動頁面時哪部分是即將變成可見的;當你滾動頁面時將相應位置的元素移動到可視區域。
假設我們想要一個元素的 height 從 100 px 變成 200 px,就像這樣:
div { height: 100px; transition: height 1s linear; } div:hover { height: 200px; }
主執行緒和合成執行緒將按照下面的流程圖執行對應的操作。注意在橘黃色方框的操作可能會比較耗時,在藍色框中的操作是比較快速的。
而使用transform:scale 實作
div { transform: scale(0.5); transition: transform 1s linear; } div:hover { transform: scale(1.0); }
此時流程如下:
# #也就是說,使用transform,瀏覽器只需要一次產生這個元素的點陣圖,並在動畫開始的時候將它提交給GPU 去處理。 之後,瀏覽器不需要再做任何佈局、 繪製以及提交點陣圖的操作。從而,瀏覽器可以充分利用 GPU 的專長快速地將點陣圖繪製在不同的位置、執行旋轉或縮放處理。
為了從數量級上去證實這個理論,我打開chrome 的Timeline 查看頁面FPS 其中,當用height 做動畫元素時,在切換過程的FPS 只有44,我們知道每秒60 幀是最適合人眼的交互,小於60,人眼能明顯感覺到,這就是為什麼卡頓的原因。rendering 和 painting 所花的时间如下:
再来看看用 transform:scale
FPS 达到 66,且 rendering 和 painting 时间减少了 3 倍。
到此为止问题是解决了,隔了几天,看到一篇解决 Chrome 动画”卡顿”的办法,发现还能通过开启硬件加速的方式优化动画,于是又试了一遍。
webkit-transform: translate3d(0,0,0); -moz-transform: translate3d(0,0,0); -ms-transform: translate3d(0,0,0); -o-transform: translate3d(0,0,0); transform: translate3d(0,0,0);
惊人的事情发生了,FPS 达到 72:
尽量使用 transform 当成动画属性,避免使用 height,width,margin,padding 等;
要求较高时,可以开启浏览器开启 GPU 硬件加速。
推荐学习:《css视频教程》
以上是css動畫滑動不流暢怎麼辦的詳細內容。更多資訊請關注PHP中文網其他相關文章!