Detectar y evitar problemas comunes de rendimiento y memoria en compilaciones de Unity WebGL

Rate this content
Bookmark

Esta sesión explora problemas comunes de rendimiento y memoria que surgen en las compilaciones WebGL producidas con el motor de juego Unity. Examine cómo identificar, solucionar y evitar trampas que pueden llevar a errores de falta de memoria. Aprenda a reducir la inestabilidad del juego y mejorar el rendimiento del juego en las compilaciones WebGL.

This talk has been presented at JS GameDev Summit 2022, check out the latest edition of this JavaScript Conference.

FAQ

Los problemas de memoria en compilaciones de Unity WebGL pueden surgir debido a la cantidad limitada de memoria asignada por el navegador, que varía según el dispositivo, sistema operativo, navegador utilizado y si es de 32 o 64 bits. Estos problemas pueden afectar la complejidad del contenido que se puede ejecutar y causar ralentización o bloqueos del juego.

En Unity WebGL, la gestión de la memoria puede mejorarse utilizando técnicas como los paquetes de activos, que permiten cargar y descargar activos a demanda, y el sistema de archivos de memoria virtual que desempaqueta los activos en tiempo de ejecución, evitando asignaciones extra por parte del navegador.

El montón de Unity es un bloque contiguo de memoria donde se almacenan todos los objetos en tiempo de ejecución en una compilación WebGL, incluyendo objetos nativos, activos cargados, escenas, shaders y archivos de animación. Gestionar adecuadamente el tamaño del montón es crucial para prevenir bloqueos del juego y optimizar el rendimiento.

Para reducir el uso de memoria en WebGL, se pueden adoptar estrategias como la utilización de paquetes de activos para manejar recursos frecuentes pero grandes, el uso de un sistema direccionable como alternativa a los paquetes de activos, y optimizar el código para minimizar las nuevas asignaciones de memoria como evitar la manipulación frecuente de cadenas.

La recolección de basura (GC) en WebGL se ejecuta una vez después de cada fotograma, ya que las limitaciones de JavaScript impiden pausar todos los hilos como en otras plataformas. Esta ejecución controlada ayuda a prevenir interrupciones inesperadas pero requiere que el código esté optimizado para reducir la frecuencia de la GC y mejorar el rendimiento.

Herramientas como Backtrace son útiles para depurar problemas de rendimiento y memoria en Unity WebGL. Permiten a los desarrolladores ver errores en tiempo real y analizar información del rendimiento del juego para identificar y solucionar problemas antes de que se intensifiquen.

Oz Syed
Oz Syed
10 min
07 Apr, 2022

Comments

Sign in or register to post your comment.
Video Summary and Transcription
La charla de hoy se centra en evitar problemas de rendimiento y memoria en las compilaciones de Unity WebGL. Se destaca la importancia de administrar la memoria y mantener pequeño el tamaño del montón. Técnicas como el uso de paquetes de activos o un sistema direccionable pueden ayudar a reducir el uso de la memoria. Se discuten las limitaciones de la recolección de basura en las compilaciones WebGL, junto con consejos para optimizar el código de Unity. Herramientas como Backtrace pueden ayudar en la depuración de problemas de memoria y rendimiento.

1. Introducción a las compilaciones de Unity WebGL

Short description:

Hoy, vamos a ver algunas de las formas en que podemos evitar problemas comunes de rendimiento y memoria que surgen en las compilaciones de Unity WebGL. La memoria es una restricción importante cuando se ejecuta una compilación de WebGL en un navegador. El montón de Unity es donde se almacenan todos los objetos en tiempo de ejecución, y es importante mantener el tamaño del montón lo más pequeño posible. Al construir una aplicación WebGL, Unity genera un archivo .data que contiene todos los activos y escenas requeridos. Para reducir el uso de memoria, puedes usar paquetes de activos o un sistema direccionable. La recolección de basura también es una consideración importante en las compilaciones de WebGL.

