Análisis estático en JavaScript: Lo fácil y lo difícil

Rate this content
Bookmark

Todos usamos herramientas de análisis estático como ESLint todos los días para garantizar una mejor calidad de nuestro código. ¿Cómo funciona y qué es complicado en JavaScript, lo que hace que escribir una regla adecuada a menudo no sea trivial?

23 min
05 Jun, 2023

Video Summary and Transcription

El análisis estático en JavaScript implica analizar el código fuente sin ejecutarlo, produciendo métricas, problemas o advertencias. El análisis del flujo de datos tiene como objetivo determinar los valores de los datos en un programa. La implementación de reglas en JavaScript puede ser sencilla o requerir una consideración exhaustiva de diversos casos y parámetros. La naturaleza dinámica e incierta de JavaScript hace que el análisis estático sea un desafío, pero puede mejorar en gran medida la calidad del código.

Available in English

1. Introducción al Análisis Estático en JavaScript

Short description:

Hola a todos. Mi nombre es Elena Vilchik y voy a hablarles sobre el análisis estático en JavaScript. Trabajo en la empresa Cynar, escribiendo analizadores para JavaScript y otros lenguajes. El análisis estático de código es un programa que analiza el código fuente sin ejecutarlo, produciendo métricas, problemas o advertencias. Es diferente del análisis dinámico, que ejecuta el código. Hay diferentes niveles de análisis estático, incluyendo análisis basado en texto, basado en tokens, árbol de sintaxis y análisis semántico. El análisis de flujo de control es un modelo menos utilizado.

Mi nombre es Elena Vilchik y voy a hablarles sobre el análisis estático en JavaScript. Así que, voy a hablar sobre lo que es fácil y lo que es difícil en esto. Un poco sobre mí, trabajo en la empresa Cynar. Estamos desarrollando una plataforma para la detección continua de calidad de código y seguridad. Llevo más de ocho años escribiendo analizadores para JavaScript y muchos otros lenguajes, y cuando se trata de código limpio, algunas personas pueden llamarme una molestia.

Antes de entrar en lo que es fácil y lo que es difícil, quiero contarles primero qué es el análisis estático de código. No todos pueden estar al tanto de eso. Un analizador de código estático es un programa, como podrán haber adivinado, que toma el código fuente , los archivos de texto del programa. A veces, para algunos lenguajes, toma algo más. Algunos archivos precompilados, por ejemplo, bytecode para Java, para obtener información semántica producida por el compilador. Y sin ejecutar realmente el código fuente, puede tener alguna imitación de la ejecución, pero nunca ejecuta realmente el código fuente, produce algunas métricas, problemas o advertencias, hallazgos, como quieran llamarlos. También pueden pensar, bueno, análisis estático, lo entiendo, entonces ¿qué es el análisis dinámico y si son direcciones competidoras de lo mismo, de hecho no, el análisis dinámico lo usan todos los días, esto es algo que realmente ejecuta un código y ejemplos también que son conocidos por todos, esto es la cobertura de código, estas son las pruebas unitarias, y en realidad estas dos cosas son necesarias para todos y grandes amigos y ayudantes de cada desarrollador en la vida cotidiana.

