viernes, 28 de julio de 2017

La H-1B: El viaje de un desarrollador iOS desde Honduras hasta Silicon Valley

Por estos días, vivo en la gran ciudad de San Francisco. Obtuve un trabajo que amo, y uno con el cual soñé con tener durante mucho tiempo. Parece fácil ahora, pero no siempre fue así.

Cómo empezó todo

Nací en San Pedro Sula, un pequeño pueblo en la esquina noroeste de Honduras. Comencé a programar cuando tenía 12 años. Todo empezó con BASIC. Un día, estaba jugando un vídeo juego y se colgó. Cuando ví la pantalla llena de códigos de error y mensajes, me picó la curiosidad—entonces comencé a aprender algunos comandos BASIC, que eventualmente me llevaron a comprar libros de programación sobre Clipper, Turbo Pascal, C, C++, etc. Fue genial. Tenía todo el tiempo del mundo para gastar programando cualquier cosa que quisiera: sin limites de tiempo (aparte de la escuela, que no era tan demandante como un trabajo de tiempo completo) o responsabilidades de adulto.
file
Muchos años más tarde, a la edad de 15 años, mi padre estaba teniendo problemas con una aplicación defectuosa de contabilidad. Le dije que podía crear una versión mejor—sin realmente entender en dónde me estaba metiendo (nunca había abierto una base de datos SQL). Entonces compré algunos libros más y me puse a trabajar. (Nota: Esto sucedía en la época en donde Internet no era algo predominante como lo es hoy: estaba viviendo en un país del tercer mundo, e Internet llegó a finales de 1997, 5 años después de haber comenzado a programar).

Sueños y ambiciones

Recuerdo que me dije a mí mismo: “Quiero ser un ingeniero informático”. Por supuesto, no tenía idea exactamente qué es lo que eso abarcaba, pero sabía que me gustaban las computadoras (estoy hablando de esos viejos y cuadrados monitores de fósforo verde, PCs lentas con DOS—horribles, por supuesto, ahora que tenemos de esos brillantes nuevos sistemas operativos).
Recuerdo muy claramente que en mi segundo o tercer viaje a los EEUU (solíamos ir de vacaciones), decidí que quería vivir ahí. Todo era tan avanzado! Por supuesto que hoy, con la globalización e Internet, las diferencias no son tan vastas, pero brechas en el crecimiento y en el progreso pueden seguir viéndose en el desarrollo de infraestructura, la inestabilidad política, el índice de delincuencia, etc.
file
Entonces, siendo un ingenuo de veinte y tantos, decidí que quería emigrar hacia los EEUU—pero por supuesto, eso es un camino largo e inestable.
Por esos tiempos, mi padre tenía una empresa de contabilidad, y habían empezado a tener problemas con su aplicación contable. El desarrollador era obstinado y sin deseos de ayudar, entonces mi padre empezó a buscar alternativas. El quería que me ponga al día como programador, fue a la universidad local—el único lugar donde vendían libros avanzados de programación—y se abarrotó de recursos. Fue un mundo nuevo para mí: tenía una de esas nuevas (en esa época) PCs de monitor de fósforo verde con un procesador de 5 MHz, 256kb de memoria RAM y un disco rígido de 10mb de capacidad. Usaba de esos viejos discos mecánicos, por lo que podías oír todo lo que estaba procesando. El teclado era también mecánico y el sonido al teclear era placentero. 10 años más tarde todavía seguía trabajando en la misma aplicación contable; ahora, sin embargo, lo vendía a clientes, con una interfaz en Windows, una base de datos SQL y conectividad vía Internet.

Yendo a la quiebra

