Productos secos | La guía práctica de optimización del rendimiento de proyectos más completa de Vue

 

Prefacio

A través del enlace de datos bidireccional y la tecnología DOM virtual, el marco Vue nos ha ayudado a lidiar con la parte más sucia y agotadora de la manipulación DOM en el desarrollo de front-end. Ya no necesitamos pensar en cómo operar el DOM y cómo operar el DOM de manera más eficiente; pero aún en el proyecto Vue Hay problemas como la optimización de la primera pantalla del proyecto y la optimización de la configuración de compilación de Webpack, por lo que aún debemos prestar atención a la optimización del rendimiento del proyecto Vue para hacer que el proyecto tenga un rendimiento más eficiente y una mejor experiencia de usuario. Este artículo es resumido por el autor a través de la práctica de optimización de proyectos reales. Espero que los lectores tengan un pensamiento esclarecedor después de leer este artículo, para ayudar a optimizar sus propios proyectos. El contenido de este artículo se divide en las siguientes tres partes:

  • Optimización del nivel de código Vue;

  • Optimización del nivel de configuración del paquete web;

  • Optimización de tecnología Web básica.

 

1. Optimización a nivel de código

 

1.1, v-if y v-show distinguen escenarios de uso

v-if es una representación condicional verdadera, porque asegurará que los detectores de eventos y los subcomponentes en el bloque condicional se destruyan y reconstruyan correctamente durante el proceso de conmutación; también es perezoso: si la condición es falsa en el momento de la representación inicial, No se hace nada. Hacer: el bloque condicional no se procesará hasta que la condición se cumpla por primera vez.

 

v-show es mucho más simple, no importa cuál sea la condición inicial, el elemento siempre se renderizará y simplemente se cambiará según la propiedad de visualización de CSS.

 

Por lo tanto, v-if es adecuado para escenarios que rara vez cambian las condiciones durante el tiempo de ejecución y no necesitan cambiar las condiciones con frecuencia; v-show es adecuado para escenarios que requieren condiciones de cambio muy frecuentes.

 

1.2. Diferenciar escenarios de uso entre calculado y reloj

Calculado: Es un atributo calculado, que depende de otros valores de atributo, y el valor calculado se almacena en caché. Solo cuando el valor del atributo del que depende cambia, el valor calculado se recalculará la próxima vez que se obtenga el valor calculado;

 

reloj: Es más una función de "observación", similar a la devolución de llamada de monitoreo de algunos datos, siempre que los datos monitoreados cambien, la devolución de llamada se ejecutará para operaciones posteriores;

 

Escenarios de aplicación:

  • Cuando necesitamos realizar cálculos numéricos y depender de otros datos, debemos usar computed, porque podemos usar la función de caché de computed para evitar recalcular cada vez que obtenemos un valor;

  • Cuando necesitemos realizar operaciones asincrónicas o costosas cuando los datos cambian, debemos usar watch. Usar la opción watch nos permite realizar operaciones asincrónicas (acceso a una API), limitando la frecuencia con la que realizamos la operación, y antes de que lleguemos el resultado final, establece el estado intermedio. Estas son cosas que las propiedades calculadas no pueden hacer.

 

1.3, v-for transversal debe agregar una clave al elemento y evitar usar v-if al mismo tiempo

 

(1) V-para el recorrido debe agregar clave al artículo

Cuando se recorren y representan los datos de la lista, se debe establecer un valor de clave único para cada elemento, de modo que el mecanismo interno de Vue.js pueda encontrar con precisión los datos de la lista. Cuando se actualiza el estado, el nuevo valor del estado se compara con el valor del estado anterior y la diferencia se localiza más rápido.

 

(2) v-para el recorrido evite usar v-if al mismo tiempo

v-for tiene una prioridad más alta que v-if. Si necesita atravesar la matriz completa cada vez, afectará la velocidad, especialmente cuando una pequeña parte de ella necesita ser renderizada, debe reemplazarse con la propiedad calculada si necesario.

 

recomendar:

<ul> <li v-for="user in activeUsers" :key="user.id"> {
   
   { user.name }} </li></ul>computed: { activeUsers: function () { return this.users.filter(function (user) { return user.isActive }) }}