♪♪ Hola a todos. Mi nombre es Oz, y soy un evangelista de desarrollo de juegos en Backtrace Source Labs. Hoy, vamos a ver algunas de las formas en que podemos evitar problemas comunes de performance y memoria que surgen en las compilaciones de Unity WebGL. El primer punto que vamos a examinar es la gestión del performance. Y una restricción importante al ejecutar una compilación de WebGL en un navegador con buen performance es la memoria. Entonces, en términos de memoria, ¿cuáles son los problemas y cuáles son las consideraciones que debemos examinar?

Entonces, como sabes, la complejidad del contenido que puedes ejecutar está limitada por la memoria. La memoria es asignada por el navegador, y la cantidad de memoria que tiene disponible varía en función de varios factores, incluyendo el dispositivo que usas, el sistema operativo que usas, qué navegador usas, y si se ejecuta en un navegador de 32 bits o de 62 bits, y un par de otros factores. Entonces, para entender cómo la memoria impacta en el performance, es muy importante primero ver cómo se asigna la memoria en una compilación de Unity WebGL. Para esto, necesitamos echar un vistazo al montón de Unity. Entonces, ¿qué es el montón de Unity o un montón de memoria, como lo llama Unity? Básicamente, aquí es donde se almacenan todos los objetos en tiempo de ejecución, y estos podrían incluir objetos nativos, activos que se cargan, escenas, shaders, archivos de animation, así como otros objetos gestionados. Vale la pena mencionar que este montón es un bloque contiguo de memoria asignada. Hasta hace unos años, tenías que asignar el tamaño máximo del montón en la configuración de la compilación, pero ahora, Unity soporta la expansión del montón a demanda, dependiendo de las necesidades del juego, y es expandible hasta dos juegos. Sin embargo, la misma característica puede hacer que tu juego se bloquee, especialmente cuando el navegador falla al asignar un bloque contiguo de memoria, y es exactamente por eso que es muy importante mantener el tamaño del montón lo más pequeño posible.

Ahora, para entender cómo podemos mantener el tamaño del montón de memoria pequeño, primero tenemos que echar un vistazo a lo que Unity hace con todos los activos y los datos de la escena en un navegador, y qué sucede cuando construyes una aplicación WebGL en Unity. Entonces, cuando construyes una aplicación WebGL, lo que sucede es que Unity genera un archivo .data. Y esto es básicamente todos los activos y escenas en la aplicación que se requieren en el momento del lanzamiento, y todo eso se empaqueta en un archivo .data, incluyendo las escenas de Unity, texturas, modelos, precios de UI, activos de audio, shaders, y prácticamente todo lo demás que necesitas para que el juego funcione. Y básicamente Unity WebGL no tiene acceso a un sistema de archivos real, por lo que tiene que crear un sistema de archivos de memoria virtual, y el navegador luego desempaqueta el archivo .data en este sistema de archivos virtual particular. Y el navegador, mientras el juego está en ejecución, mantiene los data sin comprimir. Ahora imagina si tienes una escena compleja con todo tipo de activos, ¿verdad? Incluyendo modelos 3D, shaders, todo. Entonces puedes ver cómo posiblemente puede tener problemas de memoria y también ralentizar el rendimiento del juego. Entonces la pregunta que surge es, ¿qué puedes hacer para reducir la memoria? Bueno, hay algunas técnicas que puedes adoptar para reducir el uso de memoria. Y una forma, la más común, es usar paquetes de activos. Entonces podrías poner todos los activos más frecuentes, pero más grandes en un paquete de activos y cargarlo, descargarlo a demanda cuando quieras. También vale la pena mencionar que los paquetes de activos se descargan directamente en el montón de Unity y por lo tanto evitan la asignación extra realizada por un navegador. Si hay paquetes grandes, una técnica es posiblemente almacenar en caché los data y esto es básicamente una cosa adicional que te ayuda a evitar la descarga cada vez que realmente juegas el juego. Entonces el tercero es algo llamado sistema direccionable, que es una alternativa a los paquetes de activos. Y a veces se inicia como una versión mejor de los paquetes de activos. Sin embargo, tiene algunos de sus propios problemas, incluyendo el soporte de las compilaciones de WebGL de serie. Pero existen algunas soluciones para hacerlo funcionar. La próxima consideración importante con respecto a las compilaciones de WebGL es la recolección de basura o GC en resumen.

