El resto de este artículo profundiza en muchas de las características de Dart (incluidas sus bibliotecas estándar) que lo convierten en el mejor lenguaje para implementar Flutter .
[Puede omitir esta sección si ya conoce temas como lenguajes estáticos versus dinámicos, compilación AOT y JIT y máquinas virtuales.]
Históricamente, los lenguajes informáticos se han dividido en dos grupos: (p. ej., Fortran o C, donde las variables se escriben estáticamente en tiempo de compilación) y (p. ej., Smalltalk o JavaScript, donde el tipo de una variable puede cambiar en el momento de la ejecución). tiempo). Los lenguajes estáticos generalmente se compilaban para producir programas de código de máquina nativo (o código ensamblador ) para la máquina de destino, que en tiempo de ejecución eran ejecutados directamente por el hardware. Los lenguajes dinámicos fueron ejecutados por un intérprete, sin producir código de lenguaje de máquina.
Por supuesto, las cosas eventualmente se volvieron mucho más complicadas. Se hizo popular el concepto de una (VM), que en realidad es solo un intérprete avanzado que imita una máquina de hardware en el software. Una máquina virtual facilita la migración de un idioma a nuevas plataformas de hardware. En este caso, el idioma de entrada de una máquina virtual suele ser un . Por ejemplo, un lenguaje de programación (como ) se compila en un lenguaje intermedio (código de ) y luego se ejecuta en una máquina virtual (la ). Además, ahora hay . Un compilador JIT se ejecuta durante la ejecución del programa, compilando sobre la marcha. Los compiladores originales que se ejecutan durante la creación del programa (antes del tiempo de ejecución) ahora se denominan . En general, solo los lenguajes estáticos son aptos para la compilación AOT en código de máquina nativo porque los lenguajes de máquina generalmente necesitan conocer el tipo de datos, y en los lenguajes dinámicos el tipo no se fija con anticipación. En consecuencia, los lenguajes dinámicos suelen interpretarse o compilarse JIT. Cuando la compilación AOT se realiza durante el desarrollo, invariablemente da como resultado ciclos de desarrollo mucho más lentos (el tiempo entre realizar un cambio en un programa y poder ejecutar el programa para ver el resultado del cambio). Pero la compilación AOT da como resultado programas que pueden ejecutarse de manera más predecible y sin pausas para el análisis y la compilación en tiempo de ejecución. Los programas compilados de AOT también comienzan a ejecutarse más rápido (porque ya se han compilado). Por el contrario, la compilación JIT proporciona ciclos de desarrollo mucho más rápidos, pero puede resultar en una ejecución más lenta o entrecortada. En particular, los compiladores JIT tienen tiempos de inicio más lentos, porque cuando el programa comienza a ejecutarse, el compilador JIT tiene que realizar análisis y compilación antes de que se pueda ejecutar el código. Los estudios han demostrado que . Ese es el final de la información de fondo. ¿No sería increíble combinar las ventajas de la compilación AOT y JIT? sigue leyendoLa compilación JIT se usa durante el desarrollo, utilizando un compilador que es especialmente rápido. Luego, cuando una aplicación está lista para su lanzamiento, se compila AOT. En consecuencia, con la ayuda de herramientas y compiladores avanzados, Dart puede ofrecer lo mejor de ambos mundos: ciclos de desarrollo extremadamente rápidos y tiempos de ejecución y puesta en marcha rápidos.
La flexibilidad de Dart en compilación y ejecución no termina ahí. Por ejemplo, Dart se puede para que los navegadores puedan ejecutarlo. Esto permite la reutilización de código entre aplicaciones móviles y aplicaciones web. Los desarrolladores han entre sus aplicaciones móviles y web. Dart también se puede usar en un servidor ya sea compilando en código nativo o compilando en JavaScript y usándolo con Finalmente, que usa el propio lenguaje Dart como su lenguaje intermedio (esencialmente actuando como un intérprete).Dart se puede compilar AOT o JIT de manera eficiente, interpretar o transpilar a otros idiomas. La compilación y ejecución de Dart no solo es inusualmente flexible, sino que es especialmente rápida .
La siguiente sección proporciona un ejemplo de cómo la velocidad de compilación de Dart puede cambiar las reglas del juego...Una de las características más populares de Flutter es su recarga en caliente extremadamente rápida. Durante el desarrollo, Flutter usa un compilador JIT que puede recargar y continuar ejecutando el código, generalmente en menos de un segundo. El estado de la aplicación se conserva entre recargas siempre que sea posible, por lo que la aplicación puede continuar desde donde la dejó.
Recarga en caliente con estado de subsegundos de Flutter Es difícil apreciar lo importante que puede ser una recarga en caliente realmente rápida (y confiable) durante el desarrollo, a menos que lo haya experimentado usted mismo. Los desarrolladores informan que cambia la forma en que crean sus aplicaciones, y lo describen como si . Esto es lo que :
Quería probar la recarga en caliente, así que cambié un color, guardé mi modificación y… ¡me enamoré ❤️!
Esta característica es realmente asombrosa. Pensé que Editar y continuar en Visual Studio era bueno, pero esto es simplemente asombroso . Solo con esto, creo que un desarrollador móvil puede ser dos veces más productivo.
Esto es realmente un cambio de juego para mí. Cuando implemento mi código y toma mucho tiempo, pierdo el enfoque, hago otra cosa y cuando vuelvo al simulador/dispositivo, he perdido la noción de lo que quería probar. ¿Qué es más frustrante que perder 5 minutos para mover un control 2px? Con Flutter esto ya no existe.La recarga en caliente de Flutter hace que sea mucho más fácil probar nuevas ideas o experimentar con alternativas, proporcionando un gran impulso a la creatividad. Hasta ahora, hemos discutido cómo Dart mejora las cosas para el desarrollador. La siguiente sección trata sobre cómo Dart también facilita la creación de aplicaciones fluidas que deleiten a los usuarios.
Una aplicación rápida es excelente, pero una aplicación fluida es aún mejor. Incluso una animación súper rápida se verá mal si es entrecortada. Sin embargo, prevenir puede ser difícil porque hay muchas causas diferentes. Dart tiene una serie de características para evitar muchas de las cosas comunes que causan bloqueos.
Por supuesto, (como cualquier idioma) todavía es posible escribir una aplicación janky en Flutter; Dart ayuda al ser más predecible y brindar al desarrollador más control sobre la fluidez de su aplicación, lo que facilita brindar la mejor experiencia de usuario posible, sin excepción. ?Con una velocidad de 60 fps, las interfaces de usuario creadas con Flutter funcionan mucho mejor que las creadas con otros marcos de desarrollo multiplataforma.Y no solo mejor que las aplicaciones multiplataforma, sino tan bueno como las mejores aplicaciones nativas:
La interfaz de usuario es suave como la mantequilla... Nunca había visto una aplicación de Android tan fluida.
Sin embargo, hay una ventaja aún mayor en el código compilado AOT y es evitar el "puente de JavaScript". Cuando los lenguajes dinámicos (como JavaScript) necesitan interoperar con el código nativo en la plataforma, tienen que comunicarse a través de un puente , lo que que tienen que guardar una gran cantidad de estado (potencialmente en almacenamiento secundario). Estos son un doble golpe porque no solo ralentizan las cosas, sino que pueden causar problemas graves.
"El puente" Nota: incluso el código compilado puede necesitar una interfaz para hablar con el código de la plataforma, y esto también se puede llamar puente, pero generalmente es mucho más rápido que el puente requerido por un lenguaje dinámico. Además, dado que Dart permite mover cosas como widgets a la aplicación, se reduce la necesidad de cruzar un puente.
Dart tomó un enfoque diferente a este problema. Los subprocesos en Dart, llamados aislados , no comparten memoria, lo que evita la necesidad de la mayoría de los bloqueos. Los aislados se comunican pasando mensajes a través de canales, lo que es similar a los actores en o los trabajadores web en JavaScript.
Dart, como JavaScript, tiene , lo que significa que no permite la preferencia en absoluto. En cambio, los subprocesos ceden explícitamente (usando o ). Esto le da al desarrollador más control sobre la ejecución. El subproceso único ayuda al desarrollador a garantizar que las funciones críticas (incluidas las animaciones y las transiciones) se ejecuten hasta el final, sin preferencia. Esto suele ser una gran ventaja no solo para las interfaces de usuario, sino también para otros códigos cliente-servidor. Por supuesto, si el desarrollador se olvida de ceder el control, esto puede retrasar la ejecución de otro código. Sin embargo, hemos descubierto que olvidarse de ceder el paso suele ser mucho más fácil de encontrar y solucionar que olvidarse de bloquear (porque las condiciones de carrera son difíciles de encontrar).Otra causa grave de bloqueo es la recolección de basura. De hecho, este es solo un caso especial de acceso a un recurso compartido (memoria), que en muchos idiomas requiere el uso de bloqueos. Pero los bloqueos pueden mientras se recopila memoria libre. Sin embargo, Dart puede realizar la recolección de basura casi todo el tiempo sin bloqueos .
Dart utiliza un avanzado, que es particularmente rápido para asignar muchos objetos de corta duración (perfecto para interfaces de usuario reactivas como Flutter que reconstruyen el árbol de vista inmutable para cada cuadro). Dart puede asignar un objeto con un solo golpe de puntero (no se requiere bloqueo). Una vez más, esto da como resultado un desplazamiento y una animación suaves, sin bloqueos.
Una vista en Dart y lo que produce Tenga en cuenta lo fácil que es visualizar el resultado que produce este código (incluso si no tiene experiencia con Dart).
Tenga en cuenta que ahora que Flutter usa Dart 2, el diseño se ha vuelto aún más simple y claro porque la new
palabra clave es opcional, por lo que los diseños estáticos pueden verse aún más como si estuvieran escritos en un lenguaje de diseño declarativo, como este:
Sin embargo, sé lo que probablemente esté pensando: ¿cómo puede llamarse una ventaja la falta de lenguajes de diseño especializados? Pero en realidad es un cambio de juego. Esto es lo que escribió un desarrollador en un artículo titulado " Por qué los desarrolladores de aplicaciones nativas deberían considerar seriamente a Flutter ".
En Flutter, los diseños se definen solo con el código Dart. No hay XML / lenguaje de plantillas. Tampoco hay una herramienta de diseño visual/guión gráfico.
Mi corazonada es que, al escuchar esto, algunos de ustedes podrían incluso encogerse un poco. Prima facie, esa también fue mi reacción. ¿No es más fácil hacer diseños usando una herramienta visual? ¿Escribir todo tipo de lógica de restricciones en el código no complicaría demasiado las cosas?
La primera parte de la respuesta es la recarga en caliente mencionada anteriormente.La respuesta para mí resultó ser no . ¡Y chico! qué revelador ha sido.
No puedo enfatizar lo suficiente cómo esto está años luz por delante de Instant Run de Android o cualquier solución similar. Simplemente funciona, incluso en grandes aplicaciones no triviales. Y es increíblemente rápido. Ese es el poder de Dart para ti.
Dart crea un diseño conciso y fácil de entender, mientras que la recarga en caliente "locamente rápida" te permite ver los resultados al instante. Y eso incluye las partes no estáticas de su diseño.En la práctica, eso hace que una interfaz de editor visual sea redundante. No me perdí en absoluto el agradable diseño automático de XCode.
Y como resultado, he sido mucho más productivo escribiendo diseños en Flutter (Dart) que en Android/XCode. Una vez que aprendes a hacerlo (para mí eso significó un par de semanas), hay una reducción sustancial de los gastos generales debido a que se está produciendo un cambio de contexto muy pequeño. Uno no tiene que cambiar a un modo de diseño, elegir un mouse y comenzar a hacer clic. Y luego preguntarse si algo tiene que hacerse programáticamente, cómo lograrlo, etc. Todo es programático. Y las API están muy bien diseñadas. Pronto se vuelve intuitivo y es mucho más poderoso que las construcciones que ofrecen los XML de diseño/diseño automático.Por ejemplo, aquí hay un diseño de lista simple que agrega un divisor (línea horizontal) entre todos los demás elementos, definido mediante programación:
Si no muchos programadores conocen Dart, ¿será más difícil encontrar programadores calificados? Irónicamente, Dart facilita la búsqueda de programadores porque es un lenguaje increíblemente rápido de aprender. Los programadores que ya conocen lenguajes como Java, JavaScript, Kotlin, C# o Swift pueden comenzar a programar en Dart casi de inmediato. Además de eso, la recarga en caliente alienta a los usuarios a jugar con Dart y probar cosas nuevas, lo que hace que aprender Dart sea aún más rápido y placentero.
Así es como lo expresó un programador en un artículo titulado " ":De otro artículo sobre Flutter y Dart, titulado “, el lenguaje utilizado para desarrollar aplicaciones de Flutter, es estúpido y simple de aprender . Google tiene experiencia en la creación de lenguajes simples y bien documentados como Go, por ejemplo. Hasta ahora, a mí, Dart me recuerda a Ruby y es un placer aprender. Además, no es solo para dispositivos móviles, sino también .
Flutter también usa el lenguaje Dart que fue creado por Google, para ser honesto, no soy un fanático de los lenguajes fuertemente tipados como C # o JAVA, pero no sé por qué la forma de escribir el código de Dart parece diferente. Y me siento muy cómodo escribiéndolo. Tal vez porque es muy simple de aprender y muy directo.Dart fue diseñado específicamente para ser familiar y fácil de aprender, a través de una extensa investigación y prueba de UX. Por ejemplo, en la primera mitad de 2017, el equipo de Flutter realizó . Les dimos una breve introducción a Flutter, luego los soltamos durante una hora más o menos para crear una vista simple. Todos los participantes pudieron comenzar a programar de inmediato, aunque nunca antes habían usado Dart. Se centraron en escribir puntos de vista reactivos, no en el lenguaje. .
Al final, un participante (que había progresado particularmente en la tarea) no mencionó nada sobre el idioma, por lo que les preguntamos si se daban cuenta de qué idioma estaban usando. Ellos no sabían. El idioma no importaba ; estaban programando en Dart en minutos.
La parte difícil de aprender un nuevo sistema generalmente no es aprender el lenguaje, sino aprender todas las bibliotecas, marcos, herramientas, patrones y mejores prácticas para escribir un buen código. Y las bibliotecas y herramientas de Dart son excepcionalmente buenas y están bien documentadas. : "Como beneficio adicional, también cuidan mucho su base de código y tienen la mejor documentación que he visto". El poco esfuerzo que se dedica a aprender Dart se compensa fácilmente con el ahorro de tiempo en el aprendizaje del resto.Como evidencia directa, un gran proyecto dentro de Google quería portar su aplicación móvil a iOS. Estaban a punto de contratar a algunos programadores de iOS, pero decidieron probar Flutter. Supervisaron cuánto tiempo les tomó a los desarrolladores ponerse al día con Flutter. Sus resultados mostraron que un programador podía aprender Dart y Flutter y volverse productivo en tres semanas. Esto se compara con las cinco semanas que habían observado anteriormente para que los programadores se pusieran al día solo con Android (sin mencionar que habrían tenido que contratar y capacitar a los desarrolladores para iOS).
Finalmente, el artículo " " es de una empresa que trasladó su gran aplicación empresarial a Dart en las tres plataformas (iOS, Android y web). Sus conclusiones:Mucho más fácil de contratar. Ahora buscamos elegir al mejor candidato sin importar si es de la Web, iOS o Android.
Tenemos 3 veces el ancho de banda ahora que todos nuestros equipos están consolidados en una sola base de código.
El intercambio de conocimientos está en su punto más alto
Pudieron triplicar su productividad usando Dart y Flutter. Esto no debería ser una sorpresa dado lo que estaban haciendo antes. Ellos, como muchas empresas, estaban creando aplicaciones separadas para cada plataforma (web, iOS y Android) utilizando lenguajes, herramientas y programadores separados . Cambiar a Dart significó que ya no tenían que contratar tres tipos diferentes de programadores. Y fue fácil para ellos trasladar a sus programadores existentes a Dart.
Ellos y otros descubrieron que una vez que los programadores comienzan a usar Flutter, a menudo . Les gusta la concisión del lenguaje y la falta de ceremonia. Les encantan como cascadas, parámetros con nombre, asíncrono/espera y flujos. Y, por encima de todo, les encantan las características de Flutter (como la recarga en caliente) que son posibles gracias a Dart, y las hermosas y eficaces aplicaciones que Dart les ayuda a crear. Dart 2 también hace que la new
palabra clave sea opcional. Esto significa que es posible describir muchas vistas de Flutter sin usar ninguna palabra clave , lo que las hace menos desordenadas y más fáciles de leer. Por ejemplo:
Dart 2 también usa la inferencia de tipos para hacer que muchos usos de la palabra clave const
sean opcionales al no requerir que const
se especifique de manera redundante dentro de un contexto const
. Por ejemplo, la declaración:
Debido a que el breakfast
es const
, se infiere que todo lo demás también es const
.
El enfoque es algo bueno . Prácticamente todos los lenguajes populares perdurables se beneficiaron de estar muy enfocados. Por ejemplo:
Por otro lado, muchos lenguajes han intentado explícitamente (y fallado) ser completamente de propósito general, como PL/1 y Ada, entre otros. El problema más común es que sin foco , estos lenguajes se convirtieron en proverbiales fregaderos de cocina.
Muchas de las características que hacen de Dart un excelente lenguaje del lado del cliente también lo convierten en un mejor lenguaje para usar en el lado del servidor. Por ejemplo, el hecho de que Dart evite la multitarea preventiva le otorga las mismas ventajas que Node en el servidor, pero con una escritura mucho mejor y más segura. Lo mismo ocurre con la escritura de software para sistemas integrados. La capacidad de Dart para manejar múltiples entradas simultáneas de manera confiable es clave aquí. Finalmente, el éxito de Dart en el cliente inevitablemente generará más interés en usarlo en el servidor, tal como sucedió con JavaScript y Node. ¿Por qué obligar a las personas a usar dos idiomas diferentes para crear software cliente-servidor?