ExtJS5: Пользовательский компонент (тикер), увеличивающий циклы ЦП в 10 раз

Я использую компонент тикера в своем приложении. Когда текст катится, циклы процессора достигают 10+. Как только я навожу курсор на него, прокрутка останавливается, а циклы процессора сбрасываются до 0.

Может кто-нибудь сказать, нормально ли это? Если нет, то как я могу заставить этот компонент использовать меньше циклов процессора?

Вот код тикера:

Ext.define('MyApp.ux.Ticker', {
    extend: 'Ext.Component',
    xtype: 'ticker',
    baseCls: 'x-ticker',
    autoEl: {
        tag: 'div',
        cls: 'x-ticker-wrap',
        children: {
            tag: 'div',
            cls: 'x-ticker-body'
        }
    },
    body: null,


    constructor: function (config) {
        Ext.applyIf(config, {
            direction: 'left',
            speed: 10,
            pauseOnHover: true
        });
        if (config.speed < 1) config.speed = 1;
        else if (config.speed > 20) config.speed = 20;


        Ext.applyIf(config, {
            refreshInterval: parseInt(10 / config.speed * 15)
        });
        config.unitIncrement = 1;


        this.callParent([config]);
    },


    afterRender: function () {
        this.body = this.el.first('.x-ticker-body');
        this.body.addCls(this.direction);


        this.taskCfg = {
            interval: this.refreshInterval,
            scope: this
        };


        var posInfo, body = this.body;
        switch (this.direction) {
            case "left":
            case "right":
                posInfo = { left: body.getWidth() };
                this.taskCfg.run = this.scroll.horz;
                break;
            case "up":
            case "down":
                posInfo = { top: body.getHeight() };
                this.taskCfg.run = this.scroll.vert;
                break;
        }
        posInfo.position = 'relative';


        body.setPositioning(posInfo);
        DHT.ux.Ticker.superclass.afterRender.call(this);


        if (this.pauseOnHover) {
            this.el.on('mouseover', this.onMouseOver, this);
            this.el.on('mouseout', this.onMouseOut, this);
            this.el.on('click', this.onMouseClick, this);
        }


        this.task = Ext.apply({}, this.taskCfg);
        Ext.util.TaskManager.start(this.task);
    },


    add: function (o) {
        var dom = Ext.DomHelper.createDom(o);        
        this.body.appendChild(Ext.fly(dom).addCls('x-ticker-item').addCls(this.direction));
    },


    onDestroy: function () {
        if (this.task) {
            Ext.util.TaskManager.stop(this.task);
        }


        DHT.ux.Ticker.superclass.onDestroy.call(this);
    },


    onMouseOver: function () {
        if (this.task) {
            Ext.util.TaskManager.stop(this.task);
            delete this.task;
        }
    },


    onMouseClick: function (e, t, o) {
        var item = Ext.fly(t).up('.x-ticker-item');
        if (item) {
            this.fireEvent('itemclick', item, e, t, o);
        }
    },


    onMouseOut: function () {
        if (!this.task) {
            this.task = Ext.apply({}, this.taskCfg);
            Ext.util.TaskManager.start(this.task);
        }
    },


    scroll: {
        horz: function () {
            var body = this.body;
            var bodyLeft = body.getLeft(true);
            if (this.direction == 'left') {
                var bodyWidth = body.getWidth();
                if (bodyLeft <= -bodyWidth) {
                    bodyLeft = this.el.getWidth(true);
                } else {
                    bodyLeft -= this.unitIncrement;
                }
            } else {
                var elWidth = this.el.getWidth(true);
                if (bodyLeft >= elWidth) {
                    bodyLeft = -body.getWidth(true);
                } else {
                    bodyLeft += this.unitIncrement;
                }
            }
            body.setLeft(bodyLeft);
        },


        vert: function () {
            var body = this.body;
            var bodyTop = body.getTop(true);
            if (this.direction == 'up') {
                var bodyHeight = body.getHeight(true);
                if (bodyTop <= -bodyHeight) {
                    bodyTop = this.el.getHeight(true);
                } else {
                    bodyTop -= this.unitIncrement;
                }
            } else {
                var elHeight = this.el.getHeight(true);
                if (bodyTop >= elHeight) {
                    bodyTop = -body.getHeight(true);
                } else {
                    bodyTop += this.unitIncrement;
                }
            }
            body.setTop(bodyTop);
        }
    }
});

И вот как я его использую:

{
                    xtype: 'panel',
                    border: false,
                    height: 40,
                    width: 256,
                    layout: {
                        type: 'hbox',
                        align: 'stretch'
                    },
                    items: [{
                        width: 200,
                        direction: 'left',
                        xtype: 'ticker',
                        itemId: 'rollerPanel'
                    }],
                    listeners: {
                        afterrender: function (panel) {
                            var ticker = panel.down('ticker');
                            ticker.add({
                                tag: 'div',
                                cls: 'title',
                                html: "Ticker content."
                            });
                        }
                    }
                }

Что не так с приведенным выше кодом? Что может быть причиной более высокой загрузки процессора?


person user1640256    schedule 03.11.2014    source источник
comment
Из моего опыта - операции dom потребляют процессор. IMO, вы можете уменьшить накладные расходы, используя больше CSS. Может быть, попробуйте position: fixed, тогда вы сможете удалить некоторый код из обработчика прокрутки.   -  person Krzysztof    schedule 26.11.2014


Ответы (1)


Инструменты разработчика Chrome помогут вам профилировать это, но не помешает кэшировать некоторые вещи, такие как ширина/высота тела и элементов, чтобы вы читали их только при запуске, а не на каждом тике.

person Colin Ramsay    schedule 08.12.2014