Por esos tiempos, decidí dejar la universidad y empezar mi propia compañía. Había estado trabajando con mi padre, de alguna manera: dividíamos las ganancias de la aplicación contable (a pesar de que era mi idea y ejecución, el invirtió mucho tiempo enseñándome contabilidad). Así que tomamos caminos separados: él seguía vendiendo la versión actual de la aplicación y yo me embarqué a crear una nueva. Pero como descubriría pronto, el negocio de desarrollo de software en Honduras no es ningún paseo en el parque: los clientes no quieren pagar por tus servicios, y ellos ven siempre el desarrollo de software como una tarea relativamente fácil dado que no requiere trabajar con un producto tangible; a menudo, no perciben el valor en el software al no crear ganancias inmediatas, haciéndolo más difícil de vender.
Del lado del negocio, había contratado a algunos de los mejores estudiantes de la carrera (a quienes encontré cuando volví a la universidad). Pero con el tiempo, comencé a usar demasiados títulos: CEO, contador, Representante de RRHH, Servicio y Soporte al cliente, Jefe de proyecto, y (mi favorito) Desarrollador. Yo sólo quería programar, pero se volvió demasiado difícil mientras mantenía todos esos roles. Eventualmente, nos encontramos con problemas, como que nuestros clientes no estaban pagando a tiempo y luchábamos para encontrar nuevos proyectos: cuando tienes a los mejores talentos alrededor, estos quieren ser bien pagados, y estábamos pagando bien; pero los clientes no estaban respondiendo como esperábamos. Además, el vivir en un país del tercer mundo había desalentado cualquier tipo de interés de inversión. Tendría que haber ido con un modelo de negocio distinto, pero estaba demasiado ocupado haciendo malabares con todos mis títulos. Al final, la compañía quebró, y a mi me quedó una tonelada de deudas, empleados enojados y un gusto amargo en la boca. Tenía que empezar de nuevo desde el principio.

El SDK de iPhone

file
150mil descargas de aplicaciones pagas después, demostré que tenía razón.



Lo que más importa es cómo nos levantamos de vuelta cuando enfrentamos la derrota, y cómo aprendemos de nuestros errores. Empezar de nuevo y re-pensar todo es desalentador, pero eso es lo que tenía que hacer. Mi esposa me ayudó durante esos momentos difíciles y me empujó a hacer cosas que no pensé que podría ser capaz. Así que empecé a trabajar en mi aplicación contable de nuevo, pero sin ningún dinero para marketing era muy difícil de promover. Los ingresos eran escasos, y necesitaba mantener a mi familia. Tuve que cambiar de marcha. Alrededor de la misma época, Apple introdujo el SDK de iPhone. Sonaba como una plataforma arriesgada para mí; además, era nuevo con el Mac en sí. (mi transición al Mac empezó con el iPhone y un Hackintosh, que me dejó probar el sabor de OS X sin desembolsar dinero en una máquina costosa). Algunos de mis amigos se reían y me ignoraban por completo cuando decía que iba a desarrollar para el iPhone; pero realmente creía que había dinero de por medio en la App Store. 150mil descargas de aplicaciones pagas después, demostré que tenía razón; aunque, por supuesto, esos números solos no cuentan la historia completa: la economía de la App Store es compleja, realmente necesitas invertir en tu producto y encontrar clientes para crear valor a largo plazo. Y para eso, necesitas un equipo. Así que aunque le estuviera yendo bien a mi aplicación, no era sostenible (desde el punto de vista del negocio) para seguir desarrollándola por mi cuenta. A pesar de todo, había demostrado lo que podía hacer—entonces, un día, me levanté y me dije a mi mismo que finalmente emigraría a los EEUU.
Como pude descubrir, emigrar a los EEUU no era una tarea fácil. Probablemente la ruta más simple era conseguir una Green Card por medio de un miembro de la familia, pero mi opción más cercana era mi hermano, que había nacido en los EEUU; sin embargo, el vivía con nosotros en Honduras y no podía pedir por nadie ya que no estaba trabajando en ese momento. Y aunque pudiera, el proceso podría llegar a tomar 15 años (Nota: los hermanos tienen menor preferencia en lo que respecta a miembros familiares para el patrocinio de la Green Card). Mi solución era crear una compañía estadounidense. Conseguí que un amigo invirtiera y empezamos a crear juegos para iPhone y iPad. En los papeles, todo parecía genial; pero, por supuesto, la economía de la App Store nos demostró lo contrario. Pronto, estábamos necesitando más dinero; mi amigo no había anticipado eso. Al final, publicamos una aplicación (había otra en desarrollo, pero nunca fue finalizada debido a problemas de financiación). De vuelta, las cosas parecían poco prometedoras. Decidí perseguir lo que creí que era mi último recurso: trabajar para una compañía de EEUU.

Consiguiendo un empleo

