7

我有静态图像 500x640 坐在由 20x20 块和 css 精灵组成的文件夹中,我正在设置背景位置来显示每一块,我需要这种显示以便以后能够对每一块进行操作。

CSS:

   .piece
        {
            width: 20px;
            height: 20px;
            display: inline-block;
            //display: inline;
            //zoom:1;
        }        

    .ob { background-image: url("/Images/ob.jpg");}

js:

<script id="flipTemplate" type="text/html">
    <div class="piece ob" data-bind="style: { backgroundPosition: viewModel.getLeftValue($index) + ' ' + viewModel.getTopValue($index) }, attr: {cond: Cond, id: Id }, click: viewModel.setClick ">
                </div>
</script>
<script type="text/javascript">
    viewModel = {
        flips: ko.observableArray([]),      

        setClick: function (data, e) {
            e.preventDefault();            
            //doing click
        },

        getLeftValue: function (index) {

            var position = 0;

            var currentLine = div(index(), 25);

            if (currentLine > 0)
                return '-' + (index() - (currentLine * 25)) * 20 + 'px';
            else
                return '-' + index() * 20 + 'px';
        },

        getTopValue: function (index) {

            return '-' + (div(index(), 25)) * 20 + 'px';
        }
    };    

    ko.applyBindings(viewModel);
</script>
function div(val, by){
    return (val - val % by) / by;
}

所以我有一些性能问题。例如,在 Opera 和 FF 图像中加载非常快,大约 1 秒,在 IE 中大约 3 秒,但在 Chrome 中加载非常慢在此处输入图像描述

在 Chrome 中显示所有部分大约需要 17 秒...

浏览器只执行一个请求来获取图像而不是从中切割小块,为什么在 Chrome 中可能需要这么长时间?

有什么办法可以提高性能吗? 在此处输入图像描述

刚刚做了 CTRL+Refresh 和这里奇怪的加载结果: 在此处输入图像描述

更新:我刚刚在这里放了一个样本:http: //bit.ly/TrcCdp

更新: 在我的示例中有 JSON 数组,它包含 800 个元素,所以我只是找出如果我减少它,例如 600-700 个元素,性能会越来越好,但无论如何我需要 800 个元素。

例如,当只有 600 个元素时,它会将 Chrome 中的负载减少到大约 6 秒....

所以可能是淘汰迭代模板的某个地方的问题?

4

3 回答 3

4

问题不在于图像。可以通过在顶部任何样式表或脚本标记之前放置预加载来修复图像:

<meta name="viewport" content="width=device-width">

<script type="text/javascript">
    var img = new Image();
    img.src = 'TestApp_files/obm000.jpg';
</script>

<link href="TestApp_files/jquery00.css" rel="stylesheet">
<link href="TestApp_files/jquery01.css" rel="stylesheet">
<!-- ad nauseum -->

在此之后,图像在 170 毫秒(本地)内加载。然而,在试图决定要做什么之后,该页面仍然会再混乱 10 到 15 秒。

根本问题是javascript绝对是一团糟。图像/文件/函数名称是神秘的。页面中间的东西取决于末尾的代码取决于开头的代码取决于末尾的代码。控制器/视图/模型逻辑遍布地图。全局变量和多文件耦合...呵呵</soapbox>,现在开始治疗症状。

问题 1:在 DOM 加载之前绑定敲除

将 applyBindings 放入 domready 回调中:

jQuery(function($) {
   ko.applyBindings(viewModel);
});

问题2:foreach很慢

对于大型数据集,淘汰赛 foreach 绑定非常慢。您可以尝试使用 jQuery 模板并在模板中移动 foreach,如此 SO question 中所述。它似乎将时间缩短到大约 3 秒。

我真的不明白为什么这是必要的,因为它似乎与您当前的 foreach 渲染得很好,它只是永远挂起,而淘汰赛在后台做了一些魔术,据我所知,在 foreach 完成后发生。

旁注:是否有必要将翻转放入可观察数组?我假设您打算稍后使用它,因为当前代码中不需要它。如果没有,请将其取出,它将有助于提高性能(尽管它不会解决此问题)。

干杯,我希望这会有所帮助。

于 2012-08-29T17:23:08.150 回答
2

foreach这是绑定和 Chrome之间的某种奇怪的渲染错误。我尝试在模板中添加一个字符,然后div修复延迟(但也搞砸了布局)。

解决此问题的一个好方法是使用foreach. 我的repeat绑定在这里运行良好,解决了延迟问题。

这是您使用的代码部分repeat

<div class="condListHolder" style="width:558px">
    <div class="cond2" title="Click to flip" data-bind="repeat: flips">
        <div class="piece obm" data-bind="
          style: { backgroundPosition: getLeftValue($index) + ' ' + getTopValue($index) },
          attr: {cond: $item().cond, id: $item().Id },
          click: setClick "></div>
    </div>
</div>

因为repeat不使用可观察的 for $index,所以您还需要更改您的getTopValueandgetLeftValue函数以取出 之后的()括号index

于 2012-08-29T23:23:54.567 回答
1

You should also look into streamlining your code that is called by the foreach loop. I don't know how often you call the getLeftValue and getTopValue methods but they are pretty unoptimized.

  • Try limiting function calls that give you the same result, use local vars to cache since they are cheap
  • don't concatenate strings in large loops, this is way slower than using an array to join them.

I tried optimizing your two functions. You should see at least some improvement:

getLeftValue: function (index) {

    var position = 0,
        realIndex = index(),
        currentLine = div(realIndex, 25);


    if (currentLine > 0)
        return ["-", (realIndex - (currentLine * 25)) * 20, "px"].join("");
    else
        return ["-", realIndex, "px"].join("");
},

getTopValue: function (index) {

    return ["-",(div(index(), 25)) * 20,"px"].join("");
}
于 2012-08-30T08:16:11.593 回答