2. Gestión de Memoria y Depuración en Unity WebGL

Short description:

GC en Unity WebGL se ejecuta una vez después de cada fotograma debido a las limitaciones en JavaScript. Manipular cadenas puede causar problemas de rendimiento y de memoria. Ejemplos incluyen la actualización de un texto de temporizador de cuenta regresiva y el uso de enlarged para un bucle. Para optimizar el código de Unity, use StringBuilder para la manipulación de cadenas, cache las matrices antes de iterar y use CompareTag en lugar de comparar cadenas. Herramientas como Backtrace pueden ayudar a depurar problemas de memoria y rendimiento. Si tienes preguntas sobre WebGL o Unity, no dudes en ponerte en contacto.

Entonces, típicamente lo que hace GC es localizar y recoger la memoria no utilizada y luego reasignarla al montón de Unity. En otras plataformas, cuando se ejecuta GC, todos los hilos en ejecución se pausan para dar tiempo para que GC revise la pila. Esto no es posible en WebGL debido a las limitaciones en JavaScript. Entonces, lo que hace Unity aquí es simplemente ejecutarlo una vez después de cada fotograma porque la condición para que GC se ejecute en WebGL es que la pila tiene que estar vacía y esto solo sucede después de que se renderiza cada fotograma.

Ahora veremos algunos ejemplos de code que aumentan GC y reducen el performance y cómo podemos realmente escribir un mejor code. Entonces, en el primer ejemplo que tengo aquí, puedes ver cómo la manipulación de una cadena es una causa principal de problema de performance y a veces también puede causar que una aplicación se quede sin memoria. Y la razón principal por la que esto sucede es porque cualquier manipulación de cadena hace que Unity cree una nueva cadena cada vez y esto puede sumar rápidamente. Por ejemplo, si el code fuera parte del bucle de actualización. Este ejemplo que puedes ver aquí es donde tienes un temporizador de cuenta regresiva mostrando en un UI y el texto del temporizador de cuenta regresiva se está actualizando continuamente en el bucle de actualización al agregar el prefijo de cuenta regresiva con el valor de cuenta regresiva. Y cada vez que haces eso, está creando una nueva cadena que puede sumar rápidamente y no es bueno para la memoria. A la derecha, puedes ver cómo este code se está reescribiendo en un mejor code donde separamos la etiqueta y el valor y por lo tanto evitamos la manipulación de la cadena por completo. Aquí hay otro ejemplo de manipulación de cadena. Si se está utilizando enlarged para un bucle. Ya sabes, en una compilación no-WebGL, esto podría funcionar tan bien como podría ser porque el recolector de basura estará involucrado pero no tanto en una compilación de WebGL porque en una compilación de WebGL no tiene la oportunidad de involucrarse hasta el final del fotograma y por lo tanto es probable que se quede sin memoria y se bloquee. Aquí tengo algunos otros ejemplos donde puedes optimizar el code de Unity para reducir la asignación de memoria y reducir la necesidad de recolección de basura frecuente. Entonces, cuando usas cadenas, por ejemplo, si necesitas manipular y pegar cadena, usa StringBuilder en lugar de Plus. Si estás usando funciones de Unity donde la función devolvería una matriz y tienes que hacer algunas manipulaciones de matriz o iterar a través de una matriz, deberías almacenarla en caché antes de usarla en un bucle for. Para comparaciones como comparar un nombre o etiqueta, no muchos de nosotros sabemos que estos accesorios en realidad devuelven una nueva cadena cada vez, por lo que es mejor usar, por ejemplo, para comparar con una etiqueta, usa la función CompareTag. Y por último, pero no menos importante, en el caso de las coroutines, una cosa común que tendemos a hacer como programadores es usar una línea que devuelve new WaitForSeconds o WaitUntil o WaitWhile. Así que en su lugar, almacénalo en caché y úsalo, especialmente si lo estás usando en un bucle for.

