iteye_75
2011-09-29 18:18 阅读 355

javascript string.format效率问题

Extjs在机器较差的系统上的性能真是个问题,现在的业务大概是这样的:
有一个编辑表格,当我编辑一个单元格时,需要影响到其他几个单元格,以及统计行信息。
这个操作在机器较差的IE7、IE8下执行时间竟然差不多10s左右,firefox和chrome没有问题,基本上2-3s。
请看截图:

[img]http://dl.iteye.com/upload/attachment/562661/f7cdd017-1d98-33e4-a0d0-f41c18bb1d2b.jpg[/img]

使用IE自带的探查器分析了下,发现主要就是这个string.format执行了太长的时间。
其实现如下:
[code="java"]
format : function(format){
var args = Ext.toArray(arguments, 1);
return format.replace(/{(\d+)}/g, function(m, i){
return args[i];
});
}
[/code]
网上查询了下,确实是有存在性能问题。
主要参考:http://blog.csdn.net/hax/article/details/1416692

他提供的这个确实看不懂。同时我们的替代符是{1}、{2}这样的,也有点不一样。
不知道有谁遇到相关的问题没有,能否提供点建议。

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

8条回答 默认 最新

  • 已采纳
    cyrilluce cyrilluce 2011-09-30 12:18

    做个补丁吧,我也想不通为什么Ext3.3会越改越挫

    [code="js"]
    Ext.override(Ext.grid.GridView, {
    getColumnStyle : function(colIndex, isHeader) {
    var colModel = this.cm,
    colConfig = colModel.config,
    style = isHeader ? '' : colConfig[colIndex].css || '',
    align = colConfig[colIndex].align;

        //style += String.format("width: {0};", this.getColumnWidth(colIndex));
        style += "width: " + this.getColumnWidth(colIndex) + ";";
    
        if (colModel.isHidden(colIndex)) {
            style += 'display: none; ';
        }
    
        if (align) {
            // style += String.format("text-align: {0};", align);
            style += "text-align: " + align + ";";
        }
    
        return style;
    }
    

    });
    [/code]

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2011-09-30 09:20

    你用format转换的数据量很大吗?这样的话建议使用Ext.XTemplate,它是会“预编译”的,即将含占位符的字符串解析,生成js代码,放入函数中,这样后面执行就和你手写拼接一样了。

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2011-09-30 11:06

    ...你的Grid有252列?!
    这个。。。太BT了
    另外,你用的Ext是什么版本?我看3.1是没有用format的

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2011-09-30 13:11

    在我看来,你一心一意去优化String.format是找错目标了,我也无能为力;它用起来是很方便,但为了性能必须避免大量调用

    format性能很难提升了,它用到了正则,又有多次函数调用,这都省不掉,也没有更高性能的实现方法了。
    倒是toArray写成inline形式可能会有一点点提升

    你现在要做的优化是:[b]提升getColumnData接口的性能[/b]。因为它会遍历你的200多列的bt grid。
    或者可以考虑将columnData缓存起来,在ColumnModel有变动时通知作废,以便下次取时更新。

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2011-09-30 13:17

    呃。。。另外有个建议,刚才搞忘了
    你这里是一次更新了14行记录,说真的,一行行地更新总的效率太低了,更别说这个Ext版本以及你的列数原因,导致每行更新getColumnData成本不下于dom更新。

    我碰到这种问题的做法是,拦截store的事件,批量修改完后,再发出datachanged事件:
    [code="js"]
    store.suspendEvents();
    store.getAt(i).set("test", "test");
    ...
    store.resumeEvents();
    store.fireEvent("datachanged", store);
    [/code]
    这样就只会有一次完整更新了。

    如果grid的行数很多,考虑换成BufferView。
    另如果有滚动条,还要考虑改造datachanged事件加个参数,或创建一个全新事件,用于只更新数据[b]不重置滚动条[/b](当然GridView也要修改)

    意见就这么多,怎么选看你的了

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2011-09-30 13:20

    既然你用了Ext3.x,就不要考虑升级了。。。Ext4.x改动太大了,升级的工作量还不如重新写。

    我们现在还一直用的是Ext3.1呢,自己打补丁、加功能,目前来说够用了。

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2011-09-30 14:21

    没用过多表头,给不了建议

    另外,你改14个列那更应该优化了,本来就只应该更新一次的,结果进行了14次update。。。。
    如果是一条记录,用批量编辑:
    [code="js"]
    record.beginEdit();
    record.set(...);
    record.endEdit();
    [/code]

    点赞 评论 复制链接分享
  • cyrilluce cyrilluce 2011-09-30 16:23

    你给store的afterEdit下个断点吧,肯定有其它原因

    点赞 评论 复制链接分享

相关推荐