Es duro ser contratado por una compañía de EEUU desde el extranjero. Me postulé para varias posiciones, pero el primer problema era que requerían relocación: ellos tendrían que solicitar y patrocinar una visa de trabajo. El proceso era caro en términos de tiempo (hasta un año, si no hay visa disponible en ese momento) y dinero (por ej., honorarios de abogados). Así que, en vez de eso, comencé buscando trabajo por medio de un sitio de trabajo independiente online. En teoría, es un buen servicio. Pero, al principio, debes empezar por construir confianza—lo cual es duro. Hay también hordas de desarrolladores que cobran menos que el promedio sólo para llamar la atención; por esto, es difícil ser bien pagado. Terminé haciendo un sólo proyecto por medio del sitio, que valía 8 horas de trabajo.
Más tarde, fui contactado por Toptal con lo que parecía una muy buena oportunidad: ellos contratan grandes programadores y los conectan con los clientes. Además, puedo trabajar desde casa, y para una empresa de EEUU. Aparecí en sus radares por medio de mi trabajo en la App Store, pero todavía tenía que pasar un estricto proceso de selección, haciendo de todo, desde comprensión de textos hasta trivia de programación, desde algoritmos de optimización hasta sesiones de programación cronometradas. Lo más memorable fue la entrevista final, que incluía discutir uno de mis proyectos y guiando a un ingeniero de Toptal por algunas partes de mi código para demostrar que era realmente mío.






Luego de que Toptal me aceptara dentro de su red de desarrolladores, fui puesto en una lista de espera. Una vez que el cliente muestra interés en un desarrollador en particular, este entrevistará a ese candidato (cómo en una entrevista de trabajo normal) para asegurarse que es el adecuado. Antes de mi primer entrevista, estaba bastante nervioso. Comenzó con el cliente explicando lo que se esperaba de mí, así como también el proyecto en general, y haciendo preguntas todo el tiempo para comprobar sí había entendido todo. Mientras la entrevista avanzaba, las cosas no estaban yendo como esperaba, y las preguntas se fueron volviendo cada vez más específicas y técnicas. Terminaron contratando a alguien más. En retrospectiva, fue bueno que no me hayan querido: una semana después, fui entrevistado por quien, eventualmente, terminó siendo mi empleador a tiempo completo.
Me preparé mejor para la siguiente entrevista, la cual fue tan bien como podría haber esperado: hablamos más sobre mi experiencia cómo desarrollador, y la compañía se familiarizó con mi enfoque para solucionar problemas. Tres días después, había firmado contrato y comencé a trabajar para este nuevo cliente via Toptal.
Trabajé para Life360 via Toptal al menos 9 meses. Su producto estrella es una aplicación móvil de localización de familiares, pero inicialmente estuve trabajando sólo en algunos proyectos paralelos: la primera, una aplicación de alertas de terremotos; y la segunda, un escáner policial. Por algunos meses, mi flujo de trabajo consistía principalmente en: recibir requerimientos de alto nivel de Life360, devolviendo bocetos y preguntas, e integrando sus respuestas dentro de esas aplicaciones, repetía este ciclo varias veces. Estaba en contacto con un diseñador y algunos empleados de Life360 (la compañía tenía sólo cinco o seis en esa época), pero tenía mucha autonomía. Era liberador trabajar desde casa: no tenía que viajar a diario y había creado un ambiente de trabajo sin distracciones.
Pronto me encontré más y más profundamente integrado con el equipo—había demostrado mi valor, por decirlo de alguna manera, con estos dos proyectos iniciales. Para Diciembre, me preguntaron si quería formar parte del equipo a tiempo completo en San Francisco—Acepté con entusiasmo y ellos empezaron el papeleo. Para Enero, estaba atendiendo reuniones diarias de Scrum (virtualmente, ya que estaba todavía en Honduras), describiendo mi trabajo del día anterior y mi lista de tareas para lo que seguía. Mi flujo de trabajo se volvió más organizado, y me comprometí más con la empresa.

Reubicación

