Red de conocimiento informático - Material del sitio web - Cómo optimizar el rendimiento de una página web

Cómo optimizar el rendimiento de una página web

El front-end es enorme e incluye HTML, CSS, Javascript, Image, Flash y otros recursos diversos. La optimización del front-end es compleja y existen diferentes métodos para todos los aspectos de los recursos. Entonces, ¿cuál es el propósito de la optimización front-end?

1. Desde la perspectiva del usuario, la optimización puede hacer que la página se cargue más rápido, responda a las operaciones del usuario de manera más oportuna y brinde a los usuarios una experiencia más amigable.

2. Desde la perspectiva del proveedor de servicios, la optimización puede reducir la cantidad de solicitudes de página o reducir el ancho de banda ocupado por las solicitudes, lo que puede ahorrar recursos considerables.

En resumen, una optimización adecuada no sólo puede mejorar la experiencia del usuario del sitio sino también ahorrar una considerable utilización de recursos.

Hay muchas formas de optimizar el front-end, que se pueden dividir aproximadamente en dos categorías según la granularidad. La primera categoría es la optimización a nivel de página, como la cantidad de solicitudes HTTP y la carga sin bloqueo. de scripts, optimización de posición de scripts en línea, etc. La segunda categoría es la optimización a nivel de código, como la optimización de la operación DOM en Javascript, la optimización del selector CSS, la optimización de imágenes, la optimización de la estructura HTML, etc. Además, con el fin de mejorar la relación entrada-salida, las diversas estrategias de optimización mencionadas más adelante se organizan aproximadamente de mayor a menor relación entrada-salida.

1. Optimización a nivel de página

1. Reducir el número de solicitudes HTTP

Esta estrategia es básicamente conocida por todos los usuarios de front-end, y lo es. también el más importante y eficaz. Se dice que las solicitudes HTTP deberían reducirse, pero ¿qué pasará si hay demasiadas solicitudes? En primer lugar, cada solicitud tiene un costo, que incluye tanto el costo de tiempo como el costo de recursos. Una solicitud completa requiere un proceso "largo" y complicado de direccionamiento DNS, establecer una conexión con el servidor, enviar datos, esperar a que el servidor responda y recibir datos. El costo de tiempo es que los usuarios tienen que esperar a que finalice el proceso para ver o "sentir" el recurso. Dado que cada solicitud en el recurso necesita transportar datos, cada solicitud requiere ancho de banda. Además, dado que existe un límite superior en la cantidad de solicitudes simultáneas que el navegador puede realizar (consulte aquí para obtener más detalles), cuando aumenta la cantidad de solicitudes, el navegador debe realizar solicitudes en lotes, lo que aumentará el tiempo de espera del usuario. y causar problemas al sitio web del usuario. La impresión de velocidad lenta es que incluso si se han solicitado todos los recursos en la primera pantalla que el usuario puede ver, la barra de progreso del navegador siempre existirá.

Las principales formas de reducir el número de solicitudes HTTP incluyen:

(1) Simplificar la página desde el nivel de diseño e implementación.

Si su página lo es. Tan simple como la página de inicio de Baidu, entonces las siguientes reglas son básicamente innecesarias. Lo más sencillo es mantener la página simple y reducir el uso de recursos. Si no es así y tu página necesita una apariencia hermosa, continúa leyendo a continuación.

(2). Configurar correctamente la caché HTTP

El poder de la caché es poderoso y una configuración de caché adecuada puede reducir en gran medida las solicitudes HTTP. Tome la página de inicio de Youah como ejemplo. Cuando el navegador no la almacena en caché, se emitirán 78 solicitudes por primera vez y se enviarán más de 600 000 datos (como se muestra en la Figura 1.1). para la segunda visita, solo hay 10 solicitudes de acceso y más de 20.000 datos (Figura 1.2). (Cabe señalar aquí que si actualiza la página directamente con F5, el efecto será diferente. En este caso, el número de solicitudes sigue siendo el mismo, pero el servidor de solicitudes para el recurso almacenado en caché es una respuesta 304. Solo el El encabezado no tiene cuerpo, lo que puede ahorrar ancho de banda)

¿Cuál es una configuración razonable? El principio es muy simple. Cuanto más caché pueda, mejor, y cuanto más tiempo pueda almacenarse en caché, mejor. Por ejemplo, los recursos de imagen que rara vez cambian pueden establecer directamente un encabezado de vencimiento largo a través de Expires en el encabezado HTTP. Los recursos que cambian con poca frecuencia pero pueden cambiar pueden usar Last-Modifed para la verificación de la solicitud. Mantenga los recursos en la caché el mayor tiempo posible.

Las configuraciones y principios específicos del almacenamiento en caché HTTP no se describirán en detalle aquí. Aquellos que estén interesados ​​pueden consultar los siguientes artículos:

Descripción de las estrategias de almacenamiento en caché en el protocolo HTTP1.1

. Fiddler Introducción al almacenamiento en caché en el rendimiento HTTP

(3). Fusión y compresión de recursos

Si es posible, combine scripts y estilos externos tanto como sea posible y combine varios en uno. Además, CSS, Javascript e Image se pueden comprimir utilizando las herramientas correspondientes. Después de la compresión, a menudo se puede ahorrar mucho espacio.

(4). CSS Sprites

Fusionar imágenes CSS, otra buena forma de reducir el número de solicitudes.

(5). Imágenes en línea

Uso de datos:

Utilice esquema de URL para incrustar imágenes en páginas o CSS si no considera la gestión de recursos. es un problema, esta es una buena solución. Si está incrustado en la página, el tamaño de la página aumentará y no se podrá utilizar la memoria caché del navegador. Las imágenes utilizadas en CSS son más ideales.

(6). Carga diferida de imágenes (todavía no entiendo el contenido de esta sección)

Es posible que esta estrategia en realidad no reduzca la cantidad de solicitudes HTTP, pero puede reducirlas. el número de solicitudes HTTP bajo ciertas condiciones o cuando la página se carga por primera vez. Para las imágenes, puede cargar solo la primera pantalla cuando la página recién se carga y solo cargar las imágenes posteriores cuando el usuario continúa desplazándose hacia atrás. De esta forma, si al usuario sólo le interesa el contenido de la primera pantalla, se guardarán las solicitudes de imágenes restantes.

Sí, hay una página de inicio

El método anterior era almacenar en caché la dirección de la imagen después de la primera pantalla en la etiqueta Textarea al cargar y esperar hasta que el usuario se desplaza hacia abajo hasta " carga "perezosa".

2. Coloque el script externo en la parte inferior (cargue el contenido del script después de que se cargue el contenido de información de la página)

Como se mencionó anteriormente, el navegador puede realizar solicitudes simultáneas. Esta característica. le permite cargar recursos más rápido, sin embargo, los scripts de enlaces externos bloquearán otros recursos durante la carga. Por ejemplo, antes de que se cargue el script, las imágenes, estilos y otros scripts detrás de él se bloquearán hasta que se cargue el script. Si el script se coloca en una posición relativamente alta, afectará la velocidad de carga de toda la página y, por lo tanto, afectará la experiencia del usuario. Hay muchas maneras de resolver este problema,

aquí hay una introducción más detallada

(aquí está la traducción y

ejemplos más detallados

), y el método más simple y confiable es mover el script lo más atrás posible para reducir el impacto en las descargas simultáneas.

3. Ejecute scripts en línea de forma asincrónica (de hecho, el principio es el mismo que el anterior, asegurando que el script se cargue después del contenido de la página).

En comparación con los scripts externos, el El impacto de los scripts en línea en el rendimiento es peor que eso. La página de inicio, al igual que los scripts externos, los scripts en línea también bloquearán las solicitudes concurrentes cuando se ejecuten. Además, dado que el navegador tiene un solo subproceso en el procesamiento de la página, cuando el script en línea se ejecuta antes de que se represente la página, el trabajo de representación de la página se pospondrá. . En resumen, cuando se ejecuta el script en línea, la página está en blanco. En vista de las dos razones anteriores, se recomienda ejecutar scripts en línea que tardan mucho en ejecutarse de forma asincrónica. Hay muchos métodos asincrónicos, como el uso del atributo defer del elemento de secuencia de comandos (existen problemas de compatibilidad, como). ya que document.write no se puede utilizar), usando setTimeout

, además, se introdujo el mecanismo

Web Workers en HTML5, que puede resolver este tipo de problema.

4. Javascript de carga diferida (solo se carga cuando es necesario cargarlo, el contenido de la información no se carga en circunstancias normales).

Con la popularidad de los marcos de Javascript, cada vez más sitios también utiliza marcos. Sin embargo, un marco a menudo incluye muchas implementaciones funcionales. Estas funciones no son necesarias para todas las páginas. Si descarga scripts innecesarios, es una pérdida de recursos: desperdicia ancho de banda y tiempo de ejecución. Actualmente existen dos enfoques: uno es personalizar una versión mini dedicada del marco para páginas con tráfico particularmente alto y el otro es Lazy Load. YUI utiliza el segundo método. En la implementación de YUI, inicialmente solo se carga el módulo principal y otros módulos pueden esperar hasta que sean necesarios.

5. Coloque CSS en HEAD

Si coloca CSS en otros lugares como BODY, el navegador puede comenzar a representar la página antes de descargar y analizar el CSS, lo que provoca la aparición de la página. saltar del estado sin CSS al estado CSS y la experiencia del usuario es deficiente. Además, algunos navegadores solo comenzarán a representar la página después de que se complete la descarga del CSS. Si el CSS se coloca en una posición inferior, el navegador retrasará el tiempo de procesamiento.

