signalR.js實現實時數據推送(WEB端)以及頁面優化


       數據看板作為一個直觀性較強的實時數據展示平台,在各個行業項目中都極有可能使用到。而作為一個web的初生牛犢,第一次設計制作看板程序,在這個過程中算是踩了不少的坑。下面我將對自己的整個編程經歷分兩點進行總結。

  第一點:實時數據請求

  在進行看板項目編輯初期,由於想法太單純,想着還是采用基本的ajax數據請求技術,每隔幾秒鍾請求一次獲取到新數據,從而對頁面進行數據渲染,所以,在沒有跟后台開發人員進行更加合理的技術探討情況下便開始了看板設計。頁面布局設計完成之后,開始了實時數據請求渲染,然而,問題來了。一個看板分了七八個模塊,每隔模塊又是單獨的接口,在面對每隔兩三秒發出一次請求的情況下,終於,系統崩潰了。jquery的ajax請求技術,在每次請求的時候都會創建一個XMLHttpRequest對象,由於接口的堵塞,又導致了數據得不得更新。想着jquery的ajax數據請求有個complete回調函數,不管請求成功與否都會使用設個函數,於是,對代碼進行了修改。demo方式如下:

  function getMessage () {  

    $.ajax({

      url: 'urlAddress',

      type: 'get',

      async: true,

      cache: false,

      dataType: 'json',

      success: function(){},

      error: function(){},

      complete: function (XTR, TS) {

        XTR = null;  // 釋放XMLHttpRequest對象

        setTimeout(getMessage, 3000); // 使用setTimeout代替setInterval

      }

    })

  }

  經過請求代碼的改進,本以為完事了,結果然並卵,經過一段時間之后,頁面卡死,請求通道阻塞。於是度娘一下,了解到了問題的大郅所在。頻繁的請求占用着帶寬,頁面渲染也需要時間,函數執行計算公式也占用着時間,雖然這些時間使用不多,但是數據無法獲取更新,頁面又出現假死狀態。於是便跟后台商量着放棄ajax的實時請求,采用其他方法進行數據獲取。最終,結合編程語言,了解到了signalR的實時數據推送服務。從原來的主動請求變成了被動獲取數據,將前端壓力移交給了后台。

  signalR實時數據推送web端方法如下:

  <script src="js/jquery-1.11.0.js"></script>
  <script src="http://ip:端口/Scripts/jquery.signalR-2.4.1.js"></script>
  <script src="http://ip:端口/signalr/hubs"></script>  <!-- 引用服務器上的signalR和自動生成的代理文件Hubs -->
  
  $.connection.hub.url = _url;  // 服務器端口地址
  const hub = $.connection.layoutDataHub1;  // 定義連接池對象
  hub.client.getAlertInfoList = function (message) {} // 定義執行函數,根據推送得到的數據結果,渲染看板效果
  $.connection.hub.start() // 第一次握手執行方法
    .done(function () { console.log('連接成功!') })
.    fail(function () { console.log('連接失敗!') });
  
  第二: canvas占用GPU
  終於經過對數據獲取的方式改寫,效果明顯有了好轉,但是內存依舊還是增加,通過內存情況分析和canvas技術的了解。過度頻繁的canvas繪制拖占GPU,但是,令人頭疼的是,客戶終端並沒有加顯卡,這就很難受了。對於一個需要大量canvas技術繪圖的數據看板,沒有GPU的性能支持,程序依舊會癱瘓。最后無奈之下,只好去掉canvas,使用div元素進行canvas替換。下面談談canvas性能優化問題:
  1、離頻渲染
  離屏渲染就可以讓我們先把圖片裁剪成想要的尺寸內容保存起來,繪制的時候就可以使用第一種寫法簡單的把圖片放進去就完了:
  // 在離屏 canvas 上繪制   var offscreencanvas = document.createElement('canvas');   // 寬高賦值為想要的圖片尺寸   offscreencanvas.width = dWidth;   offscreencanvas.height = dHeight;   // 裁剪   offscreencanvas.getContext('2d').drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);   // 在視圖canvas中繪制   viewcontext.drawImage(canvas, x, y);
  2、分層畫布
  多個相互重疊的canvas根據變化程度分開渲染,越復雜的場景越適合。
  3、一次性繪制
  繪制操作的性能開銷較高,可以創建一個包含所有線條的路徑,然后通過單個繪制路徑調用進行繪制。
  4、使用requestAnimationFrame執行動畫
  5、清空畫布
  6、減少使用canvas的API


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM