2011-05-30 10 views
10

Utilizando las herramientas de desarrollador de Firebug y Chrome, puedo ver que cargar algunos archivos javascript y css a través de una acción puede tomar 500ms adicionales en mi máquina de desarrollo. Esto sucede con diferentes archivos en diferentes llamadas y no importa en qué orden los coloque. Si conecto directamente a los archivos, este retraso de 500 ms no se produce. Puedo actualizar la página una y otra vez y obtener diferentes valores, pero siempre se ven como 500 ms se agregó al tiempo de solicitud. Si continúo actualizando la página, los 500 ms adicionales aparecen en diferentes archivos individuales o, a veces, en dos archivos, donde uno es un retraso de 1000 ms, como en la imagen siguiente.Mysterious ASP.NET MVC Action ¿Problema de alta latencia?


EDITAR

Poner en Monitor.Enter BeginRequest y Monitor.Exit de mi HttpModule en el EndRequest causado el retraso que se fuera, así que yo creo que tiene algo que ver con el roscado múltiples peticiones.


utilizo el método pueda describirse por Evan Nagel here para almacenar en caché, pero lo mismo sucede cuando sustituyo los enlaces con las llamadas a mi propio controlador con una acción que simplemente pasa un archivo en bruto a través de:

public FileResult RawFile(string path, string contentType) 
{ 
    var server = HttpContext.Server; 
    string decodedPath = server.UrlDecode(path); 
    string mappedPath = server.MapPath(decodedPath); 
    return File(mappedPath, contentType); 
} 

Aquí está el código que tengo en la sección de cabecera de mi html:

<link rel="stylesheet" href="@Url.Action("RawFile", new { controller = "Content", path = "~/Content/Site.css", contentType = "text/css" })" type="text/css" /> 
<script src="@Url.Action("RawFile", new { controller = "Content", path = "~/Scripts/debug/FBINFO.js", contentType = "application/x-javascript" })" type="text/javascript"></script> 
<script src="@Url.Action("RawFile", new { controller = "Content", path = "~/Scripts/jquery-1.4.1.min.js", contentType = "application/x-javascript" })" type="text/javascript"></script> 

Esto no parece suceder en mi servidor de producción, al menos no tan a menudo, pero es más difícil de decir porque la latencia es más alta normalmente. ¿Es esto algo de lo que no debes preocuparte? ¿Qué lo causaría? Sucede tanto con Cassini como con mi servidor IIS local en Windows 7 Home Ultimate de 64 bits.

He añadido un atributo personalizado para sincronizar las llamadas y los tiempos entre OnAction/OnResult Executing y Executed son generalmente de menos de milisegundos. Utilicé un cronómetro en torno al método de acción (el ZipController escribe en la secuencia de respuesta y no devuelve un resultado) y los tiempos también son pequeños, promedian 1.5ms y siempre son menores de 10ms.

La única diferencia real que puedo ver en los encabezados de Fiddler es el encabezado X-AspNetMvc-Version, por lo que configuré que no se anexe e incluso eliminé el encabezado X-AspNet-Version en vano. Intenté habilitar y deshabilitar la compresión y todo lo demás en lo que puedo pensar. Esto es después de que agregué mis propios encabezados de Cache-Control y ETag que no tuvieron ningún efecto. Curiosamente, la demora de 500 ms ocurre incluso en el caso de una respuesta 304 No Modificada donde el cuerpo no se envía. A veces, dos de los archivos tendrán retrasos, uno de 500ms y el otro de 1000ms.

archivo directa: la acción

HTTP/1.1 200 OK 
Content-Type: application/x-javascript 
Last-Modified: Sun, 29 May 2011 22:42:27 GMT 
Accept-Ranges: bytes 
ETag: "b57a84af511ecc1:0" 
Server: Microsoft-IIS/7.5 
Date: Mon, 30 May 2011 04:38:20 GMT 
Content-Length: 1336 

RawFile:

HTTP/1.1 200 OK 
Cache-Control: public 
Content-Type: application/x-javascript 
ETag: "CD9F383D0537373C6D2DC8F60D6519A6" 
Server: Microsoft-IIS/7.5 
Date: Mon, 30 May 2011 04:34:37 GMT 
Content-Length: 1336 

Action MethodDirect File

Siguiendo el comentario de IanT8, añadí un HttpModule para rastrear comenzar/petición final, así como la adición de registro llamadas como la primera y la última declaración de mis métodos de acción. En resumen, ambas solicitudes entran al mismo tiempo y el retraso de 500 ms se produce después de la primera EndRequest, antes de que se ejecute el método de acción de la segunda llamada. Este retraso suele ser de 499 ms, pero fue 497 ms una vez, 498 ms una vez y 492 ms una vez.

2011-05-31 00:55:19.1874|INFO|20110531 00:55:19.196 BeginRequest: http://localhost:51042/Zip/Style?Path=~/Content/Site.css 
2011-05-31 00:55:19.1874|INFO|20110531 00:55:19.197 BeginRequest: http://localhost:51042/Zip/Script?Path=~/Scripts/jquery-1.4.1.min.js|~/Scripts/debug/FBINFO.js 
2011-05-31 00:55:19.2034|INFO|20110531 00:55:19.203 Style() Start 
2011-05-31 00:55:19.2034|INFO|20110531 00:55:19.208 Style() End 
2011-05-31 00:55:19.2034|INFO|20110531 00:55:19.212 EndRequest: http://localhost:51042/Zip/Style?Path=~/Content/Site.css 
2011-05-31 00:55:19.7044|INFO|20110531 00:55:19.704 Script() Start 
2011-05-31 00:55:19.7044|INFO|20110531 00:55:19.712 Script() End 
2011-05-31 00:55:19.7044|INFO|20110531 00:55:19.713 EndRequest: http://localhost:51042/Zip/Script?Path=~/Scripts/jquery-1.4.1.min.js|~/Scripts/debug/FBINFO.js 

Ahora para la parte realmente interesante. Creé un objeto estático en mi HttpModule y llamé Monitor.Enter en BeginRequest y Monitor.Exit en EndRequest. La demora desapareció. Chrome muestra una llamada que toma entre 15 y 20 ms y la otra tarda entre 30 y 40 ms porque tiene que esperar a que finalice la primera llamada, pero la demora de 500 ms se ha ido. Obviamente, esta solución no es óptima.

+0

¿Ha considerado el tiempo de compilación de las acciones? Puede probar esto al verificar las llamadas subsiguientes. – Buildstarted

+0

Sí, agregaré una nota a la pregunta. –

+1

¿Podría tener algo que ver con este límite que encontré mencionado en Server Fault? ¿Realmente querría la EM hacer que nuestras máquinas de desarrollo sean prácticamente inútiles para pruebas de este tipo? Los casi 500ms agregados a cada llamada me hacen pensar que podría ser algo así. http://serverfault.com/questions/133772/what-about-windows-7-as-a-web-server –

Respuesta

5

intenta deshabilitar sesión (SessionStateAttribute).

+0

Eso evita que suceda, pero realmente quiero usar la variable de sesión ... ¿Crees que es un error de MVC? –

+0

@Jason Las solicitudes para acciones de uso de sesión siempre se serializan en ASP.NET para evitar problemas de concurrencia. ¿Realmente necesita estado de sesión para estas solicitudes a archivos estáticos? – bzlm

+0

Ah, por alguna razón me perdí que era un atributo y solo sabía cómo deshabilitarlo para todo en Web.config. Usando el atributo trabajado. –

0

Existe un problema conocido con Cassini y problemas de rendimiento relacionados con la asignación de archivos de host IPv6 sobre IPv4 y la resolución de número de puerto que utiliza Cassini en Windows 7. Es already answered en Stack Overflow y resuelve problemas observados en Firefox y Chrome.

Cuestiones relacionadas