2012-08-28 59 views
7

我有静态图像500x640坐在文件夹由20x20件与CSS精灵捕捉,我设置背景位置来显示每一块,我需要这样的显示,以便能够与每件后操纵。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秒,但在铬它加载很慢enter image description here

它正在约17秒,以显示在浏览器的所有块...

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

有没有什么办法可以提高性能? enter image description here

只是做了CTRL +刷新这里奇怪的装载结果: enter image description here

更新: 我只是放在这里的样本:http://bit.ly/TrcCdp

UPDATE: 在我的样本有JSON数组,它包含800个元素,所以我只是发现是否让它变得更少,例如600-700个元素的性能会越来越好,但无论如何我需要800个元素。

e.g当只有600元是减少在Chrome负荷约6秒....

所以大概可能在某个地方敲除迭代模板​​点问题呢?

+0

对不起,图片有点小。你的精灵有多大? – canon

+0

这是可重复的吗? – SLaks

+0

@canon如果您右键单击图片并按下打开,它将以实际大小打开(http://i.stack.imgur.com/WGdAr.jpg)。我的精灵是83.78kb。 – Kuncevic

回答

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完成。

附注:是否有必要将翻转到可观察数组中?我假设你打算稍后使用它,因为当前代码中没有任何内容需要它。如果没有,拿出来,这将有助于表现(尽管它不会解决这个问题)。

干杯,我希望这可以帮助。

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功能取出括号()index之后。

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