Mientras hablamos de las formas en que la memoria puede ser gestionada en algunas situaciones y cómo podemos reducir el uso de memoria, hay algunas situaciones inesperadas que pueden hacer que las aplicaciones se queden sin memoria o incluso hacer que las aplicaciones se bloqueen, así que aquí es donde las herramientas que pueden ayudar a debugging estos problemas entran en juego. Así que una de esas herramientas es Backtrace, que uso en las aplicaciones y juegos que hago para cualquier plataforma. Y por supuesto, WebGL no es una excepción. Así que cuando lo integro, puedo ver errores en tiempo real y en el panel de control y me ayuda a solucionar problemas de performance y de falta de memoria. Cosas como las que vemos hoy, estas pueden ser realmente utilizadas y luego esa información puede ser recogida para solucionar problemas futuros antes de que se salgan de control.

Eso es prácticamente el final de la masterclass. Si tienes alguna pregunta sobre WebGL o Unity, no dudes en ponerte en contacto conmigo. Mis datos de contacto están en esta diapositiva. Gracias por sintonizar. ♪♪♪

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

Una Guía del Comportamiento de Renderizado de React
React Advanced 2022React Advanced 2022
25 min
Una Guía del Comportamiento de Renderizado de React
Top Content
This transcription provides a brief guide to React rendering behavior. It explains the process of rendering, comparing new and old elements, and the importance of pure rendering without side effects. It also covers topics such as batching and double rendering, optimizing rendering and using context and Redux in React. Overall, it offers valuable insights for developers looking to understand and optimize React rendering.
Acelerando tu aplicación React con menos JavaScript
React Summit 2023React Summit 2023
32 min
Acelerando tu aplicación React con menos JavaScript
Top Content
Mishko, the creator of Angular and AngularJS, discusses the challenges of website performance and JavaScript hydration. He explains the differences between client-side and server-side rendering and introduces Quik as a solution for efficient component hydration. Mishko demonstrates examples of state management and intercommunication using Quik. He highlights the performance benefits of using Quik with React and emphasizes the importance of reducing JavaScript size for better performance. Finally, he mentions the use of QUIC in both MPA and SPA applications for improved startup performance.
Concurrencia en React, Explicada
React Summit 2023React Summit 2023
23 min
Concurrencia en React, Explicada
Top Content
React 18's concurrent rendering, specifically the useTransition hook, optimizes app performance by allowing non-urgent updates to be processed without freezing the UI. However, there are drawbacks such as longer processing time for non-urgent updates and increased CPU usage. The useTransition hook works similarly to throttling or bouncing, making it useful for addressing performance issues caused by multiple small components. Libraries like React Query may require the use of alternative APIs to handle urgent and non-urgent updates effectively.
El Futuro de las Herramientas de Rendimiento
JSNation 2022JSNation 2022
21 min
El Futuro de las Herramientas de Rendimiento
Top Content
Today's Talk discusses the future of performance tooling, focusing on user-centric, actionable, and contextual approaches. The introduction highlights Adi Osmani's expertise in performance tools and his passion for DevTools features. The Talk explores the integration of user flows into DevTools and Lighthouse, enabling performance measurement and optimization. It also showcases the import/export feature for user flows and the collaboration potential with Lighthouse. The Talk further delves into the use of flows with other tools like web page test and Cypress, offering cross-browser testing capabilities. The actionable aspect emphasizes the importance of metrics like Interaction to Next Paint and Total Blocking Time, as well as the improvements in Lighthouse and performance debugging tools. Lastly, the Talk emphasizes the iterative nature of performance improvement and the user-centric, actionable, and contextual future of performance tooling.
Optimización de juegos HTML5: 10 años de aprendizaje
JS GameDev Summit 2022JS GameDev Summit 2022
33 min
Optimización de juegos HTML5: 10 años de aprendizaje
Top Content
PlayCanvas is an open-source game engine used by game developers worldwide. Optimization is crucial for HTML5 games, focusing on load times and frame rate. Texture and mesh optimization can significantly reduce download sizes. GLTF and GLB formats offer smaller file sizes and faster parsing times. Compressing game resources and using efficient file formats can improve load times. Framerate optimization and resolution scaling are important for better performance. Managing draw calls and using batching techniques can optimize performance. Browser DevTools, such as Chrome and Firefox, are useful for debugging and profiling. Detecting device performance and optimizing based on specific devices can improve game performance. Apple is making progress with WebGPU implementation. HTML5 games can be shipped to the App Store using Cordova.
How React Compiler Performs on Real Code
React Advanced 2024React Advanced 2024
31 min
How React Compiler Performs on Real Code
Top Content
I'm Nadia, a developer experienced in performance, re-renders, and React. The React team released the React compiler, which eliminates the need for memoization. The compiler optimizes code by automatically memoizing components, props, and hook dependencies. It shows promise in managing changing references and improving performance. Real app testing and synthetic examples have been used to evaluate its effectiveness. The impact on initial load performance is minimal, but further investigation is needed for interactions performance. The React query library simplifies data fetching and caching. The compiler has limitations and may not catch every re-render, especially with external libraries. Enabling the compiler can improve performance but manual memorization is still necessary for optimal results. There are risks of overreliance and messy code, but the compiler can be used file by file or folder by folder with thorough testing. Practice makes incredible cats. Thank you, Nadia!