br

 

No recomendado:

<ul> <li v-for="user in users" v-if="user.isActive" :key="user.id"> {
   
   { user.name }} </li></ul>
br

 

1.4, optimización del rendimiento de lista larga

Vue secuestrará los datos a través de Object.defineProperty para darse cuenta de que la vista responde a los cambios de datos. Sin embargo, a veces nuestros componentes son pura visualización de datos y no habrá cambios. No necesitamos que Vue secuestra nuestros datos. En el caso de visualización de datos, esto puede reducir significativamente el tiempo de inicialización del componente ¿Cómo prohibir que Vue se apropie de nuestros datos? Puede congelar un objeto mediante el método Object.freeze. Una vez que el objeto está congelado, ya no se puede modificar.

export default { data: () => ({ users: {} }), async created() { const users = await axios.get("/api/users"); this.users = Object.freeze(users); }};
br

 

1.5. Destrucción del evento

Cuando se destruye un componente de Vue, automáticamente limpiará su conexión con otras instancias, desvinculará todas sus instrucciones y detectores de eventos, pero solo se limitará a los eventos del propio componente. Si usa addEventListene y otros métodos en js, no se destruirá automáticamente. Necesitamos eliminar manualmente los oyentes de estos eventos cuando se destruye el componente para evitar pérdidas de memoria, como:

created() { addEventListener('click', this.click, false)},beforeDestroy() { removeEventListener('click', this.click, false)}
br

 

1.6, carga diferida de recursos de imágenes

En el caso de páginas con demasiadas imágenes, para acelerar la velocidad de carga de la página, en muchos casos necesitamos cargar primero las imágenes que no están en el área visible de la página y luego cargarlas después de desplazarse al área visible. Esto mejorará enormemente el rendimiento de carga de la página y también mejorará la experiencia del usuario. Usamos el complemento vue-lazyload de Vue en el proyecto:

 

(1) Instale el complemento

npm install vue-lazyload --save-dev
br

 

(2) Introducir y utilizar en el archivo de entrada man.js

import VueLazyload from 'vue-lazyload'
br
 

Entonces úsalo directamente en vue

Vue.use(VueLazyload)
br

 

O agregue opciones personalizadas

Vue.use(VueLazyload, {preLoad: 1.3,error: 'dist/error.png',loading: 'dist/loading.gif',attempt: 1})br

(3) Cambie el atributo src de la etiqueta img directamente a v-lazy en el archivo vue para cambiar el modo de visualización de la imagen a la visualización de carga diferida:

<img v-lazy="/static/img/1.png">
br

 

Lo anterior es un uso simple del complemento vue-lazyload. Si desea ver más opciones de parámetros del complemento, puede verificar la dirección github de vue-lazyload.

 

1.7, enrutamiento de carga diferida

Vue es una aplicación de una sola página, y puede haber muchas rutas introducidas. De esta manera, los archivos empaquetados con webpcak son muy grandes. Al ingresar a la página de inicio, se cargan demasiados recursos y la página aparecerá en blanco, que es no favorece la experiencia del usuario. Si podemos dividir los componentes correspondientes a diferentes rutas en diferentes bloques de código, y luego cargar los componentes correspondientes cuando se acceda a las rutas, será más eficiente. Esto aumentará considerablemente la velocidad de visualización de la primera pantalla, pero la velocidad de otras páginas puede reducirse.

 

Carga diferida de enrutamiento:

const Foo = () => import('./Foo.vue')const router = new VueRouter({ routes: [ { path: '/foo', component: Foo } ]})
br

 

 

1.8. Introducción a pedido de complementos de terceros

 

A menudo necesitamos introducir complementos de terceros en nuestros proyectos. Si introducimos directamente el complemento completo, el tamaño del proyecto será demasiado grande. Podemos usar babel-plugin-component para introducir solo los componentes necesarios para reducir el tamaño del proyecto. el objetivo de. El siguiente es un ejemplo de introducción de la biblioteca de componentes element-ui en el proyecto:

 

(1) Primero, instale babel-plugin-component:

npm install babel-plugin-component -D
br

 

(2) Luego, modifique .babelrc para:

{ "presets": [["es2015", { "modules": false }]], "plugins": [ [ "component", { "libraryName": "element-ui", "styleLibraryName": "theme-chalk" } ] ]}
br

 

(3) Introduzca algunos componentes en main.js:

import Vue from 'vue';import { Button, Select } from 'element-ui'; Vue.use(Button) Vue.use(Select)
br

 

 

1.9. Optimizar el rendimiento ilimitado de la lista

Si su aplicación tiene una lista de desplazamiento muy larga o infinita, necesita usar tecnología de ventanas para optimizar el rendimiento. Solo necesita renderizar una pequeña parte del área, reduciendo el tiempo para volver a renderizar componentes y crear nodos dom. Puede consultar los siguientes proyectos de código abierto vue-virtual-scroll-list y vue-virtual-scroller para optimizar esta escena de lista infinita.

 

1.10, renderizado SSR del lado del servidor o renderizado previo

La representación del lado del servidor significa que el trabajo de Vue que representa todos los fragmentos html de las etiquetas en el lado del cliente se completa en el lado del servidor, y los fragmentos html formados en el lado del servidor se devuelven directamente al lado del cliente. Este proceso se llama servidor -representación lateral.

 

(1) Ventajas de la representación del lado del servidor:

  • Mejor SEO: debido a que el contenido de la página SPA se obtiene a través de Ajax, y la herramienta de rastreo del motor de búsqueda no espera a que Ajax se complete de forma asincrónica para rastrear el contenido de la página, por lo que la página no se puede rastrear en el SPA. La página se obtiene a través de Ajax Content y SSR devuelve directamente la página renderizada desde el servidor (los datos ya están contenidos en la página), por lo que las herramientas de rastreo del motor de búsqueda pueden rastrear la página renderizada;

  • Tiempo de llegada de contenido más rápido (carga más rápida en la primera pantalla): SPA esperará a que se descarguen todos los archivos js compilados de Vue antes de comenzar a renderizar la página. La descarga de archivos lleva una cierta cantidad de tiempo, por lo que la renderización de la primera pantalla necesita una cierta cantidad de tiempo; SSR es procesado directamente por el servidor y la página se devuelve directamente a la pantalla, sin esperar la descarga de archivos js y procesamiento, por lo que SSR tiene un tiempo de llegada de contenido más rápido;

 

(2) Desventajas de la representación del lado del servidor:

  • Más restricciones en las condiciones de desarrollo: por ejemplo, la representación del lado del servidor solo admite dos funciones de enlace antes de Crear y crear, lo que hará que algunas bibliotecas de extensión externas requieran un procesamiento especial antes de que puedan ejecutarse en aplicaciones de representación del lado del servidor; y se pueden implementar en cualquier archivo estático La aplicación SPA de una sola página completamente estática en el servidor es diferente La aplicación de renderización del lado del servidor debe estar en el entorno de ejecución del servidor Node.js;

  • Más carga del servidor: renderizar una aplicación completa en Node.js obviamente consume más recursos de CPU que un servidor que solo proporciona archivos estáticos. Por lo tanto, si espera usarlo en un entorno de alto tráfico, prepare la carga del servidor correspondiente. Y use estrategias de almacenamiento en caché sabiamente.

 

Si el SEO y la representación de la primera pantalla de su proyecto son los indicadores clave para evaluar el proyecto, entonces su proyecto necesita una representación del lado del servidor para ayudarlo a lograr el mejor rendimiento de carga inicial y SEO. Para la implementación específica de Vue SSR, consulte la publicación del autor Otro artículo "Vue SSR Trampled Tour". Si su proyecto de Vue solo necesita mejorar el SEO de algunas páginas de marketing (como /, / about, / contact, etc.), es posible que deba prerrepresentar y simplemente generar archivos HTML estáticos para rutas específicas en el momento de la compilación . La ventaja es que es más fácil configurar el renderizado previo y puede usar su interfaz como un sitio completamente estático. Específicamente, puede usar prerender-spa-plugin para agregar fácilmente el renderizado previo.

 

2. Optimización a nivel de paquete web

 

2.1, Webpack comprime imágenes