Era un sueño hecho realidad: había hecho un gran trabajo para una compañía de EEUU, y estaba en camino de reubicarme—pero todavía faltaban varios obstaculos a superar. En primer lugar, nunca había completado mi carrera universitaria. Aunque no es estrictamente necesario para trabajar en una empresa de tecnología en estos días, sí se necesita el título de bachiller para calificar para una visa de tipo H-1B. Así que tuve que terminar mi carrera; esto requería de un compromiso de seis meses a un proyecto de mayor escala, el cual tenía justo el tiempo necesario para completar.
El abogado llenó el papeleo el 1ero de Abril, el día en el que el proceso de la visa tipo H-1B abre (al momento del envio, dejó la sección del diploma cómo “pendiente”, dado que el tipo de visa H-1B es limitado y podía enviar la documentación más tarde). Terminé mi proyecto a tiempo, atendí a mi ceremonia de graduación y recibí un diploma.
Desde ese punto en adelante, la compañía que te contrata tiene que ser muy abierta, por sobre todo, y muy paciente. El proceso para la aplicación de la visa empieza en Abril; si optas por la opción del proceso premium, obtienes tus resultados de la USCIS en dos semanas. Luego de eso, todavía tienes que pasar por un proceso de entrevistas, punto en el cual todavía te pueden denegar la visa; pero si todo sale bien, puedes entrar a los Estados Unidos después del 1ero de Octubre — seis meses después de la fecha de la aplicación, y no antes. Esto significa que no puedes trabajar para esa compañía hasta que realmente consigas la visa de tipo H-1B, lo cual puede ser un problema: la compañía necesita resolver como continuar trabajando remotamente mientras esperan que la visa se active. En mi caso, la compañía decidió contratarme como un desarrollador independiente, facturar mis horas como servicios profesionales, y no rompió ninguna ley de inmigración y trabajo.
Volé a San Francisco el 1ero de Octubre de 2012. El objetivo que había ansiado desde que puedo recordar fue finalmente completado.
Contenido traducido por Pablo Fabregat, miembro de TransBunko, un mercado de traducciones técnicas.
Articulo publicado originalmente en Toptal.

viernes, 21 de julio de 2017

Componentes React Eficientes: Una Guía para Optimizar el Desempeño de React


Desde su presentación inicial, React ha cambiado la forma de pensar de desarrolladores front-end al construir aplicaciones web. Con DOM virtual, React hace las actualizaciones UI (Interfaz de Usuario) tan eficientes como nunca, haciendo al mismo tiempo a tu aplicación web más precisa. Pero, ¿por qué las aplicaciones web con React con un buen tamaño todavía tienen un desempeño pobre?
Bueno, la clave está en cómo usas React.
Una biblioteca front-end moderna como React no hace más rápida tu aplicación mágicamente. Se requiere que el desarrollador entienda cómo funciona React y cómo los componentes viven a través de las diferentes fases del ciclo de vida del componente.
Con React puedes ganar muchas de las mejoras que ofrece al medir y optimizar cómo y cuándo regresan tus componentes. Y React proporciona sólo las herramientas y funciones necesarias para hacer esto más fácil.
Acelera tu aplicación React al optimizar tu proceso renderización-diff de los componentes.
En este tutorial React, aprenderás cómo puedes medir el desempeño de tus componentes de React y optimizarlos para construir una aplicación web con React de mayor y mejor desempeño. De igual modo, aprenderás cómo un par de las mejores prácticas JavaScript también ayudan a que tu aplicación web con React presente una experiencia de usuario sin inconvenientes.

¿Cómo funciona React?

