HTML5 网络拓扑图性能优化

HTML5 中的 Canvas 对文本的渲染(fillText,strokeText)性能都不太好,好比设置字体(font)、文本旋转(rotation),若是绘制较多的文本时,一些交互操做会手动很大的影响,操做起来没那么顺畅,体验将会极其差,这不是咱们想要的结果,再进一步和图片的绘制进行比较比较,你会发现,绘制图片和绘制文本在性能上不是一个等级的,在性能上绘制图片会好太多。javascript

咱们今天就来谈谈 HT for Web 性能相关的问题。在 HT 中,有不少地方能够设置文本,每一个节点上面均可以设置两个 label 和两个 note 文本,若是全开启的话,绘制一个节点就要附带绘制 4 个文本,假如说绘制 文本的性能消耗是绘制图片性能消耗的 3 倍的话,附带绘制 4 个文本,就想当与多出 12 倍的性能消耗,这节点以多的话,可想而知,不论是哪一个引擎都不可能 hold 得住这样的性能消耗。html

既然绘制文本的性能消耗没法避免,那么咱们要如何提升系统的总体性能呢?换个思路,绘制文本会有高性能消耗,致使操做上面的延迟和卡顿,那么我是否是能够在操做时不绘制文本呢,将文本绘制所消耗的性能节省下来,用在其余的性能消耗上,这样是否是就能够解决操做延迟和卡顿的问题呢?java

咱们不妨来试试,在 GraphView 中添加若干个 node、edge、group 等节点,而且每一个节点上都显示文本(包括线条,上图所示),看看拓扑的缩放效果怎么样。没次缩放都要等上两三秒,性能实在是差得不行,这样的应用确定是不合格的。node

咱们来看看具体的 Demo,连接:http://www.hightopo.com/demo/labelVisible/visible.html。接下来解析下具体代码的实现。浏览器

var init = function() {
    window.matchMedia('screen and (min-resolution: 2dppx)').
        addListener(function() {
            ht.Default.setDevicePixelRatio();
        });

    var g2d = new ht.graph.GraphView(),
        dm = g2d.dm();
    g2d.addToDOM();
    g2d.getLabel = function(data) {
        if (data.s('label'))
            return data.s('label');
        if (data instanceof ht.Edge)
            return 'from:' + data.getSourceAgent().toString() + 
                ' to:' + data.getTargetAgent().toString();
        return data.toString();
    };

    createNodes(dm);

    var autoLayout = new ht.layout.AutoLayout(g2d);
    autoLayout.setAnimate(true);
    autoLayout.layout('symmetric', function() {
        g2d.fitContent(true);
    });

    createFormPane(g2d, autoLayout);
};

上面的代码是页面初始化代码,首先先监听 media 的值变化,防止在不一样的 devicePixelRatio 屏幕中切换 而致使页面不清晰,ht.Default.setDevicePixelRatio() 方法会更新 HT 系统中存放 devicePixelRatio 的变量,而后刷新页面上全部的 HT 组件,这样就能够保证页面必定不会不清晰。网络

接着是常见网络拓扑图 GraphView 组件,并将其添加到 DOM 中,重载 GraphView 的 getLabel 方法设置图元的文本,让每一个节点都有文本。布局

接下来调用 createNodes 方法建立全部的节点,建立完代码后,建立一个 AutoLayout 来自动布局全部节点,自动布局为开发人员节省手动布局的时间,在效率上大大提高,在布局完后,让 GraphView 中的节点自适应屏幕,让全部节点都显示在当前页面中。性能

最后建立一个 FormPane 放在右上角,用于存放几个控制按钮及几个 ComboBox 选择项,可让 GraphView 运行在不一样的布局模式下,同时这些功能也能够用来检测页面性能,在布局的过程当中是否流畅,具体的代码能够经过浏览器的 Sources 查看。字体

文本始终显示的话,在性能上仍是不行的,就如上面所说的,是不合格的。那么我么该如何优化,让性能有质的提高呢?优化

在文章的开头有提到,咱们能够采用在操做交互的过程当中不绘制文本,来提高性能,让页面的呈现更加流畅。那么该怎么实现才能让操做交互过程当中不绘制文本呢?具体 Demo 连接:http://www.hightopo.com/demo/labelVisible/invisible.html。看码:

var state = {};
g2d.isLabelVisible = function(data) {
    return !state.zooming && !state.panning && !state.autoLayout;
};
g2d.onAutoLayoutEnded = function() {
    state.autoLayout = false;
};
g2d.onZoomEnded = function() {
    state.zooming = false;
};
var timer = null;
g2d.mp(function(e) {
    if (e.property === 'zoom') {
        state.zooming = true;
        if (timer)
            clearTimeout(timer);
        timer = setTimeout(function() {
            timer = null;
            state.zooming = false;
            g2d.redraw();
        }, 100);
    }
});
g2d.mi(function(e) {
    if (e.kind === 'beginPan')
        state.panning = true;
    if (e.kind === 'endPan') {
        state.panning = false;
        g2d.redraw();
    }
});

首先 GraphView 提供了 isLabelVisible  的方法,让用户重载自定义文本的显示与否,state 变量是用来标记当前的操做状态,zooming 表明当前的 GraphView正在缩放,panning 表明当前的 GraphView 正在移动整个场景,autoLayout 表明正在作自动布局操做。

GraphView 的 mp(addPropertyChangeListener)方法是监听 GraphView的属性变化,当监听到 zoom 属性变化的时候,将 zooming 状态设置为 true,若是在 zoom 的过程当中没有启动动画的话,就不会触发 onZoomEnded 回调,因此须要本身添加计时器,过段时间将 zooming 状态改掉,而且从新绘制下 GraphView。

GraphView 的 mi(addInteractorListener)方法是监听用户对 GraphView 的操做动做,在监听到 beginPan 时将 panning 状态设置为 true ,在监听到 endPan 是将 panning 状态设置为 false,并重绘 GraphView。

在 FormPane 中的一些操做会对 GraphView 中的节点进行自动布局,所以在 FormPane 中会设置 autoLayout 状态,因为代码比较多,我在这边就贴代码了。咱们来看看,加上上面的代码后,对 GraphView 操做后的效果图:

上图是在缩放 GraphView 时的效果,能够发现全部的文本都不见了,用户操做起来也不会延迟和卡顿了现象,这样用户操做交互的性能问题也就解决了。

相关文章
相关标签/搜索