2012-08-28 12 views
7

Ho un'immagine statica 500x640 seduto in una cartella di 20x20 pezzi con sprite css, sto impostando la posizione di sfondo per visualizzare ogni pezzo, ho bisogno di un tale tipo di display per poter manipolare ogni pezzo in un secondo momento.Prestazioni 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; 
} 

Così sto avendo alcuni problemi di prestazioni. Per esempio in Opera e FF immagini loading molto rapidamente circa 1 secondo, in IE circa 3 secondi, ma in Chrome si sta caricando molto lento enter image description here

sta prendendo circa 17 secondi per visualizzare tutti i pezzi in Chrome ...

Browser facendo solo una richiesta per ottenere l'immagine e di tagliare piccoli pezzi da esso, perché potrebbe richiedere così tanto tempo in Chrome?

C'è un modo per migliorare le prestazioni? enter image description here

appena fatto CTRL + Aggiorna e qui strano risultato di carico: enter image description here

UPDATE: Ho appena messo un campione qui: http://bit.ly/TrcCdp

UPDATE: Nel mio esempio C'è Array JSON, contiene 800 elementi, quindi ho scoperto che se lo faccio di meno, ad es. 600-700 elementi le prestazioni stanno migliorando, ma ho comunque bisogno di 800 elementi.

per esempio quando c'è solo 600 elementi è riducendo il carico in Chrome per circa 6 sec ....

Quindi, probabilmente può essere il problema da qualche parte nel punto in cui l'iterazione ko modello?

+0

Scusa, l'immagine è un po 'piccola. Quanto è grande il tuo sprite? – canon

+0

È riproducibile? – SLaks

+0

@canon se fai clic con il tasto destro sull'immagine e premi Apri si aprirà in dimensioni reali (http://i.stack.imgur.com/WGdAr.jpg). Il mio sprite è 83.78kb. – Kuncevic

risposta

4

Il problema non è l'immagine. L'immagine può essere risolto mettendo un precarico in alto, prima di qualsiasi del foglio di stile o di script tag:

<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 --> 

Dopo questo, i carichi di immagini a 170 ms (a livello locale). Tuttavia, la pagina si spegne ancora per altri 10-15 secondi cercando di decidere cosa fare.

Il problema di root è che il javascript è un casino assoluto. I nomi di immagini/file/funzioni sono criptici. Le cose nel mezzo della pagina dipendono dal codice alla fine dipende dal codice all'inizio dipende dal codice alla fine. Controller/view/model logic è su tutta la mappa. Variabili globali e accoppiamento multi-file ... hokay, </soapbox>, ora sul trattamento del sintomo.

Problema 1: legame knockout prima del caricamento del DOM

applyBindings messo in un callback domready:

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

Problema 2: foreach è lenta

vincolante Il foreach knockout è incredibilmente lento con grandi set di dati. Puoi provare i modelli jQuery e spostare il foreach all'interno del modello, as described in this SO question. Sembra che il tempo scenda a circa 3 secondi.

Non capisco perché è necessario perché sembra che stia bene con il tuo foreach attuale, semplicemente si blocca per sempre mentre knockout fa un po 'di magia sullo sfondo che, per quanto posso dire, si svolge dopo foreach completa.

Nota a margine: è necessario inserire i flip in una matrice osservabile? Presumo che tu intenda utilizzarlo in seguito, poiché nulla nel codice attuale ne ha bisogno. In caso contrario, estrailo e questo aiuterà le prestazioni (anche se non risolverà questo problema).

Cheers, spero che questo aiuti.

2

È una specie di bug di rendering strano tra l'associazione foreach e Chrome. Ho provato ad aggiungere un carattere nel modello prima dello div e ho corretto il ritardo (ma ho anche incasinato il layout).

Un buon modo per risolvere questo problema è utilizzare qualcosa di diverso da foreach. Il mio repeat binding funziona bene qui e risolve il problema del ritardo.

qui è che la sezione del codice utilizzando 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> 

Perché repeat non usa un'osservabile per $index, avrete anche bisogno di cambiare i vostri getTopValue e getLeftValue funzioni di togliere le parentesi () dopo index.

1

Si dovrebbe anche cercare di snellire il codice che viene chiamato dal ciclo foreach. Non so quanto spesso chiami i metodi getLeftValue e getTopValue ma sono piuttosto non ottimizzati.

  • Provare a limitare le chiamate di funzione che ti danno lo stesso risultato, utilizzare Vars locali per mettere in cache dal momento che sono a buon mercato
  • non concatenare stringhe in grandi anse, questo è il modo più lento rispetto all'utilizzo di una serie di unirsi a loro.

Ho provato a ottimizzare le due funzioni. Dovresti vedere almeno qualche miglioramento:

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