Voy a repasar los niveles de análisis estático, niveles en términos de los modelos que se utilizan para escribir. Vamos a utilizar el término regla que es familiar para todos. El primer nivel será basado en texto cuando solo obtienes el archivo fuente y tratas de inferir algo a partir de eso. Esto puede ser, por ejemplo, el número de líneas en el archivo o la presencia del encabezado de licencia. Para obtener esas cosas, no necesitas saber nada más que el texto del código fuente. El siguiente nivel serán los tokens. Los divides en palabras. Conoces algunos metadatos sobre esos tokens, si es una palabra clave, un dictador, y puedes saber, escribir algunas reglas en este nivel. Por ejemplo, para el literal de cadena, puedes decir que, okay, tengo este token literal y puedo decirte si está usando las comillas correctas, ya sea comillas simples o comillas dobles, lo que configures. El siguiente nivel es el árbol de sintaxis o árbol de sintaxis abstracta, AST por sus siglas en inglés. Esto es muy común, el nivel más utilizado donde representamos el código fuente en el formato de árbol. Aquí está el ejemplo, un poco simplificado por supuesto por la brevedad del código que acabamos de tener antes. Tenemos una función que tiene el nombre foo y el parámetro p que tiene un cuerpo. La declaración if tiene una condición con un operador de igualdad y esos tienen operandos, p falso y una llamada a la función. Así que para aquellos que no lo sabían, realmente recomendaría echar un vistazo al sitio web IST Explorer , un sitio web genial que te mostrará la representación AST del código fuente que pongas allí, muy útil incluso para investigar algunas características nuevas del lenguaje y ver qué es realmente lo que acabas de ingresar allí, qué tipo de sintaxis de lenguaje es. hay un nivel semántico, semántico estamos hablando de rivales, sus declaraciones, usos y en este nivel, por ejemplo, sabes que aquí está el parámetro P, se declara aquí, se usa aquí, luego está la función foo que se declara y se referencia en la última línea y la variable P que no es la misma que el parámetro P aunque tengan el mismo nombre, aquí se declaran en diferentes ámbitos, el ámbito es otra noción de este nivel y aquí se escribe y declara y aquí se lee. Y luego hablamos de modelos más avanzados que generalmente no se utilizan tanto como todos los anteriores, el más común de ellos es el análisis de flujo de control que está presente, por ejemplo, en el núcleo de ESLint.

2. Comprensión del Análisis de Flujo de Datos

Short description:

En este nivel, tenemos en cuenta el orden de ejecución de instrucciones, expresiones y declaraciones. El análisis de flujo de datos tiene como objetivo determinar los valores de los datos en un programa. El compilador de TypeScript realiza análisis de flujo de datos para verificar los tipos de variables basados en el flujo de control. Cada nivel se basa en el anterior, siendo el análisis de flujo de control un requisito previo para el análisis de flujo de datos.

En este nivel, tenemos en cuenta el orden de ejecución de instrucciones, la ejecución de expresiones y declaraciones, o nuestro ejemplo con la declaración if. Dentro de la función foo, tenemos la condición p igual a true y, dependiendo de si es verdadera, la mostraremos en un alert, si no, mostraremos en un alert que podemos salir también. Así que este es el último nivel del que quería hablar, el último modelo es el análisis de flujo de datos.

En este nivel, queremos conocer los valores, lo máximo que podemos aprender sobre los valores de los datos, en otras palabras, del programa. Por supuesto, no podemos saberlo todo porque nadie lo sabe todo hasta que realmente se ejecute el programa, pero podemos saber algo sobre los valores. Por ejemplo, en este bloque de código, si es igual a true, sabremos que p es en realidad un valor verdadero, en el else sabremos que no es verdadero. Fuera de este if, no sabremos nada sobre el valor de p. También puedes pensar en el compilador de TypeScript como un análisis de flujo de datos, porque eso es lo que hace. Observa el flujo de control del programa y verifica, según las diferentes declaraciones, diferentes expresiones, cuáles son los límites para el tipo de variable. Y aquí la noción entre valor y tipo es bastante difusa, debido a la forma en que TypeScript lo define. Y como habrás notado, cada nivel siguiente se basa en el anterior para poder construir el análisis de flujo de datos, necesitas tener necesariamente el análisis de flujo de control, y así sucesivamente.

3. Explorando la Implementación de Reglas en JavaScript

Short description:

Entonces, ¿qué es fácil en JavaScript? Su naturaleza dinámica y la abundancia de comportamientos extraños hacen que sea fácil generar ideas para reglas, especialmente para los recién llegados. La implementación de la mayoría de las reglas en los primeros niveles, como texto, tokens, IST y semántica, es sencilla. Por ejemplo, la regla No New Symbol de YesLint tiene una implementación corta y clara. Por otro lado, la regla lint.nonused.variable requiere una consideración exhaustiva de varios casos y parámetros, demostrando el principio de Pareto en la implementación de reglas. Ajustar la regla con diferentes opciones y casos especiales es crucial para obtener resultados óptimos. Esto incluye considerar las características del lenguaje, las prácticas de desarrollo y el uso de frameworks y bibliotecas.

