Cómo mejorar el rendimiento de las aplicaciones web front-end: cinco consejos



En muchos de mis proyectos front-end, en algún momento me enfrenté a una disminución en la productividad; esto generalmente ocurre cuando aumenta la complejidad de la aplicación, y esto es normal. Sin embargo, los desarrolladores siguen siendo responsables del rendimiento, por lo que en mi artículo daré cinco consejos para optimizar las aplicaciones que aplico yo mismo: algunos pueden parecer obvios, otros afectan los principios básicos de la programación, pero creo que refrescar la memoria no es superfluo será. Cada consejo está respaldado por pruebas: puede ejecutarlas usted mismo y probar el rendimiento.

Traducido a Alconost

Prólogo


Recuerde: si el código no necesita optimización, no entre en él. Por supuesto, el código que escriba debería funcionar rápidamente, y siempre puede encontrar un algoritmo más rápido, pero el escrito debe permanecer claro para otros desarrolladores. En la conferencia "Programación como arte", Donald Knuth expresó una idea muy importante sobre la optimización del código:

El verdadero problema era que los programadores pasaban demasiado tiempo preocupándose por la eficiencia en lugares inapropiados y en momentos inapropiados. La optimización prematura es la raíz de todos los errores de programación (o al menos la mayoría).

1. Búsqueda: en lugar de matrices ordinarias - objetos y matrices asociativas


Cuando se trabaja con datos, a menudo surgen situaciones en las que, por ejemplo, necesita encontrar un objeto, hacer algo con él, luego buscar otro objeto, etc. La estructura de datos más común en JS es una matriz, por lo que almacenar datos en ellos es una práctica normal. Sin embargo, cada vez que necesite encontrar algo en la matriz, debe usar métodos como "buscar", "indexOf", "filtro" o iterar con bucles, es decir, debe iterar sobre los elementos de principio a fin. Por lo tanto, realizamos una búsqueda lineal, cuya complejidad es 0 (n) (en el peor de los casos, necesitaremos realizar tantas comparaciones como elementos en la matriz). Si realiza esta operación un par de veces en arreglos pequeños, el impacto en el rendimiento será pequeño. Sin embargo, si tenemos muchos elementos, y la operación se realiza muchas veces, el rendimiento ciertamente fallará.

En este caso, será una buena solución convertir una matriz regular en un objeto o una matriz asociativa y realizar una búsqueda clave: en estas estructuras, se puede acceder a los elementos con complejidad O (1): tendremos una llamada de memoria, independientemente del tamaño. La mejora de la velocidad del trabajo se logra mediante el uso de una estructura de datos llamada tabla hash .

Puede probar el rendimiento aquí: https://jsperf.com/finding-element-object-vs-map-vs-array/1 . A continuación están mis resultados:



La diferencia es muy significativa: para una matriz asociativa y un objeto, obtuve millones de operaciones por segundo, mientras que para una matriz, el mejor resultado es un poco más de cien operaciones. Por supuesto, la conversión de datos no se tiene en cuenta aquí, pero incluso teniendo en cuenta su funcionamiento será mucho más rápido.

2. En lugar de excepciones, el operador condicional "if"


A veces parece más fácil omitir la comprobación nula y simplemente detectar las excepciones correspondientes. Esto, por supuesto, es un mal hábito: no necesita hacer esto, y si tiene uno en su código, simplemente vuelva a escribir las secciones correspondientes. Pero para convencerte por completo, apoyaré esta recomendación con pruebas. Decidí probar tres formas de hacer verificaciones: la expresión "try-catch", la condición "if" y el cálculo de "cortocircuito".

Prueba: https://jsperf.com/try-catch-vs-conditions/1 . A continuación están mis resultados:



Creo que es obvio a partir de aquí que es necesario verificar "nulo". Además, como puede ver, casi no hay diferencia entre la condición "si" y el cálculo del "cortocircuito", entonces aplique a lo que miente el alma.

3. Cuantos menos ciclos, mejor


Otra consideración obvia, pero quizás controvertida. Hay muchas funciones convenientes para las matrices: "mapa", "filtro", "reducir", por lo que su uso se ve atractivo, y el código con ellas se ve más ordenado y es más fácil de leer. Pero cuando surge la pregunta de mejorar la productividad, puede intentar reducir la cantidad de funciones llamadas. Decidí analizar dos casos: 1) "filtro", luego "mapa", y 2) "filtro", luego "reducir" - y compararlos con la cadena funcional, "forEach" y el bucle tradicional "for". ¿Por qué exactamente estos dos casos? De las pruebas se verá que los beneficios obtenidos pueden no ser muy significativos. Además, en el segundo caso, también intenté usar "filtro" cuando llamé a "reducir".

Prueba de rendimiento para "filtro" y "mapa": https://jsperf.com/array-function-chains-vs-single-loop-filter-map/1 . Mis resultados:



Se puede ver que un ciclo es más rápido, pero la diferencia es pequeña. La razón de una brecha tan pequeña es la operación de "empuje", que no es necesaria cuando se usa el "mapa". Por lo tanto, en este caso, puede pensar si realmente es necesario continuar con un ciclo.

Ahora revisemos "filtro" + "reducir": https://jsperf.com/array-function-chains-vs-single-loop-filter-reduce/1 . Mis resultados:



Aquí la diferencia ya es mayor: la combinación de dos funciones en una aceleró la ejecución en casi la mitad. Sin embargo, la transición al ciclo tradicional "for" da un aumento mucho más significativo en la velocidad.

4. Use regular para bucles


Este consejo también puede parecer controvertido, porque a los desarrolladores les encantan los ciclos funcionales: son bien leídos y pueden simplificar el trabajo. Sin embargo, son menos efectivos que los ciclos tradicionales. Creo que ya puede notar la diferencia en el uso de for loops, pero echemos un vistazo en una prueba por separado: https://jsperf.com/for-loops-in-few-different-ways/ . Como puede ver, además de los mecanismos integrados, también verifiqué "forEach" de la biblioteca "Lodash" y "each" de "jQuery". Resultados:



Y nuevamente vemos que el ciclo "para" más simple es mucho más rápido que el resto. Es cierto que estos bucles son buenos solo para matrices: en el caso de otros objetos iterables, debe usar "forEach", "for ... of" o el iterador en sí. Pero "for ... in" debe aplicarse solo si no hay otros métodos. Además, recuerde que "for ... in" acepta todas las propiedades del objeto (y en la matriz las propiedades son índices), lo que puede conducir a resultados impredecibles. Sorprendentemente, los métodos de Lodash y jQuery no fueron tan malos en términos de rendimiento, por lo que en algunos casos puede usarlos de forma segura en lugar del "forEach" incorporado (curiosamente, en la prueba, el bucle de Lodash funcionó más rápido que el incorporado).

5. Use las funciones integradas para trabajar con el DOM


A veces miras el código de otra persona y ves que el desarrollador importó jQuery solo para manipular el DOM; estoy seguro de que también lo has visto, porque esta es una de las bibliotecas de JavaScript más populares. Está claro que no hay nada de malo en usar bibliotecas para controlar el DOM: hoy usamos React y Angular, y ellos hacen lo mismo. Sin embargo, a veces a algunos les parece que jQuery debería usarse incluso para operaciones simples para extraer un elemento del DOM y realizar pequeños cambios en él.

Aquí hay una comparación de las funciones integradas para DOM y operaciones JQuery similares en tres casos diferentes: https://jsperf.com/native-dom-functions-vs-jquery/1 . Mis resultados:



Y de nuevo, las funciones más básicas - "getElementById" y "getElementsByClassName" - resultaron ser las más rápidas cuando se visualiza el DOM. En el caso de identificadores y selectores avanzados, querySelector también es más rápido que jQuery. Y en un solo caso es "querySelectorAll" más lento que jQuery (obteniendo elementos por nombre de clase). Para obtener más información sobre cómo y cómo reemplazar jQuery, consulte aquí: http://youmightnotneedjquery.com .

Está claro que si ya está utilizando la biblioteca para administrar el DOM, se recomienda encarecidamente que se adhiera a ella; sin embargo, para casos simples, las herramientas integradas son suficientes.

Materiales adicionales


Estos cinco consejos lo ayudarán a escribir un código JavaScript más rápido. Pero si está interesado en leer más sobre la optimización del rendimiento, aquí hay algunas recomendaciones:

1. Optimización de paquetes de JavaScript usando Webpack: este es un tema muy extenso, pero si todo se hace correctamente, la carga de aplicaciones puede acelerarse significativamente.

2. Estructuras de datos, algoritmos básicos y su complejidad: muchos creen que esto es "solo una teoría", pero en el primer párrafo vimos cómo funciona esta teoría en la práctica.

3. Pruebas en la página jsPerf : aquí puede familiarizarse con una comparación de diferentes formas de realizar la misma tarea en JavaScript y al mismo tiempo ver un indicador importante en la práctica: la diferencia de velocidad.

Sobre el traductor

El artículo fue traducido por Alconost.

Alconost localiza juegos , aplicaciones y sitios en 70 idiomas. Traductores en lengua nativa, pruebas lingüísticas, plataforma en la nube con API, localización continua, gestores de proyectos 24/7, cualquier formato de recursos de cadena.

También hacemos videos de publicidad y capacitación , para sitios que venden, imágenes, publicidad, capacitación, teasers, expliner, trailers de Google Play y App Store.

Leer más

Source: https://habr.com/ru/post/456808/


All Articles