Workshops on related topic

Masterclass de Depuración de Rendimiento de React
React Summit 2023React Summit 2023
170 min
Masterclass de Depuración de Rendimiento de React
Top Content
Featured WorkshopFree
Ivan Akulov
Ivan Akulov
Los primeros intentos de Ivan en la depuración de rendimiento fueron caóticos. Vería una interacción lenta, intentaría una optimización aleatoria, vería que no ayudaba, y seguiría intentando otras optimizaciones hasta que encontraba la correcta (o se rendía).
En aquel entonces, Ivan no sabía cómo usar bien las herramientas de rendimiento. Haría una grabación en Chrome DevTools o React Profiler, la examinaría, intentaría hacer clic en cosas aleatorias, y luego la cerraría frustrado unos minutos después. Ahora, Ivan sabe exactamente dónde y qué buscar. Y en esta masterclass, Ivan te enseñará eso también.
Así es como va a funcionar. Tomaremos una aplicación lenta → la depuraremos (usando herramientas como Chrome DevTools, React Profiler, y why-did-you-render) → identificaremos el cuello de botella → y luego repetiremos, varias veces más. No hablaremos de las soluciones (en el 90% de los casos, es simplemente el viejo y regular useMemo() o memo()). Pero hablaremos de todo lo que viene antes - y aprenderemos a analizar cualquier problema de rendimiento de React, paso a paso.
(Nota: Esta masterclass es más adecuada para ingenieros que ya están familiarizados con cómo funcionan useMemo() y memo() - pero quieren mejorar en el uso de las herramientas de rendimiento alrededor de React. Además, estaremos cubriendo el rendimiento de la interacción, no la velocidad de carga, por lo que no escucharás una palabra sobre Lighthouse 🤐)
Crea un Juego Con PlayCanvas en 2 Horas
JSNation 2023JSNation 2023
116 min
Crea un Juego Con PlayCanvas en 2 Horas
Top Content
Featured WorkshopFree
Steven Yau
Steven Yau
En esta masterclass, construiremos un juego utilizando el motor WebGL de PlayCanvas desde el principio hasta el final. Desde el desarrollo hasta la publicación, cubriremos las características más cruciales como la escritura de scripts, la creación de UI y mucho más.
Tabla de contenido:- Introducción- Introducción a PlayCanvas- Lo que vamos a construir- Agregando un modelo de personaje y animación- Haciendo que el personaje se mueva con scripts- 'Falsa' carrera- Agregando obstáculos- Detectando colisiones- Agregando un contador de puntuación- Fin del juego y reinicio- ¡Resumen!- Preguntas
Nivel de la masterclassSe recomienda familiaridad con los motores de juegos y los aspectos del desarrollo de juegos, pero no es obligatorio.
Construyendo aplicaciones web que iluminan Internet con QwikCity
JSNation 2023JSNation 2023
170 min
Construyendo aplicaciones web que iluminan Internet con QwikCity
Featured WorkshopFree
Miško Hevery
Miško Hevery
Construir aplicaciones web instantáneas a gran escala ha sido elusivo. Los sitios del mundo real necesitan seguimiento, análisis y interfaces y interacciones de usuario complejas. Siempre comenzamos con las mejores intenciones pero terminamos con un sitio menos que ideal.
QwikCity es un nuevo meta-framework que te permite construir aplicaciones a gran escala con un rendimiento de inicio constante. Veremos cómo construir una aplicación QwikCity y qué la hace única. El masterclass te mostrará cómo configurar un proyecto QwikCity. Cómo funciona el enrutamiento con el diseño. La aplicación de demostración obtendrá datos y los presentará al usuario en un formulario editable. Y finalmente, cómo se puede utilizar la autenticación. Todas las partes básicas para cualquier aplicación a gran escala.
En el camino, también veremos qué hace que Qwik sea único y cómo la capacidad de reanudación permite un rendimiento de inicio constante sin importar la complejidad de la aplicación.
Cómo crear arte generativo increíble con código JavaScript simple
JS GameDev Summit 2022JS GameDev Summit 2022
165 min
Cómo crear arte generativo increíble con código JavaScript simple
Top Content
WorkshopFree
Frank Force
Frank Force
En lugar de dibujar manualmente cada imagen como en el arte tradicional, los artistas generativos escriben programas que son capaces de producir una variedad de resultados. En esta masterclass aprenderás cómo crear arte generativo increíble usando solo un navegador web y un editor de texto. Comenzando con conceptos básicos y avanzando hacia la teoría avanzada, cubriremos todo lo que necesitas saber.
Next.js 13: Estrategias de Obtención de Datos
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Estrategias de Obtención de Datos
Top Content
WorkshopFree
Alice De Mauro
Alice De Mauro
- Introducción- Prerrequisitos para la masterclass- Estrategias de obtención: fundamentos- Estrategias de obtención – práctica: API de obtención, caché (estática VS dinámica), revalidar, suspense (obtención de datos en paralelo)- Prueba tu construcción y sírvela en Vercel- Futuro: Componentes de servidor VS Componentes de cliente- Huevo de pascua de la masterclass (no relacionado con el tema, destacando la accesibilidad)- Conclusión
PlayCanvas de principio a fin: la versión rápida
JS GameDev Summit 2022JS GameDev Summit 2022
121 min
PlayCanvas de principio a fin: la versión rápida
Top Content
WorkshopFree
João Ruschel
João Ruschel
En esta masterclass, construiremos un juego completo utilizando el motor PlayCanvas mientras aprendemos las mejores prácticas para la gestión de proyectos. Desde el desarrollo hasta la publicación, cubriremos las características más cruciales como la gestión de activos, scripting, audio, depuración, y mucho más.