Solución:
He encontrado la respuesta a mi pregunta.
La clave es comprender el propósito del DOM virtual.
Primero tenemos que ver qué enfoque toma React para renderizar los componentes.
Los diferentes marcos de JavaScript adoptan diferentes enfoques para detectar cambios en el modelo de datos y representarlos en la vista.
Considere AngularJS. Cuando nos referimos a nuestros datos en una plantilla Angular, por ejemplo en una expresión como {{foo.x}}, Angular no solo representa esos datos sino que también crea un observador para ese valor en particular. Siempre que sucede algo en nuestra aplicación (evento de clic, respuesta HTTP, tiempo de espera), todos los observadores se ejecutan. Si el valor en un observador ha cambiado, ese valor se vuelve a representar en la interfaz de usuario. Al ejecutar todos los observadores, AngularJS esencialmente está descubriendo dónde necesita hacer los cambios. El proceso de ejecución de estos observadores se denomina verificación sucia.
React adopta un enfoque diferente. Siempre que hay un cambio de estado en un componente de React, en lugar de averiguar dónde hacer los cambios (como AngularJS), React vuelve a renderizar toda la IU desde cero (con el estado actualizado).
Pero este enfoque de React tiene un problema. Volver a renderizar toda la interfaz de usuario significa volver a renderizar todo el árbol DOM. Esto es un problema porque la actualización de DOM es un proceso lento (debido al reflujo y al repintado).
Aquí es donde entra en juego el DOM virtual de React. Un DOM virtual es solo una representación del DOM real en forma de objetos javascript. Es solo una estructura de datos de árbol de objetos simples de JavaScript que existe en la memoria. En comparación con el DOM real, la renderización del DOM virtual es mucho más rápida porque nunca se renderiza en la pantalla (no es necesario refluir ni volver a pintar).
Entonces, ¿cómo resuelve el problema Virtual DOM? Cuando cargamos nuestra aplicación, React crea un DOM virtual que es una copia virtual exacta del DOM real. Siempre que hay un cambio de estado en un componente, en lugar de volver a renderizar todo el DOM Real, React renderiza un DOM virtual completamente nuevo (con el estado actualizado). Luego, hace una diferencia entre el DOM virtual antiguo (la copia inicial del DOM Real) y este DOM virtual nuevo (renderizado después del cambio de estado) para averiguar los cambios entre ellos y SOLO hace esos cambios en el DOM Real. De esta manera, se vuelve a renderizar toda la IU (al renderizar un DOM virtual completamente nuevo) pero solo se realizan los cambios mínimos requeridos en el DOM real.
Entonces, cuando se dice que “Usar Virtual DOM React actualiza solo aquellos elementos que necesitan ser actualizados” (punto 1 en mi pregunta), significa que con la ayuda de Virtual DOM React está superando las limitaciones de su propio enfoque (enfoque de renderizando toda la interfaz de usuario desde cero).
Esta respuesta también explica el mismo concepto.
He visto algunas respuestas que afirman que la manipulación del DOM usando React es más rápida que usar la api DOM porque la api DOM vuelve a renderizar todo el árbol DOM mientras que React vuelve a renderizar solo aquellas partes del árbol DOM que necesitan ser cambiadas. Esto no es verdad. Todos los navegadores modernos son lo suficientemente eficientes como para actualizar solo aquellas partes del árbol DOM que deben cambiarse. Esto se puede verificar usando paint flashing en las herramientas de desarrollo de los navegadores (consulte también esta respuesta y esta respuesta). Incluso si asumimos que la API DOM vuelve a representar todo el árbol DOM, este razonamiento es falso porque el código interno de React tiene que usar la API DOM para actualizar el DOM. Si la API de DOM volvió a renderizar todo el árbol DOM, React también volvería a renderizar todo el árbol de DOM porque eventualmente también usará la API de DOM para actualizar el DOM.
En cuanto al segundo punto, React realmente nos facilita el procesamiento por lotes.
En React, mientras que las lecturas se realizan en el DOM Real, las escrituras (cambios de estado) no se realizan en el DOM Real. En su lugar, las escrituras se ponen en cola. Luego, cuando todas nuestras lecturas y escrituras han sido procesadas, se construye un nuevo DOM virtual basado en las escrituras. Luego, se hace la diferencia entre el DOM virtual antiguo y el nuevo y luego React escribe los cambios necesarios en el DOM real para actualizarlo. Por lo tanto, eventualmente, todas las escrituras en el DOM real se realizan juntas en un solo reflujo.
Pero también podemos, manualmente, sin React, escribir nuestro código de tal manera que primero se realicen todas las lecturas y luego todas las escrituras. React facilita el procesamiento por lotes porque con React no tenemos que preocuparnos por hacer las lecturas y escrituras juntas y React automáticamente procesará las escrituras por nosotros. Entonces React no acelera las cosas. Facilita las cosas.
En conclusión, podemos decir que React no es en realidad más rápido. Es más fácil. Como dice Pete Hunt en este video, “React no es mágico. Al igual que puedes entrar en ensamblador con C y vencer al compilador de C, puedes ingresar a operaciones DOM sin procesar y llamadas DOM API y vencer a React si quieres. Sin embargo, el uso de C, Java o JavaScript es una mejora del rendimiento de un orden de magnitud porque no tiene que preocuparse … por las características específicas de la plataforma. Con React puede crear aplicaciones sin siquiera pensar en el rendimiento y el estado predeterminado es rápido “. .
Esta publicación de Rich Harris también afirma que es un mito que “el DOM virtual es rápido”.
Una vez que React sabe qué objetos DOM virtuales han cambiado, React actualiza solo esos objetos, en el DOM real. Esto hace que el rendimiento sea mucho mejor en comparación con la manipulación del DOM real directamente. Esto hace que React se destaque como una biblioteca de JavaScript de alto rendimiento.
Con respecto a la actualización por lotes:
React sigue un mecanismo de actualización por lotes para actualizar el DOM real. Por lo tanto, conduce a un mayor rendimiento. Esto significa que las actualizaciones del DOM real se envían en lotes, en lugar de enviar actualizaciones para cada cambio de estado.
El repintado de la interfaz de usuario es la parte más costosa, y React asegura de manera eficiente que el DOM real reciba solo actualizaciones por lotes para repintar la interfaz de usuario.