Entonces, ahora comienzo a hablar sobre lo que es fácil. Lo que es fácil es que diría que JavaScript es un lenguaje que es súper dinámico, que tiene muchos comportamientos extraños, lo que nos da muchas ideas para las reglas, especialmente para las personas que son nuevas en el lenguaje. No muchas personas esperarían que X igual a null sea verdadero cuando x es indefinido, que X igual a null nunca sea verdadero, y que el signo más sea una concatenación cuando hay al menos un operando de cadena. Otra cosa sobre la facilidad es que la mayoría de las reglas se implementarán en los primeros niveles, en el texto, tokens, IST y semántica, y la implementación será bastante sencilla.

Tomé el ejemplo de la regla No New Symbol de YesLint. Esta regla te informa cada vez que usas un nuevo símbolo, lo cual producirá una excepción en tiempo de ejecución, ya que debes usar un símbolo incorporado sin new. Verás que la implementación es muy corta. Primero tienes el bloque de metadatos para la regla con descripción y mensaje. Y luego aquí está la implementación real de la regla, que consta de solo 20 líneas o incluso menos. Obtenemos del ámbito global todas las variables con nombre de símbolo, porque si estamos usando el símbolo incorporado, será del ámbito global. Luego verificamos que las definiciones sean cero, porque de lo contrario significaría que el símbolo es declarado por el usuario y necesitamos un símbolo incorporado. Luego iteramos en todas sus referencias y, para cada una, verificamos si es una nueva expresión, y se lo informamos al usuario. Así que sí, eso es todo, muy claro y como quisieras que se vea. Otro ejemplo que quería mostrarte es la regla lint.nonused.variable. Entonces, si piensas en cómo la implementaría, diría que estoy tomando cada variable del archivo y cuando solo tiene una declaración y cero usos, esta es en realidad una variable nueva y se puede eliminar. Ahora veamos cómo se implementa realmente la regla. Verás que la regla es bastante grande, y estoy desplazándome y desplazándome y desplazándome y desplazándome, y finalmente terminé las últimas 700 líneas de código. Así que podrías haber adivinado que esto no es solo lo que acabamos de decir acerca de las variables de llegada sin ningún uso con solo declaraciones. Hay muchas cosas que los desarrolladores de esta regla tuvieron que considerar. Tiene muchos parámetros sobre rest, destructuring, co-errores, arcos y algunas excepciones. Y creo que hay muchos casos diferentes más que tuvieron que considerar para poder tener una buena implementación. Ahí es cuando hablaré sobre el principio de Pareto, que es cierto para muchas cosas en nuestras vidas. Pero aquí también es cierto que, para muchas reglas, cuando la implementas, la implementación intuitiva básica, que es muy pequeña en términos de trabajo y que te brinda el 80% del resultado, es buena. Pero necesitas pasar el 80% de tu tiempo ajustando la regla, con diferentes opciones y casos especiales, que darán como resultado ese 20% de los resultados de la regla. Pero esto es esencial para hacer una buena regla. Y para ajustar la regla, puedes hacerlo por muchas razones. Por ejemplo, enumeré tres cosas. Aquí están las características del lenguaje, que son antiguas, o en el futuro opuesto, aún no se han lanzado como parte del ECMAScript oficial, o son recientes y no las tuviste en cuenta cuando quisiste implementar la regla. También podría haber algunas prácticas de desarrollo que son bastante comunes, pero yo, por ejemplo, no las escribiría de la forma en que se muestra en la condición if, escribiría dos líneas, y la regla sobre una declaración por línea no la informaría, pero muchas personas la escriben en una línea, y necesitamos excluirlo para no molestarlos. También hay muchos frameworks y bibliotecas que, cuando los

4. Desafíos en el Análisis Estático de JavaScript

Short description:

Otras reglas sobre el tamaño de las funciones, como el número de declaraciones o líneas, pueden ser excluidas para eliminar el ruido. La ausencia de tipos en JavaScript hace que el análisis estático sea desafiante. La regla de retorno de línea es un ejemplo de una regla que está desactivada de forma predeterminada. Detecta el uso incorrecto de la función map y reporta cualquier uso, independientemente de la estructura similar a un array. La implementación de esta regla tiene limitaciones, lo que lleva a su desactivación predeterminada. Se pueden considerar diferentes estrategias y heurísticas para esta regla, cada una con sus ventajas y desventajas en términos de verdaderos positivos y falsos positivos.

úsalas, necesitas hacer algo que haga que las reglas se quejen. Por ejemplo, otras reglas sobre el tamaño de las funciones, como el número de declaraciones o líneas, o lo que sea, para los componentes funcionales de React, ya que son una especie de contenedor para otras funciones, serán bastante grandes, y las reportaremos. Necesitamos excluirlos para eliminar ese ruido. Otra cosa que es difícil en el análisis estático de JavaScript es la ausencia de tipos. Tomé como ejemplo una regla llamada regla de retorno de línea. Es posible que nunca hayas oído hablar de esto, porque está desactivada de forma predeterminada en el perfil recomendado. Cuando tienes un array y quieres operar en él, por ejemplo, aquí, simplemente estoy sumando todos los valores y usando la función map que funcionará, algo que mucha gente hace, lo estoy observando una y otra vez. De hecho, esto es un uso incorrecto de la función map, y algunas personas, los otros mantenedores, podrían verlo y decir, está bien, ¿a qué estás mapeando? ¿A qué? No estás devolviendo nada. Deberías devolver algo para poder usar map. Si no quieres mapear nada, simplemente usa for reach. Y, de hecho, si revisas cómo se implementa esta regla, se supone que solo informará sobre arrays y estructuras similares a arrays, pero te informará sobre cualquier cosa que esté allí. Solo verifica el nombre de la función. Así que esta es una implementación bastante tonta, diría yo, y esta es una estrategia de caso, que usamos a menudo en nuestra empresa, que si funciona, ¿por qué no? Pero como no es lo suficientemente bueno para la mayoría de los usuarios, durante años los mantenedores han optado por desactivar la regla de forma predeterminada. Es muy triste que una regla como esta, que tiene un gran valor, tenga que ser desactivada debido a esta limitación. Puedes pensar en otras estrategias de reglas para esta regla. Puedes pensar en verificar a qué objeto se asigna, si se asigna a un objeto, un verdadero ensayo, lo informarás. Y ahí es donde entra en juego, aquí hay otra cosa que debes elegir la mejor heurística. Y ten en cuenta que cuando estás en este caso, cuando eligieron informar sobre cada uso de map, tiene muchos problemas de verdaderos positivos. Informará sobre todos los casos que desees, pero también informará muchos falsos positivos. Así que hay una dependencia bastante lineal aquí. Si eliges informar solo sobre aquellas variables que se asignan a un literal de array, como en mi ejemplo, informará solo una fracción muy pequeña, una fracción de verdaderos positivos, pero luego no tendremos prácticamente ningún falso positivo, porque estamos seguros de que nunca informaremos sobre

5. Análisis Estático: Desafíos y Técnicas

Short description:

La naturaleza dinámica e incierta de JavaScript dificulta la detección de errores. Un ejemplo es la regla 'no argumentos adicionales', que informa cuando una función se llama con más argumentos de los que espera. La implementación de esta regla se vuelve más compleja al tratar con funciones exportadas o importadas, devoluciones de llamada o funciones con parámetros desconocidos. Técnicas avanzadas, como la detección de variables no utilizadas, requieren la implementación de análisis de variables y gráficos de flujo de control. Escribir reglas estáticas puede ser difícil, como lo demuestra el gran número de instancias de YesLingDisabled en GitHub. Comprender el análisis estático y utilizar herramientas de análisis estático puede mejorar en gran medida la calidad del código.

cualquier cosa excepto arrays. Otra cosa sobre JavaScript es que es dinámico y nunca sabes, nunca puedes estar seguro de nada. Un ejemplo es 'no argumentos adicionales'. Esta es una regla de nuestro complemento de mi empresa. Esta regla informa cuando usas una función que tiene menos argumentos de los que estás llamando. En caso de que sea solo una variable local, una función local, esto funciona perfectamente, pero probablemente no sea así cuando cometas este error porque tienes esta declaración de función justo al lado, pero puse un ejemplo cuando la función se exporta o se importa desde otro modelo o archivo, o tienes una devolución de llamada y no tienes control sobre cuántos parámetros hay, es cuando puedes cometer fácilmente este error, pero la implementación de esta regla no puede saber eso. Y al final quería hablar sobre técnicas avanzadas, así que cuando hablábamos de modelos, estábamos hablando de algo grande, que usarás para muchas reglas, como el flujo de control, el gráfico o el análisis de flujo de datos. Aquí estoy hablando de literalmente una técnica, que es útil para básicamente una regla. Esta regla que tomé como ejemplo es la detección de variables no utilizadas y creo que es realmente interesante. Esta regla se supone que detecta, voy a mostrar en este ejemplo, cuando estás escribiendo el valor, por ejemplo, aquí asignas x igual a cero, y de hecho, lo siguiente que vas a hacer es x igual 10, asignar 10, lo que significa que esta asignación en realidad nunca se usa, y este cero es una variable no utilizada. Esto a menudo, en algunos casos, puedes simplemente eliminar la línea y decir que, bueno, en realidad no necesito esta asignación, pero a menudo significa otra cosa, que realmente hiciste mal tu algoritmo. Y para implementar esa variable no utilizada, necesitas implementar el análisis de variables que calcula las variables que dejo en cada punto del programa, por lo que todo lo que no es dejado está muerto, eso es solo una copia y pega de Wikipedia, y una variable se deja en algún punto si tiene un valor que puede ser necesario en el futuro. Entonces, en este ejemplo, vemos que, bueno, el cero nunca será necesario en el futuro porque será sobrescrito justo después de eso. Para ver cómo detectar esa variable no utilizada, echemos un vistazo a este pequeño fragmento de código. Aquí tengo muchas asignaciones y asignaciones, lectura, asignación, lectura, así que lo representé como un gráfico de flujo de control con una rama en el EVE, y luego hacemos dos cosas, y luego volvemos a fusionar. Aquí no nos importan las cosas reales para poder informar sobre esta regla, solo necesitamos saber sobre la escritura y lectura de las variables. En este caso, consideramos solo la variable X, y si intentamos, para encontrar la variable no utilizada, lo que necesitamos encontrar es que necesitamos encontrar esas escrituras que no tienen ningún camino en el flujo de control gráfico que lo leerá después. Así que digamos que si encontramos el camino en el gráfico de llamadas que leerá el valor, esto no es una variable no utilizada. Entonces, si tomamos la primera, la de arriba, tiene este flujo hacia esta lectura. Si tomamos esta escritura a la izquierda, tiene un... así que si tomamos la de la izquierda, de hecho vemos que no tiene ningún flujo en el gráfico que lo leerá porque solo tiene un flujo y lo escribe, así que podemos decir que está bien, esta es una variable no utilizada. Y la siguiente escritura aquí, se leerá en la siguiente instrucción en el mismo bloque. Así que esta es solo una implementación intuitiva de la regla para este caso particular y para generalizarla y tener la implementación genérica, esto es lo que necesitas implementar. Esta es una captura de pantalla de Wikipedia donde ves que necesitas tener algunas fórmulas con conjuntos y cada vez que necesité implementar esta variable no utilizada, me llevó todo un día cargarlo en mi cabeza y luego lo olvidé en una semana. Así que quería terminar con la captura de pantalla de GitHub con el número de YesLingDisable y en el código, ves que hay casi tres millones de YesLingDisabled, creo que hay muchos más en código privado, lo que significa que sí, no es tan fácil escribir reglas estáticas. La gente necesita desactivarlas porque no están satisfechos con los resultados. Y esto es solo un falso positivo, aquí, nunca podemos decir cuántos falsos negativos hay porque nadie es capaz de verlos. Y como conclusión de mi charla, quería decirles que ustedes saben cómo funciona el análisis estático y qué es el árbol de sintaxis abstracta, así que siéntanse libres de contribuir, escribir reglas personalizadas si necesitan algunas, esas reglas pueden ser fáciles de escribir, así que no tengan miedo, simplemente háganlo. Y por otro lado, si les gustan los desafíos, si les gusta algo, aquí hay algo difícil de hacer, el análisis estático también es el lugar para ustedes, así que échenle un vistazo, especialmente a las técnicas más avanzadas. Y, por supuesto, usen herramientas de análisis estático, esto realmente les ayudará en la calidad de su código. Eso es todo por mi parte. Muchas gracias y que tengan un buen día.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

JSNation 2023JSNation 2023
29 min
Modern Web Debugging
Few developers enjoy debugging, and debugging can be complex for modern web apps because of the multiple frameworks, languages, and libraries used. But, developer tools have come a long way in making the process easier. In this talk, Jecelyn will dig into the modern state of debugging, improvements in DevTools, and how you can use them to reliably debug your apps.
JSNation 2022JSNation 2022
21 min
The Future of Performance Tooling
Top Content
Our understanding of performance & user-experience has heavily evolved over the years. Web Developer Tooling needs to similarly evolve to make sure it is user-centric, actionable and contextual where modern experiences are concerned. In this talk, Addy will walk you through Chrome and others have been thinking about this problem and what updates they've been making to performance tools to lower the friction for building great experiences on the web.
React Summit 2023React Summit 2023
24 min
Debugging JS
As developers, we spend much of our time debugging apps - often code we didn't even write. Sadly, few developers have ever been taught how to approach debugging - it's something most of us learn through painful experience.  The good news is you _can_ learn how to debug effectively, and there's several key techniques and tools you can use for debugging JS and React apps.
DevOps.js Conf 2022DevOps.js Conf 2022
31 min
pnpm – a Fast, Disk Space Efficient Package Manager for JavaScript
You will learn about one of the most popular package managers for JavaScript and its advantages over npm and Yarn.A brief history of JavaScript package managersThe isolated node_modules structure created pnpmWhat makes pnpm so fastWhat makes pnpm disk space efficientMonorepo supportManaging Node.js versions with pnpm
JSNation 2023JSNation 2023
31 min
Rome, a Modern Toolchain!
Modern JavaScript projects come in many shapes: websites, web applications, desktop apps, mobile apps, and more. For most of them, the common denominator is the technical debt that comes from settings up tools: bundlers, testing suite, code analysis, documentation, etc. I want to present you Rome, a toolchain that aims to be a all-in-one toolchain for the web, with one single tool you can maintain the health of all your projects!
React Advanced Conference 2021React Advanced Conference 2021
27 min
Beyond Virtual Lists: How to Render 100K Items with 100s of Updates/sec in React
Top Content
There is generally a good understanding on how to render large (say, 100K items) datasets using virtual lists, …if they remain largely static. But what if new entries are being added or updated at a rate of hundreds per second? And what if the user should be able to filter and sort them freely? How can we stay responsive in such scenarios? In this talk we discuss how Flipper introduced map-reduce inspired FSRW transformations to handle such scenarios gracefully. By applying the techniques introduced in this talk Flipper frame rates increased at least 10-fold and we hope to open-source this approach soon.

Workshops on related topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2023React Advanced Conference 2023
148 min
React Performance Debugging
Workshop
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
JSNation 2022JSNation 2022
71 min
The Clinic.js Workshop
Workshop
Learn the ways of the clinic suite of tools, which help you detect performance issues in your Node.js applications. This workshop walks you through a number of examples, and the knowledge required to do benchmarking and debug I/O and Event Loop issues.
JSNation 2023JSNation 2023
44 min
Solve 100% Of Your Errors: How to Root Cause Issues Faster With Session Replay
WorkshopFree
You know that annoying bug? The one that doesn’t show up locally? And no matter how many times you try to recreate the environment you can’t reproduce it? You’ve gone through the breadcrumbs, read through the stack trace, and are now playing detective to piece together support tickets to make sure it’s real.
Join Sentry developer Ryan Albrecht in this talk to learn how developers can use Session Replay - a tool that provides video-like reproductions of user interactions - to identify, reproduce, and resolve errors and performance issues faster (without rolling your head on your keyboard).