2009-04-29 13 views
6

Tengo un javascript heredado que congela el tfoot/thead de una tabla y permite al cuerpo desplazarse, funciona bien, excepto en IE8 es muy lento.clientWidth Rendimiento en IE8

He rastreado el problema de leer la propiedad clientWidth de una celda en el tfoot/thead ... en ie6/7 y FireFox 1.5-3 toma aproximadamente 3ms leer la propiedad clientWidth ... en IE8 toma el control 200 ms o más cuando aumenta la cantidad de celdas en la tabla.

¿Es este un error conocido? hay alguna solución o solución?

Respuesta

2

No he podido encontrar ningún documento que indique que se trata de un error conocido. Para mejorar el rendimiento, ¿por qué no almacenar en caché la propiedad clientWidth y actualizar periódicamente el caché? Es decir, si el código fue:

var someValue = someElement.clientWidth + somethingElse; 

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

Su problema puede estar relacionado con alguna otra cosa (y no sólo la llamada clientWidth): son su actualización/anyhting cambio de tamaño en su DOM al llamar a esta función?

Su navegador podría ser busy doing reflow en IE8, lo que hace que el cliente sea más lento?

0

IE 8 tiene la capacidad de cambiar entre las versiones de IE y también hay un modo de compatibilidad. ¿Has intentado cambiar al modo de compatibilidad? ¿Eso hace alguna diferencia?

+0

Sí, cambiar al modo de compatibilidad hace que funcione mucho mejor, sin embargo, rompe otras partes de mi IU porque no se representa exactamente como IE7. Estaba esperando una solución que no implique el uso de compatibilidad, aunque puede ser la única opción. – Element

+0

No digo que sea el problema en su caso, pero la última vez que tuve discrepancias de representación entre IE7 e IE8 encontré que mi código especialmente html/css tenía errores. El modo de compatibilidad parecía resolver el problema, pero tampoco lo acepté. Entonces probablemente comenzaría a ejecutar los códigos a través de validadores. Quién sabe, es posible que te hayas perdido algo. - Yo si. ;) –

6

He resuelto este problema si todavía está interesado. La solución es bastante compleja. Básicamente, debe conectar un HTC simple al elemento y almacenar en caché su clientWidth/Height.

El simple HTC se ve así:

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

Es necesario adjuntar el HTC usando CSS:

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

Recuerde que sólo necesita conectar el comportamiento para IE8!

a continuación, utiliza algo de JavaScript para crear captadores de los valores almacenados en caché:

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

Tenga en cuenta que he creado las constantes anchura/altura. Debe utilizar estos para obtener el ancho/altura de sus elementos:

var width = element[WIDTH]; 

Es complicado pero funciona. Tuve el mismo problema que tú, el acceso a clientWidth fue increíblemente lento. Esto resuelve el problema muy bien. Todavía no es tan rápido como IE7, pero ha vuelto a ser utilizable de nuevo.

+1

wow ... es Dean Edwards ../me ladea –

0

Pensé que también había notado un rendimiento lento al leer las propiedades de ancho. Y puede ser que sea así. No obstante, descubrí que el principal impacto para el rendimiento de nuestra aplicación era que la función que se adjuntaba al evento de cambio de tamaño de la ventana provocaba de algún modo otro cambio de tamaño que causaba un efecto de cascada, aunque no un ciclo infinito. Me di cuenta de esto cuando vi que el conteo de llamadas para la función era de órdenes de magnitud mayor en IE8 que en IE7 (me encanta IE Developer Tool).Creo que la razón es que algunas actividades en elementos, como establecer anchos de elemento quizás, ahora causan un reflujo en IE8 que no lo hizo en IE7.

Lo arreglé estableciendo el evento de cambio de tamaño de la ventana en: resize = "return myfunction();" en lugar de simplemente resize = "myfunction();" y asegurándose de que myfunction sea falso;

Me doy cuenta de que la pregunta original tiene varios meses pero pensé que publicaría mis hallazgos en caso de que alguien más se beneficie.