Antes de entrar a las técnicas de optimización, necesitamos entender mejor cómo funciona React.
En el corazón de React se encuentra la sintaxis JSX y la habilidad de React de construir y comparar DOM virtuales. Desde su lanzamiento, React ha influenciado muchas otras bibliotecas front-end. Bibliotecas tales como Vue.js también se apoyan en la idea de DOM virtuales.
Aquí se ve cómo funciona React:
Cada aplicación React comienza con un componente de raíz y se compone de muchos componentes en una formación de árbol. Los componentes en React son “funciones” que dejan la UI basada en la data (apoyo y estado) que recibe.
Esto lo podemos simbolizar como F.
UI = F(data)
Los usuarios interactúan con la UI y ocasionan un cambio en la data. Ya sea que la interacción sea dar clic a un botón, tocar una imagen, arrastrar ítems de una lista, peticiones AJAX que llaman API, etc., todas esas interacciones solo cambian la data. Nunca causan que la UI cambie directamente.
Aquí, la data es todo lo que define el estado de la aplicación web y no solo lo que has almacenado en tu base de datos. Hasta trozos de los estados front-end (ej. Qué ventana se selecciona en el momento o si una casilla se marcó en el momento) son parte de esta data.
Cuando hay un cambio en esta data, React usa las funciones de componente para volver a dejar la UI, pero solo virtualmente:
UI1 = F(data1)
UI2 = F(data2)
React calcula las diferencias entre la UI actual y la nueva UI al aplicar un algoritmo comparativo en las dos versiones de su DOM virtual.
Changes = Diff(UI1, UI2)
React luego procede a aplicar solo los cambios a la UI real en el buscador.
Cuando la data asociada al componente cambia, React determina si en realidad se necesita una actualización DOM. Esto le permite a React poder evitar operaciones de manipulación DOM costosas en el buscador, como creación de nodos DOM y acceder a algunos de estos ya existentes más de lo necesario.
Este cálculo de diferenciación repetido y el dejar componentes, puede ser una las fuentes primarias de los problemas de desempeño de React en cualquier aplicación con React. Construir una aplicación React en la que la diferenciación de algoritmos no se logra reconciliar efectivamente, causando así que toda la aplicación sea dejada repetidamente, puede resultar en una experiencia frustrante y lenta.

¿Dónde comenzar la optimización?

¿Pero qué estamos optimizando exactamente?
Bueno, durante el proceso inicial de dejar atrás, React construye un árbol DOM como éste:
Un DOM virtual de componentes React
Dado que una parte de la data cambia, lo que queremos que haga React es dejar de nuevo sólo los componentes que se ven afectados directamente por el cambio (y posiblemente obviar el proceso de diff para el resto de los componentes):
React renderiza un numero de componentes
Sin embargo, lo que React termina haciendo es:
React mal gastando recursos al renderizar todos los componentes
En la imagen de arriba, todos los nodos amarillos son renderizados y diferenciados (diff), dando como resultado una pérdida de tiempo/recursos de computación. Aquí es donde pondremos nuestros esfuerzos de optimización, principalmente. Configurar cada componente para que sólo renderice-diferencie (diff) cuando sea necesario, nos permitirá recuperar estos ciclos CPU perdidos.
Los desarrolladores de la biblioteca React tomaron esto en consideración y proporcionaron un enganche para nosotros poder hacer exactamente eso: una función que nos permite decirle a React cuando está bien obviar la renderización de un componente.

Medir Primero

Como lo dice Rob Pike de manera elegante como una de sus reglas de programación:
Medir. No ajustes la velocidad hasta que hayas medido y aun en ese momento no lo hagas, a menos que una parte del código opaque el resto.
No optimices un código que pienses que puede bajar la velocidad de tu aplicación. En vez de esto, deja que las herramientas de medida de desempeño de React te guíen en el camino.
React tiene una fuerte herramienta para esto. Al usar la biblioteca react-addons-perf puedes obtener un resumen del desempeño general de tu aplicación.
El uso es muy simple:
Import Perf from 'react-addons-perf'
Perf.start();
// use the app
Perf.stop();
Perf.printWasted();
Esto imprimirá una tabla con la cantidad de componentes de tiempo perdido al renderizar.
Tabla de componentes perdiendo tiempo al renderizar
La biblioteca proporciona otras funciones que te permiten imprimir diferentes aspectos del tiempo perdido por separado (ej., al usar las funciones printInclusive() o printExclusive()), o hasta imprimir las operaciones de manipulación DOM (usando la función printOperations()).

Tomando la Comparativa del Mercado Más Allá

Si eres una persona visual, entonces react-perf-tool es exactamente lo que necesitas.
react-perf-tool está basada en la biblioteca react-addons-perf. Te da una manera más visual de depurar el desempeño de tu aplicación con React. Ésta usa la biblioteca subyacente para obtener medidas y luego las visualiza como gráficas.
Una visualización de componentes perdiendo tiempo en renderización
Muy a menudo, ésta es una manera mucho más conveniente de notar las trancas. La puedes usar fácilmente al agregarla como componente a tu aplicación.

¿React Debería Actualizar el Componente?

