移動端 touchmove高頻事件與requestAnimationFrame的結合最佳化

來源:互聯網
上載者:User

標籤:

移動端最高頻耗記憶體的的操作  莫屬 touchmove 與scroll事件  兩者需要 微觀的 最佳化;

這裡 我們 講述 touchmove;touchmove 事件發生很頻繁,會比螢幕重新整理率快,導致無效的渲染和重繪;

幀數 –顯示裝置通常的重新整理率通常是50~60Hz –1000ms / 60 ≈ 16.6ms(1毫秒的最佳化意味著 6%的效能提升)

瀏覽器對每一幀畫面的渲染工作需要在16毫秒(1秒 / 60 = 16.66毫秒)之內完成 ;如果超過了這個時間限度,頁面的渲染就會出現卡頓效果,也就是常說的jank;我們需要在  正確的時間  做正確的渲染;

 

拖拽的都會寫,先看看效果;

大概瞭解一下 Timeline 查看看渲染情況   舊版如下

 

在看看 幀模式 渲染情況;

那些沒必要的 move 什麼也不需要做;沒必要在16.6毫秒內多餘的event對象計算;

 

關於幀模式:

 

附上原始碼:
 1 function drag(element){   2          3         var startX=0, 4             startY=0, 5             ticking=false, 6             raf, 7             doc=document; 8              9         element.addEventListener("touchstart",function(e){10              11             12                   var e=e||window.event,13                    touchs = e.touches[0];14                   e.preventDefault();       //低端安卓 touch事件 有的導致touchend事件時效  必須開始 就加   e.preventDefault();15                                            // text a ipnut textarea 幾個 等標籤除外   16                                             // ,另外自訂移動端touchstart touchend組合的 hover事件,建議不加這個,不然頁面無法滾動17                                             //touchmove 開始 就加  不然抖動一下,才能touchmove, 然後才正常 尤其早些的 三星   系列內建瀏覽器18                                               19                20                    startX=parseInt(touchs.pageX-(element.lefts||0));21                    startY=parseInt(touchs.pageY-(element.tops||0));22                   23                    doc.addEventListener("touchmove",update,false);24                    doc.addEventListener("touchend",end,false);25                             26         },false);27         28         29         30         31         32         var  update=function (e) {33              34                var e=e||window.event;35                if (e.touches.length > 1 || e.scale && e.scale !== 1) return;36                 e.preventDefault();37                38                //cancelAnimationFrame(raf);39                if(!ticking) {40 41                var touchs = e.changedTouches[0];42                    43                  //1先觸摸移動  44                     element.lefts = touchs.pageX - startX;45                     element.tops = touchs.pageY - startY;46                    47                  //2交給requestAnimationFrame 更新位置48                 //raf=requestAnimationFrame(function(){draw();});49                  raf=requestAnimationFrame(draw);50 51                 }52               53                  ticking = true;54            };55         56          57          58          59          var draw= function  (){       60                   ticking = false;61                   var nowLeft=parseInt(element.lefts);    //滑動的距離             touchmove時候,如果加阻力,可能有細小的抖動;我想應該是移動端 部分支援0.5px的緣故; parseInt的轉化有點牽強;62                   var  nowTop=parseInt (element.tops);    //滑動的距離    63                      64                     element.style.webkitTransform=element.style.transform = "translate3D(" + nowLeft + "px," + nowTop + "px,0px)";65                     66               };67                    68         var end=function(){69                      var endLeft= parseInt(element.lefts);    //滑動的距離    70                      var  endTop= parseInt(element.tops);    //滑動的距離71                     72                      //element.style.webkitTransform=element.style.transform = "translate(" + endLeft+ "px," + endTop + "px)"; 73     74                         doc.removeEventListener("touchmove",update,false);75                         doc.removeEventListener("touchend",end,false);76                         // cancelAnimationFrame(raf);77                          78             }79                 80      };81      
注意點:RequestAnimationFrame的相容
;(function(){var lastTime=0;var vendors=["ms","moz","webkit","o"];for(var x=0;x<vendors.length&&!window.requestAnimationFrame;++x){window.requestAnimationFrame=window[vendors[x]+"RequestAnimationFrame"];window.cancelAnimationFrame=window[vendors[x]+"CancelAnimationFrame"]||window[vendors[x]+"CancelRequestAnimationFrame"]}if(!window.requestAnimationFrame){window.requestAnimationFrame=function(callback,element){var currTime=new Date().getTime();var timeToCall=Math.max(0,16-(currTime-lastTime));var id=window.setTimeout(function(){callback(currTime+timeToCall)},timeToCall);lastTime=currTime+timeToCall;return id}}if(!window.cancelAnimationFrame){window.cancelAnimationFrame=function(id){clearTimeout(id)}}}());
RequestAnimationFrame的簡易動畫庫 requestAnimationFrame 節流函數
  var rafThrottle=function(fn){ //touchmove  scroll節流     var ticking=false;     var update=function () {         ticking = false;    fn&&fn.apply(this,arguments); } function requestTick() {       if(!ticking) {         requestAnimationFrame(update);        }       ticking = true;     } requestTick();};

  

 

參考網站:

Google開發人員,非常專業:https://developers.google.com/web/fundamentals/getting-started/?hl=zh-cn 需要FQ;

Web前端效能最佳化的微觀分析 http://velocity.oreilly.com.cn/2013/ppts/16_ms_optimization--web_front-end_performance_optimization.pdf

移動端效能調優:ttps://speakerdeck.com/baofen14787/yi-dong-duan-xing-neng-diao-you-ji-16msyou-hua

 

總結:做的東西多了,得 整理一下以;

移動端 scroll,touchmove的事件用的還是比較多的;有時間還是要 細細最佳化的;雖然感覺很微觀 ,甚至覺得 最佳化的幾乎看不出來;但是你去最佳化好,還是費不少時間 的;

requestAnimationFrame是個移動端的利器;動畫盡量用它或者除集合css3實現;

 

移動端 touchmove高頻事件與requestAnimationFrame的結合最佳化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.