2009-04-29 13 views
6

ho qualche javascript eredità che congela il tfoot/thead di un tavolo e permette al corpo di scorrimento, funziona bene, tranne in IE8 sua molto lento.prestazioni clientWidth in IE8

Ho rintracciato il problema alla lettura della proprietà clientWidth di una cella in tfoot/thead ... in ie6/7 e in FireFox 1.5-3 ci vogliono circa 3ms per leggere la proprietà clientWidth ... in IE8 subentra 200 ms o più quando il numero di celle nella tabella aumenta.

Si tratta di un bug noto? c'è qualche soluzione o soluzione?

risposta

2

Non sono riuscito a trovare alcuna documentazione che questo sia un bug noto. Per migliorare le prestazioni, perché non memorizzare nella cache la proprietà clientWidth e aggiornare periodicamente la cache? IE se il codice è stato:

var someValue = someElement.clientWidth + somethingElse; 

Change che a:

// Note the following 3 lines use prototype 
// To do this without prototype, create the function, 
// create a closure out of it, and have the function 
// repeatedly call itself using setTimeout() with a timeout of 1000 
// milliseconds (or more/less depending on performance you need) 
var updateCache = function() { 
    this. clientWidthCache = $('someElement').clientWidth; 
}; 
new PeriodicalExecuter(updateCache.bind(this),1); 

var someValue = this.clientWidthCache + somethingElse 
0

Il tuo problema potrebbe essere legato a qualcosa di diverso (e non solo la chiamata clientWidth): sono il tuo aggiornamento/anyhting ridimensionamento nel DOM mentre si chiama questa funzione?

Il tuo browser potrebbe essere busy doing reflow su IE8, rendendo così clientWidth più lento?

0

IE 8 ha la possibilità di passare tra le versioni di IE e anche c'è una modalità di compatibilità. Hai provato a passare alla modalità di compatibilità? Questo fa qualche differenza?

+0

Sì, il passaggio alla modalità di compatibilità consente di ottenere prestazioni migliori, tuttavia interrompe altre parti dell'interfaccia utente perché non viene visualizzato esattamente come IE7. Speravo in una soluzione che non prevedesse l'uso della compatibilità, ma potrebbe essere l'unica opzione possibile. – Element

+0

Non sto dicendo che è il problema nel tuo caso, ma l'ultima volta che ho avuto discrepanze di rendering tra IE7 e IE8 ho scoperto che il mio codice in particolare html/css aveva bug. La modalità di compatibilità sembrava risolvere il problema, ma non volevo accettarlo neanche io. Quindi probabilmente inizierei a gestire i codici attraverso i validatori. Chissà, potresti perdere qualcosa. - L'ho fatto. ;) –

6

Ho risolto questo problema se sei ancora interessato. La soluzione è abbastanza complessa. Fondamentalmente, è necessario collegare un semplice HTC all'elemento e memorizzare nella cache il suo clientWidth/Height.

La semplice HTC assomiglia a questo:

<component lightweight="true"> 
<script> 
window.clientWidth2[uniqueID]=clientWidth; 
window.clientHeight2[uniqueID]=clientHeight; 
</script> 
</component> 

è necessario collegare il HTC usando i CSS:

.my-table td {behavior: url(simple.htc);} 

ricordare che solo è necessario collegare il comportamento per IE8!

È quindi utilizzare un po 'di JavaScript per creare getter per i valori memorizzati nella cache:

var WIDTH = "clientWidth", 
    HEIGHT = "clientHeight"; 

if (8 == document.documentMode) { 

    window.clientWidth2 = {}; 
    Object.defineProperty(Element.prototype, "clientWidth2", { 
    get: function() { 
     return window.clientWidth2[this.uniqueID] || this.clientWidth; 
    } 
    }); 

    window.clientHeight2 = {}; 
    Object.defineProperty(Element.prototype, "clientHeight2", { 
    get: function() { 
     return window.clientHeight2[this.uniqueID] || this.clientHeight; 
    } 
    }); 

    WIDTH = "clientWidth2"; 
    HEIGHT = "clientHeight2"; 
} 

Si noti che ho creato il costanti larghezza/altezza. Dovresti usarli per ottenere la larghezza/altezza dei tuoi elementi:

var width = element[WIDTH]; 

È complicato ma funziona. Ho avuto lo stesso problema di te, l'accesso al clientWidth è stato incredibilmente lento. Questo risolve il problema molto bene. Non è ancora veloce come IE7, ma è tornato ad essere nuovamente utilizzabile.

+1

wow .. è Dean Edwards ../me archi –

0

Avevo notato una prestazione lenta anche durante la lettura delle proprietà della larghezza. E potrebbe anche esserci.

Tuttavia, ho scoperto che l'impatto principale delle prestazioni nella nostra app era che la funzione collegata all'evento di ridimensionamento della finestra era in qualche modo causa di un altro ridimensionamento che causava un effetto a catena, sebbene non un ciclo infinito. Ho capito questo quando ho visto il conteggio delle chiamate per la funzione era di ordini di grandezza più grande in IE8 rispetto a IE7 (adoro lo strumento di sviluppo IE).Penso che la ragione sia che alcune attività su elementi, come forse l'impostazione di larghezze di elementi, ora causano un reflow in IE8 che non lo ha fatto in IE7.

L'ho risolto impostando l'evento di ridimensionamento della finestra su: resize = "return myfunction();" invece di ridimensionare soltanto "myfunction();" e assicurandosi che la mia funzione restituisse false;

Mi rendo conto che la domanda originale è vecchia di diversi mesi, ma ho pensato di pubblicare i miei risultati nel caso in cui qualcun altro potesse trarne beneficio.