En el proyecto vue, excepto que el tamaño límite se puede establecer en el cargador de URL en webpack.base.conf.js para procesar imágenes, las imágenes más pequeñas que el límite se convierten al formato base64 y el resto no se opera. Por lo tanto, para algunos recursos de imagen más grandes, la carga será muy lenta cuando se soliciten recursos. Podemos usar image-webpack-loader para comprimir las imágenes:

 

(1) Primero, instale image-webpack-loader:

npm install image-webpack-loader --save-dev
br

 

(2) Luego, configure en webpack.base.conf.js:

{ test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use:[ { loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { loader: 'image-webpack-loader', options: { bypassOnDebug: true, } } ]}
br

 

2.2, reduzca el código redundante de ES6 a ES5

El complemento de Babel inyectará algunas funciones auxiliares al convertir el código ES6 en código ES5, como el siguiente código ES6:

class HelloWebpack extends Component{...}
br

 

Cuando este código se convierte en código ES5 que puede ejecutarse normalmente, se necesitan las siguientes dos funciones auxiliares:

babel-runtime/helpers/createClass // 用于实现 class 语法babel-runtime/helpers/inherits // 用于实现 extends 语法
br

 

De forma predeterminada, Babel incrustará estos códigos de función auxiliar dependientes en cada archivo de salida. Si varios archivos de código fuente dependen de estas funciones auxiliares, los códigos de estas funciones auxiliares aparecerán muchas veces, lo que resultará en una redundancia de código. Para evitar que el código de estas funciones auxiliares vuelva a aparecer, puede importarlas a través de require ('babel-runtime / helpers / createClass') cuando confíe en ellas, de modo que solo puedan aparecer una vez. El complemento babel-plugin-transform-runtime se utiliza para lograr esta función, reemplazando las funciones auxiliares relacionadas con declaraciones de importación, reduciendo así el tamaño del archivo del código compilado por babel.

 

(1) Primero, instale babel-plugin-transform-runtime:

npm install babel-plugin-transform-runtime --save-dev
br

 

(2) Luego, modifique el archivo de configuración .babelrc para:

"plugins": [ "transform-runtime"]
br

 

Si desea ver más detalles del complemento, puede consultar la introducción detallada de babel-plugin-transform-runtime.

 

 

2.3, extraer código público

Si las bibliotecas de terceros y los módulos públicos de cada página no se extraen en el proyecto, el proyecto tendrá los siguientes problemas:

  • Los mismos recursos se cargan repetidamente, lo que desperdicia el tráfico de usuarios y los costos del servidor.

  • Los recursos que deben cargarse para cada página son demasiado grandes, lo que provoca una carga lenta de la primera pantalla de la página web, lo que afecta la experiencia del usuario.

 

Por lo tanto, necesitamos extraer el código común de varias páginas en archivos separados para optimizar los problemas anteriores. Webpack tiene incorporado CommonsChunkPlugin, un complemento dedicado a extraer las partes comunes de múltiples Chunks. La configuración de CommonsChunkPlugin en el proyecto es la siguiente:

// 所有在 package.json 里面依赖的包,都会被打包进 vendor.js 这个文件中。new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: function(module, count) { return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ); }}),// 抽取出代码模块的映射关系new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', chunks: ['vendor']})
br

 

Si desea ver más detalles del complemento, puede ver la introducción detallada de CommonsChunkPlugin.

 

 

2.4, precompilación de plantillas

Cuando se utiliza una plantilla DOM o una plantilla de cadena en JavaScript, la plantilla se compilará en una función de representación en tiempo de ejecución. Normalmente, este proceso es lo suficientemente rápido, pero es mejor evitar este uso para aplicaciones sensibles al rendimiento.

 

La forma más sencilla de precompilar plantillas es utilizar la configuración de compilación relacionada con componentes de un solo archivo que manejará automáticamente la precompilación, por lo que el código compilado ya contiene la función de representación compilada en lugar de la cadena de plantilla original.

 

Si usa el paquete web y le gusta separar los archivos de plantilla y JavaScript, puede usar vue-template-loader, que también puede convertir archivos de plantilla en funciones de representación de JavaScript durante el proceso de compilación.

 

 

2.5, extrae el CSS del componente

Cuando se utiliza un componente de un solo archivo, el CSS del componente se inyectará dinámicamente a través de JavaScript en forma de etiquetas de estilo. Esto tiene una pequeña sobrecarga de tiempo de ejecución. Si utiliza la representación del lado del servidor, esto provocará un período de "parpadeo del contenido sin estilo (fouc)". Extraer el CSS de todos los componentes en el mismo archivo puede evitar este problema y también permitirá que CSS se comprima y almacene mejor en caché.

 

Consulte la documentación respectiva de esta herramienta de compilación para obtener más información:

  • webpack + vue-loader (la plantilla de paquete web de vue-cli ha sido preconfigurada)

  • Browserify + vueify

  • Rollup + rollup-plugin-vue

 

 

2.6, optimizar SourceMap

Después de empaquetar el proyecto, empaquetaremos los múltiples códigos de archivo en desarrollo en un solo archivo, y después de comprimir, eliminar espacios adicionales y compilar con babel, el código compilado finalmente se usará en el entorno en línea, luego habrá un gran diferencia entre el código procesado y el código fuente. Cuando hay un error, solo podemos ubicar la ubicación del código comprimido y no podemos ubicar el código en el entorno de desarrollo, lo cual no es fácil para el desarrollo. El problema, por lo que apareció sourceMap, es resolver el problema del código de depuración incorrecto.

 

Los valores opcionales de SourceMap son los siguientes (cuantos más signos +, más rápida es la velocidad, más signos, más lenta es la velocidad yo significa velocidad media)

imagen

Entorno de desarrollo recomendado: cheap-module-eval-source-map

Recomendación del entorno de producción: mapa de fuente de módulo barato

 

Las razones son las siguientes:

  • barato: la información de la columna en el código fuente no tiene ningún efecto. Por lo tanto, el archivo empaquetado no desea contener información relacionada con la columna. Solo la información de la fila puede establecer una relación de dependencia antes y después del empaquetado. Por lo tanto, ya sea un entorno de desarrollo o un entorno de producción, queremos agregar el tipo básico de barato para ignorar la información de la columna antes y después del empaque;

  • módulo: ya sea un entorno de desarrollo o un entorno formal, todos esperamos localizar la ubicación específica del código fuente del error. Por ejemplo, si un archivo Vue informa un error, esperamos localizar el archivo Vue específico, por lo que también necesitamos la configuración del módulo;

  • soure-map: source-map generará un archivo de sourcemap separado para cada módulo empaquetado, por lo que necesitamos agregar atributos de source-map;

  • eval-source-map: la velocidad del código de empaquetado eval es muy rápida, porque no genera un archivo de mapa, pero puede usar eval-source-map en combinación con eval. El archivo de mapa se almacenará en el archivo js empaquetado en forma de DataURL. No use eval-source-map en un entorno formal, porque aumentará el tamaño del archivo, pero en un entorno de desarrollo, puede probarlo porque se empaquetan rápidamente.

 

 

2.7 Análisis de salida de los resultados de la construcción

El código de salida de Webpack es muy legible y el archivo es muy grande, lo que nos da un dolor de cabeza. Para analizar los resultados de salida de manera más simple e intuitiva, han aparecido en la comunidad muchas herramientas de análisis visual. Estas herramientas muestran los resultados de forma más intuitiva de forma gráfica, lo que nos permite comprender rápidamente el problema. A continuación, explique la herramienta de análisis que usamos en el proyecto Vue: webpack-bundle-analyzer.

 

Configuramos webpack.prod.conf.js en el proyecto:

if (config.build.bundleAnalyzerReport) { var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; webpackConfig.plugins.push(new BundleAnalyzerPlugin());}
br

 

Después de ejecutar $ npm run build --report, el informe de análisis se genera de la siguiente manera:

imagen

 

2.8, optimización de la compilación del proyecto Vue

Si su proyecto de Vue está compilado con Webpack y requiere que tome una taza de café, entonces tal vez necesite optimizar la configuración de Webpack del proyecto para mejorar la eficiencia de la construcción de Webpack. Para obtener detalles sobre cómo optimizar la construcción de Webpack del proyecto Vue, consulte otro artículo del autor "Práctica de optimización de Webpack de Vue Project"

 

3. Optimización de la tecnología web básica

 

3.1, compresión gzip abierta

gzip es la abreviatura de GNUzip y se utilizó por primera vez para la compresión de archivos en sistemas UNIX. La codificación gzip en el protocolo HTTP es una tecnología que se utiliza para mejorar el rendimiento de las aplicaciones web. El servidor web y el cliente (navegador) deben admitir gzip juntos. Los navegadores convencionales actuales, Chrome, Firefox, IE, etc., son compatibles con este protocolo. Los servidores comunes como Apache, Nginx e IIS también lo admiten. La eficiencia de la compresión gzip es muy alta, generalmente alcanza una tasa de compresión del 70%. Es decir, si su página web tiene 30K, se convertirá en aproximadamente 9K después de la compresión. .

 

Tomemos como ejemplo el expreso del lado del servidor. Es muy sencillo abrir gzip. Los pasos relevantes son los siguientes:

instalación:

npm install compression --save
br

 

Agregar lógica de código:

var compression = require('compression');var app = express();app.use(compression())
br

 

Reinicie el servicio y observe el encabezado de respuesta en el panel de red. Si ve los siguientes campos en el círculo rojo, significa que gzip se ha abierto correctamente:

imagen

 

 

3.2, caché del navegador

Para mejorar la velocidad de carga de las páginas para los usuarios, es necesario almacenar en caché los recursos estáticos. Según sea necesario reiniciar las solicitudes al servidor o no, las reglas de almacenamiento en caché HTTP se dividen en dos categorías (caché obligatorio, en comparación con el almacenamiento en caché). Si no lo entiende muy claramente, puede consultar el artículo del autor sobre el almacenamiento en caché HTTP "Comprensión profunda de los mecanismos y principios del almacenamiento en caché HTTP", que no se repetirá aquí.

 

3.3 Uso de CDN

Los navegadores deben conectarse al servidor al descargar CSS, js e imágenes del servidor. La mayoría de los servidores tienen un ancho de banda limitado. Si se excede el límite, la página web no podrá responder durante medio día. CDN puede cargar archivos a través de diferentes nombres de dominio, lo que aumenta en gran medida la cantidad de conexiones simultáneas para descargar archivos, y CDN tiene mejor disponibilidad, menor retraso de red y tasa de pérdida de paquetes.

 

3.4. Utilice Chrome Performance para encontrar cuellos de botella en el rendimiento

El panel de rendimiento de Chrome puede registrar los detalles y el tiempo de ejecución de js dentro de un período de tiempo. Los pasos para analizar el rendimiento de la página con las herramientas de desarrollo de Chrome son los siguientes.

  • Abra Chrome Developer Tools y cambie al panel de rendimiento

  • Haga clic en Grabar para comenzar a grabar

  • Actualizar la página o expandir un nodo

  • Haga clic en Detener para detener la grabación

imagen

 

imagen

FIN

Los navegadores deben conectarse al servidor al descargar CSS, js e imágenes del servidor. La mayoría de los servidores tienen un ancho de banda limitado. Si se excede el límite, la página web no podrá responder durante medio día. CDN puede cargar archivos a través de diferentes nombres de dominio, lo que aumenta en gran medida la cantidad de conexiones simultáneas para descargar archivos, y CDN tiene mejor disponibilidad, menor retraso de red y tasa de pérdida de paquetes.

 

3.4. Utilice Chrome Performance para encontrar cuellos de botella en el rendimiento

El panel de rendimiento de Chrome puede registrar los detalles y el tiempo de ejecución de js dentro de un período de tiempo. Los pasos para analizar el rendimiento de la página con las herramientas de desarrollo de Chrome son los siguientes.

  • Abra Chrome Developer Tools y cambie al panel de rendimiento

  • Haga clic en Grabar para comenzar a grabar

  • Actualizar la página o expandir un nodo

  • Haga clic en Detener para detener la grabación

imagen

 

imagen

FIN

Supongo que te gusta

Origin blog.csdn.net/sqLeiQ/article/details/113110846
Recomendado
Clasificación