2012-08-28 6 views
7

정적 이미지 500x640은 CSS 스프라이트가있는 20x20 조각에 의해 catted되어 있으며, 각 조각을 표시하기 위해 배경 위치를 설정하고 있으며 나중에 각 조각을 조작 할 수있는 종류의 디스플레이가 필요합니다.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; 
} 

그래서 몇 가지 성능 문제가 발생하고있다. IE에서 매우 빠르게 약 1 초를로드 오페라와 FF 이미지의 예를 들어 약 3 초 만, 크롬에서 매우 느린로드 enter image description here

가 크롬의 모든 조각을 표시하기 위해 약 17 초 걸립니다 ...

브라우저에서 이미지를 가져오고 작은 조각을 자르는 것 하나만하면 Chrome에서 왜 오래 걸릴까요?

성능을 향상시킬 수있는 방법이 있습니까? enter image description here

는 CTRL + 새로 고침을했고, 여기에 이상한로드 결과 : 가 UPDATE enter image description here

: http://bit.ly/TrcCdp

UPDATE : 난 그냥 여기에 샘플을 배치 내 샘플에서 가 JSON 배열에는 800 개의 요소가 포함되어 있습니다. 따라서 요소를 적게 만들면 알아볼 수 있습니다. 예를 들어 600-700 개의 요소가 성능이 좋아지고 있지만 어쨌든 800 개의 요소가 필요합니다.

예 :이 약 6 초에 크롬의 부하를 감소에만 600 요소 ....있을 때

그래서 아마 어딘가에서 템플릿을 반복 녹아웃 지점에서 문제가 될 수있다?

+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 초 동안 계속 머뭇 거리며 무엇을해야할지 결정하려고합니다.

근본적인 문제는 자바 스크립트가 절대 엉망이라는 것입니다. 이미지/파일/함수 이름은 암호화되어 있습니다. 페이지의 중간에있는 것들은 끝에있는 코드에 의존합니다. 처음에는 코드에 따라 다릅니다. 컨트롤러/뷰/모델 논리가 모두지도 위에 있습니다. 전역 변수 및 다중 파일 결합 ... hokay, </soapbox>, 이제 증상 치료.

문제 1 :

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

문제 2 : foreach는이 녹아웃 foreach는 바인딩

가 느린입니다 domready 콜백으로 DOM로드되기 전에

넣어 applyBindings를 녹아웃 바인딩 대용량 데이터 세트에서는 엄청나게 느립니다. jQuery 템플릿을 사용하고 템플릿 내 foreach를 옮길 수 있습니다 (as described in this SO question). 시간이 약 3 초로 줄었습니다.

현재 foreach로 잘 렌더링되는 것처럼 이것이 필요한 이유를 실제로 이해하지 못합니다. 녹아웃이 foreach 이후에 발생하는 백그라운드에서 마술을하는 동안 영원히 정지합니다. 완료됩니다.

사이드 노트 : 플립을 관찰 가능한 배열에 넣어야합니까? 현재 코드에서 아무 것도 필요로하지 않으므로 나중에 사용하려고한다고 가정합니다. 그렇지 않은 경우 가져 가면 성능에 도움이됩니다 (이 문제는 해결되지는 않지만).

환호, 이것이 도움이되기를 바랍니다.

2

foreach 바인딩과 Chrome 간에는 이상한 렌더링 버그가 있습니다. 난 단지 div 전에 템플릿에 문자를 추가하고 그 지연을 고정 (뿐만 아니라 레이아웃 엉망이).

이 문제를 해결하는 좋은 방법은 foreach 이외의 것을 사용하는 것입니다. 내 repeat binding 여기서 잘 작동하고 지연 문제를 해결합니다. 여기

는 코드의 섹션 repeat을 사용하는 것입니다 : 당신은 또한 괄호를 적용하려면 getTopValuegetLeftValue 기능을 변경해야합니다,

<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에 대한 관찰을 사용하지 않는 ()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(""); 
}