Por defecto, React se ejecutará, renderizará el DOM virtual y comparará la diferencia para cada componente en el árbol para cada cambio en sus apoyos y estados. Pero eso no es racional, obviamente.
Mientras tu aplicación crece, intentar re-renderizar y comparar el DOM virtual completo en cada acción, eventualmente disminuirá la velocidad.
React proporciona una manera sencilla para que el desarrollador indique si un componente necesita ser re-renderizado. Aquí es donde el método shouldComponentUpdate entra en juego.
function shouldComponentUpdate(nextProps, nextState) {
   return true;
}
Cuando esta función da un resultado verdadero para cualquier componente, permite que se active el proceso de renderización-diferenciación.
Esto te da una manera sencilla de controlar el proceso de renderización-diferenciación. Cuando necesites prevenir que un componente sea re-renderizado por completo, simplemente es un resultado falso de la función. Dentro de la función, puedes comparar el set de apoyos y estado actual, al igual que el siguiente para determinar si es necesario re-renderizar:
function shouldComponentUpdate(nextProps, nextState) {
   return nextProps.id !== this.props.id;
}

Usar un React.PureComponent

Para facilitar y automatizar un poco esta técnica de optimización, React proporciona lo que se conoce como componente “puro”. Un React.PureComponent es exactamente como un React.Component que implementa una función shouldComponentUpdate() con una comparación vacía de apoyo y estado.
Un React.PureComponent es más o menos un equivalente a esto:
class MyComponent extends React.Component {
   shouldComponentUpdate(nextProps, nextState) {
       return shallowCompare(this.props, nextProps) && shallowCompare(this.state, nextState);
   }
   …
}
Ya que sólo realiza una comparación vacía, tal vez sólo te parezca útil cuando:
  • Tus apoyos y estados contienen data primitiva.
  • Tus apoyos y estados tienen data compleja, pero sabes cuándo llamar forceUpdate() para actualizar tu componente.

Hacer la Data Inmutable

¿Qué tal si pudieras usar React.PureComponent y seguir teniendo una manera eficiente de ver cuando cualquier apoyo o estado complejo ha cambiado automáticamente? Aquí es donde las estructuras de data inmutable nos hacen la vida más fácil.
La idea detrás del uso de las estructuras de data inmutable es simple. Cuando un objeto que contiene cambios de data complejos, en vez de hacer los cambios en ese objeto, crea una copia de ese objeto con los cambios. Esto hace el detectar los cambios en la data tan simple como comparar la referencia de los dos objetos.
Puedes usar Object.assign o _.extend (desde Underscore.js o Lodash):
const newValue2 = Object.assign({}, oldValue);
const newValue2 = _.extend({}, oldValue);
Aun mejor, puedes usar una biblioteca que proporciona estructuras de data inmutable:
var map1 = Immutable.Map({a:1, b:2, c:3});
var map2 = map1.set('b', 2);
assert(map1.equals(map2) === true);
var map3 = map1.set('b', 50);
assert(map1.equals(map3) === false);
Aquí, Immutable.Map es proporcionada por la biblioteca Immutable.js.
Cada vez que un mapa se actualiza con su método set, un nuevo mapa se regresa sólo si la operación set cambió el valor subyacente. De otro modo, el mismo mapa se regresa.
Puedes aprender más sobre el uso de estructuras de data inmutable aquí.

Más Técnicas de Optimización de Aplicación React

Usando la Construcción de Producción