6. Devolución de llamada de solicitud asincrónica (es decir, extraer algunos estilos de comportamiento y cargar lentamente el contenido de la información)

En algunas páginas, puede existir tal requisito y es necesario hacerlo. utilice la etiqueta script para solicitar datos de forma asincrónica. Similar:

Javascript:

/*Función de devolución de llamada*/

función myCallback(info){

//haz algo aquí

}

HTML:

Contenido devuelto por cb:

myCallback('¡Hola mundo!'); >Escribir directamente en la página de la manera anterior también tiene un impacto en el rendimiento de la página, es decir, aumenta la carga de cargar la página por primera vez y retrasa el tiempo de activación de DOMLoaded y window.onload. eventos. Si la puntualidad lo permite, puede considerar cargar cuando se activa el evento DOMLoaded, o usar el método setTimeout para controlar de manera flexible el tiempo de carga.

7. Reducir los saltos HTTP innecesarios

Para los enlaces HTTP a los que se accede en forma de directorio, muchas personas ignorarán si el enlace tiene una '/' al final si su servidor no la tiene. se tratan de manera diferente, entonces también debe prestar atención al hecho de que puede haber saltos 301 ocultos y solicitudes redundantes. Consulte la figura siguiente para obtener más detalles. Se accede al primer enlace sin el final '/', por lo que el servidor tiene un salto.

8. Evite solicitudes de recursos duplicadas

Esta situación se debe principalmente a negligencia o cuando la página se empalma en varios módulos, y luego se solicita el mismo recurso en cada módulo. Dará como resultado solicitudes repetidas de recursos

2. Optimización a nivel de código

1. Javascript

(1). operaciones deberían Es la operación que consume más rendimiento en los scripts, como agregar, modificar, eliminar elementos DOM u operar en colecciones DOM.

Si el script contiene una gran cantidad de operaciones DOM, debe prestar atención a los siguientes puntos:

a. Colección HTML (recopilador HTML, devuelve información de contenido de matriz)

En Los scripts document.images, document.forms y getElementsByTagName() devuelven colecciones del tipo HTMLCollection. En el uso diario, se utilizan principalmente como matrices porque tienen un atributo de longitud y también pueden usar índices para acceder a cada elemento. Sin embargo, el rendimiento del acceso es mucho peor que el de una matriz. La razón es que esta colección no es un resultado estático. Solo representa una consulta específica. Cada vez que se accede a la colección, la consulta se volverá a ejecutar. resultados de la consulta. El llamado "acceder a una colección" incluye leer la propiedad de longitud de la colección y acceder a los elementos de la colección.

Por lo tanto, cuando necesite recorrer la colección HTML, intente convertirla en una matriz antes de acceder a ella para mejorar el rendimiento. Incluso si no se convierte en una matriz, acceda a ella lo menos posible. Por ejemplo, al atravesar, puede guardar la propiedad de longitud y los miembros en variables locales y luego usar las variables locales.

b. Reflujo y repintado

Además del punto anterior, las operaciones DOM también deben considerar el reflujo y el repintado del navegador, porque consumen recursos, específicamente Únase a los siguientes artículos:

¿Cómo reducir el repintado y el reflujo del navegador?

Comprensión de Internet Explorer

Comportamiento de renderizado

Notas sobre el reflujo de HTML

(2) Úselo con precaución

with(obj){ p = 1}; El comportamiento del bloque de código en realidad modifica el bloque de código

Entorno de ejecución

.

coloca obj al frente de su cadena de alcance. Al acceder a variables no locales en el bloque de código with, la búsqueda comienza desde obj. Si no, presione el alcance a su vez. La cadena busca hacia arriba, por lo que usa with is. equivalente a aumentar la longitud de la cadena de alcance. Cada búsqueda de una cadena de alcance lleva tiempo y una cadena de alcance demasiado larga hará que el rendimiento de la búsqueda disminuya.

Por lo tanto, a menos que esté seguro de que solo está accediendo a las propiedades en obj en el código with, utilícelo con precaución. En su lugar, puede utilizar variables locales para almacenar en caché las propiedades a las que es necesario acceder.

(3). Evite el uso de eval y Function

Cada vez que el constructor eval o Function opera en el código fuente representado por una cadena, el motor de script necesita convertir el código fuente en un código fuente. Código de ejecución legible. Esta es una operación que consume muchos recursos, a menudo más de 100 veces más lenta que una simple llamada a función.

La función eval es particularmente ineficiente. Dado que el contenido de la cadena pasada a eval no se puede conocer de antemano, eval interpreta el código que se procesará en su contexto, lo que significa que el compilador no puede optimizar el contexto. entonces solo puede Hay un navegador que interpreta el código en tiempo de ejecución. Esto tiene un gran impacto en el rendimiento.

