CSS Sprites性能

时间:2012-08-28 17:32:20

标签: javascript css performance css-sprites knockout-2.0

我有静态图像500x640坐在20x20件用css sprites拍摄的文件夹中,我设置背景位置来显示每一件,我需要这样的显示器以便能够随后操作每件。

的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中加载非常慢enter image description here

显示Chrome中的所有内容大约需要17秒...

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

有什么方法可以改善表现吗? enter image description here

刚刚做了CTRL + Refresh,这里有奇怪的加载结果: enter image description here

更新: 我刚刚在此处放置了一个示例:http://bit.ly/TrcCdp

更新 在我的示例中有JSON数组,它包含800个元素,所以我只知道如果我减少它,例如600-700个元素,性能越来越好,但我还需要800个元素。

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

所以可能是某些地方的问题,那就是淘汰迭代模板?

3 个答案:

答案 0 :(得分: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 -->

此后,图像加载170ms(本地)。但是,在尝试决定要做什么之后,该页面仍然在另外10-15秒内完成。

根本问题是javascript绝对是一团糟。图像/文件/功能名称含糊不清。页面中间的东西取决于最后的代码取决于开头的代码取决于最后的代码。控制器/视图/模型逻辑遍布地图。全局变量和多文件耦合... hokay,</soapbox>,现在用于治疗症状。

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

将applyBindings放入domready回调中:

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

问题2:foreach很慢

对于大型数据集,淘汰赛foreach绑定非常慢。您可以尝试jQuery模板并将foreach移动到模板as described in this SO question中。它似乎将时间缩短到大约3秒钟。

我真的不明白为什么这是必要的,因为它似乎与你现在的foreach很好地渲染,它只是永远挂起,而击倒在后台做了一些魔术,据我所知,在foreach完成后发生

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

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

答案 1 :(得分:2)

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

解决此问题的一个好方法是使用foreach之外的其他内容。我的repeat binding在这里运作良好,可以解决延迟问题。

以下是使用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不使用$index的可观察对象,因此您还需要更改getTopValuegetLeftValue函数以取出括号{{1在()之后。

答案 2 :(得分:1)

您还应该考虑简化foreach循环调用的代码。我不知道你多久调用一次getLeftValuegetTopValue方法,但它们都没有得到优化。

  • 尝试限制为您提供相同结果的函数调用,使用本地变量进行缓存,因为它们很便宜
  • 不要在大循环中连接字符串,这比使用数组加入它们要慢。

我尝试优化你的两个功能。你应该看到至少一些改进:

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("");
}