Cuando se desarrolla una aplicación con React, se presentan advertencias y mensajes de errores muy útiles. Estos hacen la identificación de bugs y problemas durante el desarrollo muy fácil. Pero también cuestan parte del desempeño.
Si observas el código fuente de React, verás muchas marcas de if (process.env.NODE_ENV != 'production'). Estos trozos de código que React está ejecutando en tu ambiente de desarrollo no es algo que el usuario necesite. Para ambientes de producción, todo este código innecesario se puede descartar.
Si impulsaste tu proyecto usando create-react-app, entonces puedes ejecutar npm run build para producir la construcción de producción sin este código extra. Si estás usando Webpack directamente, puedes ejecutar webpack -p (el cual es el equivalente de webpack --optimize-minimize --define process.env.NODE_ENV="'production'".

Atar Funciones Desde Temprano

Es muy común ver funciones atadas al contexto del componente dentro de la función renderizada. Esto es, a menudo, el caso, cuando usamos estas funciones para manejar eventos de componentes en temprana etapa.
// Creates a new `handleUpload` function during each render()
<TopBar onUpload={this.handleUpload.bind(this)} />
// ...as do inlined arrow functions
<TopBar onUpload={files => this.handleUpload(files)} />
Esto causará que la función render() cree una nueva función en cada renderización. Una mejor manera de hacer lo mismo es:
class App extends React.Component {
   constructor(props) {
       super(props);
       this.handleUpload = this.handleUpload.bind(this);
   }
   render() {
       …
       <TopBar onUpload={this.handleUpload} />
       …
   }
}

Usar Múltiples Archivos Chunk

Para las aplicaciones web con React de una sola página, normalmente terminamos uniendo todo nuestro código JavaScript front-end en un archivo único minimizado. Esto funciona muy bien para aplicaciones web de tamaño medio. Pero mientras la aplicación comienza a crecer, entregar este archivo JavaScript unido al buscador como tal puede ser un proceso que consume mucho tiempo.
Si estás usando Webpack para construir tu aplicación, puedes impulsar su código al separar sus capacidades para igualmente separar tu código de aplicación construida en varios “chunks” (trozos) y entregarlos al buscador en los momentos necesarios.
Hay dos tipos de separación: separación de recursos y separación de código en demanda.
Con la separación de recursos, separas contenido de recursos en varios archivos. Por ejemplo, al usar CommonsChunkPlugin, puedes extraer un código común (como todas las bibliotecas externas) a un archivo “chunk” propiamente. Al usar ExtractTextWebpackPlugin, puedes extraer todo código CSS a un archivo CSS separado.
Este tipo de separación te ayudará de dos maneras. Ayuda al buscador a almacenar aquellos recursos que cambian con menos frecuencia. También ayudará al buscador a tomar ventaja de la descarga paralela para reducir, potencialmente, el tiempo de carga.
Una característica más notable de Webpack es la separación del código en demanda. Esto puede mantener la descarga inicial pequeña al reducir el tiempo que toma cargar la aplicación. El buscador puede, consecuentemente, descargar trozos de código en demanda cuando la aplicación lo necesite.
Puedes aprender más sobre la separación de código Webpack aquí.

Activar Gzip en tu Servidor Web

El grupo de archivos JS de la aplicación React son, comúnmente, muy grandes así que para hacer que la página web cargue más rápido, podemos activar Gzip en el servidor web (Apache, Nginx, etc.)
Todos los buscadores modernos apoyan y negocian automáticamente la compresión de Gzip para las peticiones HTTP. Activar la compresión Gzip puede reducir el tamaño de la respuesta transferida en un 90%, lo cual puede reducir la cantidad de tiempo para descargar un recurso, reducir el uso de data para el cliente y mejorar el tiempo para la renderización de tus páginas.
Verifica la documentación para tu servidor web para ver cómo activar la compresión:

Usar Eslint-plugin-react

Deberías usar ESLint para casi todos los proyectos JavaScript. React no es la diferencia.
Con eslint-plugin-react, te estarás obligando a adaptarte a muchas de las reglas de programación de React, que pueden beneficiar tu código a la larga y evitar muchos problemas comunes e inconvenientes que ocurren debido a la mala escritura de códigos.

Haz a tus Aplicaciones React rápidas Nuevamente

Para aprovechar a React al máximo, necesitas impulsar sus herramientas y técnicas. El desempeño de una aplicación web de React se encuentra en la simplicidad de sus componentes. Abrumar el algoritmo de renderización y diferenciación puede hacer que tu aplicación se desempeñe pobremente de forma muy frustrante.
Antes de que puedas optimizar tu aplicación, necesitas entender cómo funcionan los componentes de React y como se renderizan en tu buscador. Los métodos del ciclo de vida de React te dan maneras de prevenir que tu componente re-renderice innecesariamente. Elimina aquellas trancas y tendrás el desempeño de la aplicación que merecen tus usuarios.
Aunque hay más formas de optimizar una aplicación web con React, perfeccionar los componentes para actualizar sólo cuando se requiere, impide una mejora en el desempeño.
Articulo publicado originalmente en Toptal.