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端方法如下:


  
  $.connection.hub.url = _url; // 服务器端口地址
  const hub = . c o n n e c t i o n . l a y o u t D a t a H u b 1 ; / / 定 义 连 接 池 对 象     h u b . c l i e n t . g e t A l e r t I n f o L i s t = f u n c t i o n ( m e s s a g e ) / / 定 义 执 行 函 数 , 根 据 推 送 得 到 的 数 据 结 果 , 渲 染 看 板 效 果     .connection.layoutDataHub1; // 定义连接池对象   hub.client.getAlertInfoList = function (message) {} // 定义执行函数,根据推送得到的数据结果,渲染看板效果    .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

猜你喜欢

转载自blog.csdn.net/qq_26642611/article/details/108466132