El constructor de funciones es ligeramente mejor que eval porque el uso de este código no afecta el código circundante, pero aún así es lento;

Además, el uso de eval y Function no favorece que las herramientas de compresión de Javascript realicen la compresión.

(4). Reducir la búsqueda en cadena de alcance (este aspecto está diseñado para abordar algunos problemas relacionados con el contenido)

El artículo anterior habló sobre el problema de la búsqueda en cadena de alcance, especialmente en bucles. Cuestiones a tener en cuenta.

Si necesita acceder a una variable fuera de este alcance en un bucle, almacene en caché la variable con una variable local antes de recorrerla y reescriba esa variable después del recorrido. Esto es especialmente importante para las variables globales, porque las variables globales están dentro del alcance. La parte superior de la cadena tiene el mayor número de búsquedas durante el acceso.

Forma de escritura ineficiente:

// Variable global

var globalVar = 1;

función myCallback(info){

p>

for( var i = 100000; i--;){

// Cada vez que accede a globalVar, debe encontrar la parte superior de la cadena de alcance. En este ejemplo, necesitas acceder a él 100000 veces

globalVar = i;

}

}

Forma de escritura más eficiente:

// Variables globales

var globalVar = 1;

función myCallback(info){

//Variables locales en caché de variables globales

var localVar = globalVar;

for( var i = 100000; i--;){

//El acceso a las variables locales es lo más rápido

localVar = i;

}

//En este ejemplo, solo necesitas acceder a la variable global dos veces

En la función, solo es necesario asignar el valor del contenido en globalVar al área localVar

globalVar = localVar

}

Además, para reducir las búsquedas en la cadena de alcance, También debería reducirse el uso de cierres.

(5).

El acceso a datos en Javascript incluye cantidades directas (cadenas, expresiones regulares), variables, propiedades de objetos y matrices, entre las que se encuentran cantidades directas y acceso local a variables. es el más rápido y el acceso a las propiedades y matrices de los objetos requiere una mayor sobrecarga. Se recomienda colocar datos en variables locales cuando ocurren las siguientes situaciones:

a. Más de 1 acceso a cualquier propiedad de objeto

b.

Además, se deben reducir al máximo las búsquedas profundas de objetos y arrays.

(6). Empalme de cadenas

Es relativamente ineficiente usar el signo " " para empalmar cadenas en Javascript, porque cada ejecución abrirá nueva memoria y generará una nueva variable de cadena. y luego asignar el resultado de la concatenación a la nueva variable. Un enfoque más eficiente es utilizar el método de unión de la matriz, es decir, colocar las cadenas que se van a unir en la matriz y finalmente llamar a su método de unión para obtener el resultado. Sin embargo, dado que el uso de matrices también tiene una cierta sobrecarga, puede considerar usar este método cuando hay muchas cadenas que deben empalmarse.

Para obtener una introducción más detallada a la optimización de Javascript, consulte:

Escribir Javascript eficiente (PPT)

Javascript eficiente

2 . Carácter de selección de CSS

En la mente de la mayoría de las personas, los navegadores analizan los selectores de CSS de izquierda a derecha, por ejemplo

#toc A { color: #444 }

Dicho selector será muy eficiente si se analiza de derecha a izquierda, porque la primera selección de ID básicamente limita el rango de búsqueda, pero de hecho los símbolos del navegador se analizan de derecha a izquierda. Al igual que con el selector anterior, el navegador debe recorrer para encontrar los nodos ancestros de cada etiqueta A, y la eficiencia no es tan alta como se imaginaba anteriormente.

De acuerdo con esta característica de comportamiento del navegador, debe prestar atención a muchas cosas al escribir selectores. Alguien los ha enumerado uno por uno. Para obtener más información, consulte aquí.

3. HTML

La optimización del HTML en sí está atrayendo cada vez más atención. Para obtener más información, consulte este artículo resumido.

.

4. Compresión de imágenes

La compresión de imágenes es una actividad técnica, pero hoy en día existen muchas herramientas en esta área. La compresión a menudo puede brindar buenos resultados. Los principios y métodos de compresión específicos son. Se presenta en detalle en el Capítulo 10 de "Sitios web aún más rápidos". Si está interesado, puede consultarlo.

Resumen

Este artículo resume los diversos métodos de optimización front-end desde las dos granularidades de nivel de página y nivel de código. Estos métodos son básicamente el proceso de desarrollo de los desarrolladores front-end. Se puede aprender y practicar. Además, la optimización completa del front-end también debe incluir muchas otras formas, como CDN, Gzip, múltiples nombres de dominio, servidores sin cookies, etc. Dado que la operabilidad para los desarrolladores no es sólida, lo haré. No entre en detalles aquí. Para más detalles, puede consultar estas "reglas de oro" de Yahoo y Google

.