[Evento] using cpp::std 2013

El pasado día 26 de noviembre se celebró en la Universidad Carlos III un evento dedicado al desarrollo de C++. Tuve la oportunidad de participar como ponente hablando del desarrollo paralelo con la Microsoft Parallel Pattern Library (PPL).

Dejo aquí la presentación y las demos que hice en C++.

clip_image002

 

Y el código de las demos de PPL en C++.

Luis Guerrero

Windows Azure Technical Evangelist

@guerrerotook

Conoce Azure con estas dos series de webcasts

La nube, el cloud computing, entornos híbridos, etc. Términos que hace unos años sonaban como otra tendencia más que venía encima aunque sin saber si lo hacía para quedarse o para desaparecer como muchas otras anteriores. Su importancia es clara, solo tenemos que fijarnos en algunas de las cifras de Microsoft disponibles en Microsoft by the Numbers: The Enterprise Cloud:

  • 50% de las compañías Fortune 500 ya usan Windows Azure, la nube pública de Microsoft.
  • 1.000 nuevos clientes se dan de alta en Azure cada día.
  • 1 de cada 4 clientes empresariales de Microsoft ya trabajan en la nube gracias a Office 365.
  • Microsoft ha invertido más de 15 mil millones de euros en sus datacenters y sigue invirtiendo cada día más para mejorarlo y ampliarlos.

Por ello, no hay mejor forma que estar preparado frente al cambio que conocerlo. A lo largo de octubre y noviembre hemos puesto a vuestra disposición los IT Camps de Windows Azure en 5 ciudades españolas donde habéis podido conocer los detalles que traía Azure en el ámbito de la Infraestructura como Servicio (IaaS). ¡Gracias a todos los que habéis participado!

Ahora, queremos continuar ayudándoos a conocer las ventajas de la nube a través de dos series de eventos online que hemos puesto en marcha para que tengáis cada semana una nueva oportunidad de aprender.

  • Los #CloudIO en colaboración con Desarrolloweb donde cada quince días os iremos introduciendo los principios básicos de las diferentes soluciones que te ofrece Windows Azure. Ayer miércoles tuvimos el primero de Máquinas Virtuales y ya lo tenéis disponible en diferido para verlo. A través de @deswebcloud podréis tener toda la información de los próximos eventos.    
  • Los webcasts #AzureTechnet en colaboración con los MVPs de Windows Azure Ibón Landa y Quique Martínez donde profundizaremos en los detalles más técnicos y avanzados de cada producto. En ellos encontraréis también los consejos y recomendaciones extraídas de su trabajo diario con Windows Azure.

El siguiente evento que tendremos será el próximo miércoles, 27 de Noviembre en el webcast #AzureTechnet sobre Máquinas Virtuales. En él se tratará:

  • Redes virtuales para la conexión entre servicios en la nube y en tu datacenter.
  • Escenarios de alta disponibilidad para lograr dar un servicio sin interrupciones.
  • Escalado dinámico para asumir las cargas y picos de trabajo.
  • Automatización de tareas de aprovisionamiento para reducir los tiempos y los errores.
  • Monitorización y diagnóstico para reaccionar rápido frente a cualquier problema.

Podéis comenzar ya a registraros.

Si queréis conocer lo que cubriremos en ambas series, aquí os dejo los contenidos preparados:

  • Windows Azure Virtual Machines: máquinas virtuales de Windows Server y Linux en la nube    
  • Windows Azure Mobile Services: cómo crear un backend para tu app movil en segundos. Con soporte para Windows Store, Windows Phone, iOS, Android y HTML / Javascript.    
  • Windows Azure Notification Hubs: envía millones de notificaciones push a dispositivos Windows, iOS o Android con una única llamada de API.     
  • Windows Azure Storage:  Es el servicio de almacenamiento con tres abstracciones, Tablas, Colas y Blobs       
  • Windows Azure Web Sites: Te permite crear tu sitio web en segundos. Elige entre mucha de las plantillas de aplicación, o conecta tu repositorio de código para publicar directamente.       
  • Windows Azure Cloud Services: Los servicios en la nube, permite a las aplicaciones empresariales escalar hasta el infinito, elije entre roles web o de trabajo.      
  • Active Directory y MFA: Aloja tu controlador de dominio en Windows Azure y habilita a tus usuarios la autenticación en dos pasos. (Multi-Factor Authentication)      
  • Windows Azure Media Services: Es el servicio que te permite la ingesta masiva de videos, la codificación en diferentes formatos y calidades, la protección de tu IP con PlayReady y la distribuccion de los contenidos a través de la CND con soporte para re empaquetar el contenido al vuelo.   
  • HDInsight: Crea tu cluster de Apache Hadoop en segundos y utiliza el algoritmo Map-Reduce.   
  • Windows Azure Cache & Traffic Manager: El servicio de Windows Azure Cache permite guardar objetos en una cache distribuida de alto rendimiento. Traffic Manager es la manera de gestionar como los usuarios acceder a tu servicio mundialmente.     
  • Backup Service: Este servicio te permite hacer backup de tus datos de onpremises en la nube

Nos vemos en ellos. ¡Un saludo!

Luis Guerrero.

Technical Evangelist Windows Azure

@guerrerotook

Conoce Windows Azure con los #CloudIO de desarrolloweb.com

Desde Microsoft estamos decididos a que conozcas Windows Azure, así hasta finales de Abril vamos a tener una serie de #AzureIO en desarrolloweb.com.

Se pueden seguir las actualizaciones sobre los #CloudIO en @deswebcloud

Para la gente que no conozca el formato, www.desarrolloweb.com es un portal de ayuda a programadores de Web y otras soluciones que organizan los AzureIO. Se puede encontrar más información en esta dirección: http://www.desarrolloweb.com/en-directo/

Esta es la lista completa de todos los conceptos que vamos a cubrir en estos #AzureIO, así que estad atentos al blog y a las cuentas oficiales de Twitter de Microsoft España donde iremos publicando las direcciones de los eventos.

Windows Azure Virtual Machines

Máquinas virtuales de Windows Server y Linux en la nube

Enlace de YouTube.

Windows Azure Mobile Services

Crear un backend para tu app movil en segundos. Con soporte para Windows Store, Windows Phone, iOS, Android y HTML / Javascript

Windows Azure Notification Hubs

Envía millones de notificaciones push a dispositivos Windows, iOS o Android con una única llamada de API.

Windows Azure Storage

Es el servicio de almacenamiento con tres abstracciones, Tablas, Colas y Blobs

Windows Azure Web Sites

Te permite crear tu sitio web en segundos. Elige entre mucha de las plantillas de aplicación, o conecta tu repositorio de código para publicar directamente.

Windows Azure Cloud Services

Los servicios en la nube, permite a las aplicaciones empresariales escalar hasta el infinito, elije entre roles web o de trabajo.

Active Directory y MFA

Aloja tu controlador de dominio en Windows Azure y habilita a tus usuarios la autenticación en dos pasos. (Multi-Factor Authentication)

Windows Azure Media Services

Es el servicio que te permite la ingesta masiva de videos, la codificación en diferentes formatos y calidades, la protección de tu IP con PlayReady y la distribuccion de los contenidos a través de la CND con soporte para re empaquetar el contenido al vuelo.

HDInsight

Crea tu cluster de Apache Hadoop en segundos y utiliza el algoritmo Map-Reduce.

Windows Azure Cache & Traffic Manager

El servicio de Windows Azure Cache permite guardar objetos en una cache distribuida de alto rendimiento. Traffic Manager es la manera de gestionar como los usuarios acceder a tu servicio mundialmente.

Backup Service

Este servicio te permite hacer backup de tus datos de onpremises en la nube.

Luis Guerrero.

Technical Evangelist Windows Azure

@guerrerotook

Material del evento de comunidad de Sevilla

El pasado día 5 de noviembre, coincidiendo con el evento de TechDay Tour 2013 de Microsoft, se celebró un evento de comunidad en Sevilla en el participe junto con Javier Suarez y Pablo Escribano. Mi sesión fue sobre patrones de software en aplicaciones Windows Phone 8 y Windows 8.

En la sesión se explicarlos los patrones de desarrollo más comunes y cuando había que usarlos y cuando no. Os dejo la presentación de la charla y el código de ejemplo.

image

Descarga del codigo fuente.

Luis Guerrero.

std:cpp 2013

El proximo día 26 de noviembre en la Escuela Politécnica Superior de la Universidad Carlos III de Madrid tendrá lugar un evento sobre C++ para estudiantes y profesionales del sector.

Tendré el placer de participar en este evento dando una charla sobre programación paralela en C++ con Microsoft Parallel Pattern Library, en la que hablaré sobre la programación paralela en la versión de Task Parallel Library en C++.

Si estas interesado en asistir, la entrada es gratis, os dejo información sobre el organizador del evento.

Estimado colega,

Me gustaría presentarte la Jornada de C++: “using std::cpp 2013″ organizada por el grupo de investigación ARCOS de la Universidad Carlos III de Madrid. Esta jornada nace como un foro de foro de intercambio de experiencias de uso del lenguaje C++, prestando especial atención al reciente estándar C++11 y los próximos C++14 y C++17.

¿A quien va dirigido using std::cpp 2013?

El evento va dirigido a desarrolladores profesionales que utilizan C++ como lenguaje de desarrollo de aplicaciones o software de infraestructura. También va dirigido a estudiantes de últimos años de carrera interesados en el uso de C++ como un lenguaje de programación para producir sistemas informáticos complejos con altas prestaciones.

¿Cuándo y dónde se celebra using std::cpp 2013?

Se celebrará el día 26 de noviembre de 2013 en Leganés, en la Escuela Politécnica Superior de la Universidad Carlos III de Madrid.

¿Cuál es el programa del evento?

Hemos preparado un intenso programa con presentaciones de destacados desarrolladores de empresas líderes en su sector (Indizen, TCP, BBVA, Telefónica, Digital, INDRA, Biicode, Microsoft, Programming Research Group). Puedes acceder al programa en http://www.arcos.inf.uc3m.es/~cpp-day/?page_id=13.

¿Hace falta registrarse?

La asistencia a using std::cpp es gratuita, pero necesitamos que te registres para facilitar la organización del evento. Puedes registrarte en http://www.arcos.inf.uc3m.es/~cpp-day/?page_id=2.

Caneles de información

Puedes seguirnos en

Twitter: https://twitter.com/usingstdcpp

Google Groups: https://plus.google.com/u/0/communities/102726875548983454259

LinkedIn: http://www.linkedin.com/groups/Desarrolladores-C-España-2863690

¡Hola Mundo Microsoft Edition!

Este post no es sobre programación, ni sobre ningún producto de Microsoft como tal, pero está relacionado con Microsoft.

Después de más de 5 años trabajando con Plain Concepts he decidido dar el salto y cambiar de trabajo. Ha sido una decisión difícil porque Plain Concepts es un sitio donde me he sentido muy a gusto y donde más he tenido la oportunidad de aprender muchísimo.

Pero las cosas cambian y como no, los trabajos también. Así que a partir de ahora trabajo en Microsoft como Technical Evangelist de Windows Azure en el equipo de DPE. Es todo un placer y un honor para mí formar parte de esta gran familia que es Microsoft en España, y sobre todo de tener la oportunidad de compartir mi pasión por la tecnología de Microsoft.

Como os podréis imaginar, parte de mi trabajo consiste en hacer que las personas, las empresas y los desarrolladores utilicen y saquen provecho al máximo de todo lo que Microsoft tiene que ofrecer en tecnología.

Eso significa que este blog seguirá siendo técnico, sobre tecnología de Microsoft, no solo Windows Azure, si no cualquier tipo de tecnología.

Luis Guerrero.

3 formas diferentes de publicar una Web en Windows Azure.

Introducción

Windows Azure es una plataforma muy flexible en la que se pueden publicar y consumir todo tipo de aplicaciones. En este post se repasarán las 3 formas que hay de publicar un Web, viéndose las ventajas e inconvenientes de las tres formas.

Las tres maneras son: Máquinas virtuales (Infraestructura como servicio IaaS), Servicios de nube (Plataforma como servicio, PaaS) y Windows Azure Web Sites.

Maquinas Virtual, IaaS

Las máquinas virtuales, como su nombre indica es la capacidad que tiene Windows Azure de hostear una máquina virtual basada en ficheros vhdx. Desde el portal de Windows Azure se puede seleccionar nueva máquina virtual y seleccionar creación rápida. De esa manera se tiene una maquina encendida y funcionado.

Una vez generada la VM se puede instalar desde ahí, Internet Information Services y copiar nuestra aplicación Web en la máquina.

Ventajas

  • Se tiene toda la flexibilidad para instalar y administrar la máquina virtual desde escritorio remoto.
  • Se puede alojar la aplicación web en Linux.
  • La máquina virtual es persistente.

Inconvenientes

  • No hay mecanismo definido para publicar la web. Copiar los ficheros por escritorio remoto a mano o cualquier otro mecanismo.
  • Hay que configurar e instalar IIS y ASP.NET.
  • Se tiene que configurar y administrar el balanceo de carga a mano para el puerto de HTTP/HTTPS. Cuando se quieran agregar más maquinas se tiene que hacer a mano.
  • Las tareas de administración se tienen que repetir para todas las máquinas.
  • El usuario es responsable del mantenimiento del S.O.

Servicios en la nube (Plataforma como servicio)

Este fue el primer servicio con el que se lanzó Windows Azure. Permite empaquetar una aplicación Web, independientemente del tipo de lenguaje o runtime, y publicar esa aplicación en el número de máquinas que se hayan designado en el fichero de configuración.

En este método de publicar aplicaciones web, se genera una máquina virtual, se instala y configura IIS con los valores presentes en el fichero de configuración del servicio y se copia el código de la aplicación web al directorio de publicación de IIS.

El proceso es completamente automático y no requiere atención por el usuario en ningún momento. No tiene límite en cuanto al número de instancias de máquinas. (Cómo curiosidad decir que el máximo de máquinas que el autor ha configurado han sido 750, toda una pasada)

Ventajas

  • Flexibilidad para empaquetar y publicar la aplicación.
  • No requiere configuración por parte del usuario, está completamente automatizado.
  • Permite incrementar y reducir el número de instancias a petición del usuario, también de manera automática.
  • Tiene soporte para el autoscale de Windows Azure.
  • Permite configurar aplicaciones web en subdominios y subcarpetas como aplicaciones (en IIS).
  • Permite configurar todos los certificados SSL que se deseen.

Inconvenientes

  • Las máquinas donde se ejecutan no son persistentes. Hay que guardar todos los datos fuera de la máquina donde se ejecuta. Por ejemplo en un Windows Azure Storage.
  • Las peticiones Http al servicio no tienen afinidad, lo que significa que cualquier petición puede ir a cualquiera de las maquinas del servicio en la nube. Hay que configurar la sesión de ASP.NET para que se guarde en Sql Server, Windows Azure Cache Service o Windows Azure Storage.
  • Hay que ser capaz de empaquetar la aplicación web y todas sus dependencias de software.

Windows Azure Web Sites

Windows Azure Web Sites es otro servicio de Windows Azure enfocado a la publicación de aplicaciones Web pero, ¿Cuál es la diferencia con un servicio en la nube? Los servicios en la nube pueden contener, además de un rol de tipo Web, un rol de tipo de trabajo. Es decir un servicio en la nube es una colección de roles de trabajo y de web. Un rol de trabajo es como un servicio de Windows, pero que se ejecuta en Windows Azure y ejecuta tareas en segundo plano. Esas tareas pueden ser generar informes, consolidad información en la base de datos, envíos masivos de emails, cambio de resolución de imágenes y todo aquello que se tiene que hacer en nuestra aplicación web, pero que no se quiere que se impacte en el rendimiento del sitio web.

Volviendo al tema de Windows Azure Web Sites, este servicio ofrece tres modos de funcionamiento:

  • Gratis: los usuarios tienen hasta un máximo de 10 sitios web de manera gratuita, 1 Gb de espacio en disco y 165 megas de salida al día.
  • Compartida: hasta un máximo de 100 sitios web, que se pueden escalar hasta un máximo de 6 instancias, con 1 Gb de espacio en disco y el tráfico de salida se factura al precio estándar.
  • Estándar: hasta un máximo de 500 sitios web con una CPU dedicada, 10Gb de espacio en disco y el tráfico de salida se factura al precio estándar.

Con estas tres configuraciones se ofrecen diferentes maneras y precios de alojar tu aplicación web según los requerimientos del usuario.

Otra de las diferencias con respecto a los servicios en la nube, es la forma de publicar tu sitio web. WAWS ofrece varias maneras de publicar:

  • Microsoft Web Publishing: Permite publicar un proyecto de web directamente desde Visual Studio.
  • Team Foundation Service: se pude publicar directamente desde TFS Service, la solución en la nube de TFS. No funciona con TFS on premises.
  • Repositorio local de Git: puedes hacer push desde un repositorio local a uno online que representa tu sitio web.
  • Github es un servicio de hosting en Git de terceros.
  • Dropbox: te permite configurar una carpeta de la cuenta para publicar directamente en tu sitio web.
  • Bitbucket: otro servicio de hosting de Git como Github.
  • Codeplex: el servicio de hosting de proyectos de Microsoft.
  • External repository: un repositorio externo en una URL.

Otro de los aspectos que se pueden configurar en el servicio es la versión de .NET Framework en la que se ejecuta la Web, V3.5 o V4.5. Otro de los lenguajes que vienen instalados es PHP que se puede deshabilitar o cambiar la versión de 5.3 a 5.4.

Ventajas

  • Flexibilidad en cuanto al método de publicación de la web.
  • Perfecta para trabajo en equipo.
  • Rapidez, dar de alta un sitio web en Windows Azure son segundos y tener tu web online también.

Inconvenientes

  • No se puede acceder a la configuración de IIS, solamente la configuración que se ofrece desde el portal de administración de Windows Azure.
  • El número de instancias de los modos de compartido y estándar son máximo 6 y 10 respectivamente. En los servicios de la nube no hay límite.

Espero que el artículo haya sido de ayuda para decidirse con qué servicio de Windows Azure se ajusta mejor a las necesidades de cada proyecto.

Migrando una aplicación de Windows 8 a Windows 8.1. Caso práctico Reddit 8.1

Windows 8.1

El lanzamiento de Windows 8.1 es inminente y al ser una actualización gratuita del Sistema Operativo, será mucha gente, por lo decir la mayoría, la que se instale la actualización. Eso significa que si eres desarrollador de Aplicaciones de la Tienda de Windows, estarás muy ocupado ahora mismo migrando tu aplicación de Windows 8 a Windows 8.1.

En esta serie de artículos se van a detallar los diferentes pasos de migración de las aplicaciones. Y para tener un ejemplo concreto se hablará de una aplicación concreta Reddit8. Un cliente de Reddit para Windows 8 que ya está en la Store y que he procedido a migrar a Windows 8.1. Con este pretexto pretendo enseñar los diferentes desafíos que he tenido a nivel personal durante la migración y como la aplicación ha evolucionado.

TfsService

La primera recomendación antes de empezar con la migración es la de tener un control de código fuente. Esto es así porque cuando se empiece la migración, el proceso es irreversible y no se podrá volver a la versión anterior de Windows. Teniendo esto en cuenta se extrae que las aplicaciones de Windows 8.1 no son compatibles con Windows 8. Pero eso no significa que no se quiera seguir dando soporte a los clientes que tengan Windows 8.

Pon un control de código fuente en tú vida.

Es por eso que el primer paso antes de nada, es asegurarse de que se está trabajando con un control de código fuente. Yo recomiendo usar Team Foundation Service (http://tfs.visualstudio.com/) porque se integra perfectamente con Visual Studio, incluye gestión de elementos de trabajo, está en la nube y accesible desde cualquier sitio, permite trabajar con equipos de manera ágil y planificar los procesos de desarrollo.

Y lo mejor de todo esto, es que se puede usar de manera gratuita hasta 5 usuarios simplemente teniendo una cuenta de Microsoft.

image

Branch

Lo primero que hay que hacer, después de tener el código fuente en TfsService es crear una rama dentro del proyecto en el que se esté trabajando. En el ejemplo que se está siguiendo en el artículo, se pasó de llamar la carpeta Reddit8 a llamarse Reddit8.1 y ser una rama de la carpeta antes mencionada.

Migrando a Windows 8.1

La primera vez que se abre un proyecto de Windows 8 en Visual Studio 2013 Preview, VS avisa de que la solución es un proyecto de Windows 8 y que si se desea migrar a Windows 8.1. Si se elige la opción de sí, se migran todos los proyectos que tengan la solución a Windows 8.1 siendo este proceso irreversible.

En el caso de querer hacer el proceso de migración en otro momento lo único que hay que hacer es ir a las propiedades del proyecto, y en la pestaña de aplicación aparece un desplegable con la opción de cambiar la plataforma.

image

Errores de compilación

Una vez que se ha realizado el proceso de cambiar la plataforma de destino de todos los proyectos, 4 en Reddit8, se compila el proyecto y aparecen los primeros errores.

image

Que se pueden resumir en errores del framework de publicidad de Microsoft, que no es la versión correcta, y el resto de errores, son a la hora de actualizar las Tiles secundarios de la aplicación. Esto es comprensible, porque una de las características nuevas de Windows 8.1 es justamente que se han cambiado el tamaño de los Tiles.

Estos errores son fáciles de corregir. El primero simplemente es bajarse la versión para Windows 8.1 del SDK de Advertising de Microsoft de aquí. (http://msdn.microsoft.com/en-us/library/dn283993(v=msads.10).aspx)

Y el resto de errores no son tan inmediatos de corregir, porque la forma en la que se generar los Tiles secundarios ha cambiado, así que no es simplemente corregir los errores sino que hay que añadir nueva funcionalidad.

API Obsoletas

Después de corregir esos errores de los Tiles secundarios aparecen una lista de errores más grande con API que se han hecho obsoletas en Windows 8.1 y que hay otra manera de consumirlas. Se resumen brevemente en:

  • ScrollViewer. Ya no tiene métodos específicos para cambiar el desplazamiento vertical y horizontal, sino que se han integrado todos en un método llamado ChangeView que te permite cambiar desplazamiento vertical, horizontal y valor de zoom.
  • ItemsControls. Ya no se puede usar la propiedad ItemContainerGenerator que permite obtener el contenedor de una colección de elementos a partir de índice o del valor. Simplemente se ha de eliminar el texto de ItemContainerGenerator, ya que, por ejemplo, ContainerFromIndex forma parte de la clase ItemsControls y no de la clase ItemContainerGenenator.
  • ApplicationView.Value. Si se estaba usando la plantilla de código que venía con Visual Studio que incluía una clase llamada LayoutAwarePage, se ha simplificado el desarrollo de este componente.
  • DataPackage. El método SetUri, se ha cambiado por SetWebLink o SetApplicationLink.

Cambio en experiencia de usuario

Las novedades de Windows8.1 no solo están en el código sino también en los controles nuevos que permiten acercase mucho más a la experiencia de usuario de Windows8 de manera más sencilla.

A continuación se verán algunos de los cambios de funcionalidad que se han podido mejorar con controles y funcionalidad específica de Windows 8.1.

HomePage

La página principal de la aplicación ha pasado de tener un GridView con dos categorías, frontpage y subreddits.

image

A esto otro.

image

El cambio ha sido a mucho mejor. Se ha utilizado el nuevo control Hub, que soporta zoom semántico y organizar la información en secciones para mostrarlas todas seguidas.

En el caso concreto de Reddit8 se muestra una imagen que pertenece a la frontpage, que en la medida de lo posible se intenta que no se repita y el usuario siempre pueda ver contenido directamente.

El Hub control es una colección de HubSections, incluyendo una cabecera de todo el control. Cada una de las secciones incluye una cabecera y un contenido que es establecido a través de una plantilla. Así de esta manera podemos personalizar tanto el contenido como el aspecto de cada una de las secciones.

clip_image011Otro cambio incluido en la app, es la nueva barra de búsqueda que tiene la misma funcionalidad que el charm de búsqueda de Windows 8. Además se pueden seguir haciendo sugerencias de contenido conforme el usuario escribe. De esta manera ya no es necesario activar la capacidad de busqueda, ya que los dos son incopatibles entre sí.

Vista de Subreddit

Esta es la vista antes del cambio. Un GridView exactamente igual que en la página principal, pero que además mostraba información sobre el subreddit.

image

Esta es la manera en la que se muestra el contenido ahora:

image

Se ha vuelto a utilizar el mismo tipo de layout que en la página principal, pero esta vez el título de Hub es el nombre del subreddit (/r/windows8). Se ha eliminado la información del subreddit por considerarse superflua y se ha puesto en la barra de comandos.

image

En la barra de comandos de abajo aparecen, utilizando la nueva CommandBar, los comandos que son principales y secundarios. Los principales son refrescar, subscribirse al subreddit (si has iniciado sesión) agregarlos a favoritos para la navegación de la barra de arriba. En el caso de los comandos secundarios está anclar al inicio e información. Este último utiliza el controls Flyout para mostrar contenido de manera mucho más cómoda y directa que antes.

El desarrollo de la barra de comandos, se ha simplificado y se ha hecho más acorde con el estilo de aplicaciones de Windows 8.

Live tiles

Otra de las novedades de Windows 8.1 es el cambio de tamaño de los Tiles en el menú de inicio. Ahora cuando un usuario quiere anclar un elemento puede elegir el tamaño en el que quiere anclarlo.

clip_image018

Eso significa que se puede tener tiles en todos los tamaños, incluso cuando el usuario los crea.

clip_image019

Conclusión

Windows 8.1 es una mejora muy sustancial de las API que Microsoft ofrece a los desarrolladores. Ahora es más fácil que nunca adecuar nuestras aplicaciones de Windows 8 con la estética de Modern UI. Y en el caso concreto de Reddit8 la mejora, desde mi punto de vista, es más que notable. Ahora el contenido es el centro del diseño y de la funcionalidad.

Si quieres probar la nueva funcionalidad de este cliente de Reddit, puedes ir aquí para descargarte las betas que hay públicas.

http://www.reddit.com/r/reddit8/

Usando un ContentControl como hijo de un Control SemanticZoom en XAML+C# de Windows 8

El Zoom Semantico de Windows 8 permite que los usuarios puedan hacer zoom sobre el contenido de una aplicación. Esto no significa que el Zoom esté centrado en pixeles como en normal, sino que el zoom está centrado en contenido. Veamos un ejemplo de esto:

SemanticZoom

El zoom semántico permite tener dos vistas de un mismo contenido. Una vista de zoom cercano y otra vista de zoom lejano, ambas se puede intercambiar a través de interacciones de la plataforma como teclado, ratón y táctil. El código XAML correspondiente a este control sería este:

<SemanticZoom>
    <SemanticZoom.ZoomedInView>
        <GridView />
    </SemanticZoom.ZoomedInView>
    <SemanticZoom.ZoomedOutView>
        <GridView />
    </SemanticZoom.ZoomedOutView>
</SemanticZoom>

 

Este control tiene dos propiedades, ZoomedInView y ZommedOutView que son de tipo ISemanticZoomInformation. Esta interfaz es que permite la comunicación con el sistema de Zoom semántico para así poder cambiar la vista en cualquier momento que el usuario lo desee. Los dos únicos controles que implementan esa interfaz son el GridView y el ListView.

clip_image002

clip_image004

Aquí se puede ver un ejemplo de aplicación con dos vistas en zoom semántico.

Pero, ¿qué pasa si quiero usar otro control que no sea un GridView como hijo del Zoom Semántico?

SemanticZoomHost

Este control permite tener cualquier árbol de objetos en xaml y que a su vez pueda ser hijo de cualquiera de las dos propiedades del SematicZoom. Esta clase implementa la interfaz ISemanticZoomInformation, pero permite que la información de zoom se transadle a uno de sus hijos.

image

De esta manera se puede no tener un GridView únicamente sino que se puede tener cualquier tipo control y dentro de ese árbol un control GridView.

Ejemplo

<SemanticZoom>
    <SemanticZoom.ZoomedInView>
        <controls:SemanticZoomHost>
            <StackPanel>
                <TextBlock Text="Titulo"></TextBlock>
                <GridView controls:SemanticZoomHost.SemanticZoomHost="true"></GridView>
            </StackPanel>
        </controls:SemanticZoomHost>
    </SemanticZoom.ZoomedInView>
    <SemanticZoom.ZoomedOutView>
        <GridView />
    </SemanticZoom.ZoomedOutView>
</SemanticZoom>

 

¿Cómo está implementado SemanticZoomHost?

La idea que hay detrás es muy sencilla, una clase que herede de ContentControl, para que así pueda tener hijos en el árbol visual, y que implemente la interfaz ISemanticZoomInformation. La clase en sí no hace nada con la implementación de la interfaz, es decir, que simplemente traslada las llamadas al control que realmente implementa ISemanticZoomInformation. Es por eso que el control SemanticZoomHost tiene una propiedad de tipo ISematicZoomInformation que será el control que manejará el zoom semántico.

public ISemanticZoomInformation ISemanticZoomInformationHost
{
    get { return (ISemanticZoomInformation)GetValue(ISemanticZoomInformationHostProperty); }
    set { SetValue(ISemanticZoomInformationHostProperty, value); }
}

public static readonly DependencyProperty ISemanticZoomInformationHostProperty =
    DependencyProperty.Register(
        "ISemanticZoomInformationHost",
        typeof(ISemanticZoomInformation),
        typeof(SemanticZoomHost),
        new PropertyMetadata(null));

 

Attached Property

Esa propiedad tiene que ser establecida de manera automática, es decir, que de alguna manera el sistema tiene que buscar que control del árbol visual es el encargado de establecer esa propiedad. Es en este punto donde las Attached property entran en acción para que el propio control SemanticZoomHost defina una attached property llamada SemanticZoomHost de tipo booleana, que será utilizada para marcar que control en el árbol visual es el encargado de ser el receptor de la información del zoom semántico.

public static bool GetSemanticZoomHost(DependencyObject obj)
{
    return (bool)obj.GetValue(SemanticZoomHostProperty);
}

public static void SetSemanticZoomHost(DependencyObject obj, bool value)
{
    obj.SetValue(SemanticZoomHostProperty, value);
}

public static readonly DependencyProperty SemanticZoomHostProperty =
    DependencyProperty.RegisterAttached(
        "SemanticZoomHost",
        typeof(bool),
        typeof(SemanticZoomHost),
        new PropertyMetadata(false));

 

Buscando ese control en el árbol visual

La última tarea que tiene la clase es buscar los controles en el árbol visual que tengan esa propiedad a true y establecer esa propiedad. Como el control es del tipo ContentControl, tiene el método OnApplyTemplate, pero que en este caso no se puede usar porque el control en sí se ha cargado pero no todos los hijos, así que hay que usar el evento Loaded para saber cuándo se ha terminado de cargar todo el árbol visual de todos los hijos.

void OnSemanticZoomHostLoaded(object sender, RoutedEventArgs e)
{
    List<DependencyObject> all = ControlTreeHelper.GetAllControlsByType<DependencyObject>(this);
    foreach (var item in all)
    {
        if (SemanticZoomHost.GetSemanticZoomHost(item))
        {
            ISemanticZoomInformation semanticZoom = (ISemanticZoomInformation)item;
            semanticZoom.IsActiveView = isActiveView;
            semanticZoom.IsZoomedInView = isZoomedView;
            semanticZoom.SemanticZoomOwner = owner;

            this.ISemanticZoomInformationHost = semanticZoom;
            break;
        }
    }
}

 

El resto de la implementación son los métodos de la interfaz ISemanticZoomInformation.

Implementación

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace SematicZoomDemo.Controls
{
    public class SemanticZoomHost : ContentControl, ISemanticZoomInformation
    {
        public SemanticZoomHost()
        {
            Loaded += OnSemanticZoomHostLoaded;
        }

        void OnSemanticZoomHostLoaded(object sender, RoutedEventArgs e)
        {
            List<DependencyObject> all = ControlTreeHelper.GetAllControlsByType<DependencyObject>(this);
            foreach (var item in all)
            {
                if (SemanticZoomHost.GetSemanticZoomHost(item))
                {
                    ISemanticZoomInformation semanticZoom = (ISemanticZoomInformation)item;
                    semanticZoom.IsActiveView = isActiveView;
                    semanticZoom.IsZoomedInView = isZoomedView;
                    semanticZoom.SemanticZoomOwner = owner;

                    this.ISemanticZoomInformationHost = semanticZoom;
                    break;
                }
            }
        }

        public void CompleteViewChange()
        {
            ISemanticZoomInformationHost.CompleteViewChange();
        }

        public void CompleteViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination)
        {
            ISemanticZoomInformationHost.CompleteViewChangeFrom(source, destination);
        }

        public void CompleteViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination)
        {
            ISemanticZoomInformationHost.CompleteViewChangeTo(source, destination);
        }

        public void InitializeViewChange()
        {
            ISemanticZoomInformationHost.InitializeViewChange();
        }

        public void MakeVisible(SemanticZoomLocation item)
        {
            ISemanticZoomInformationHost.MakeVisible(item);
        }


        public void StartViewChangeFrom(SemanticZoomLocation source, SemanticZoomLocation destination)
        {
            ISemanticZoomInformationHost.StartViewChangeFrom(source, destination);
        }

        public void StartViewChangeTo(SemanticZoomLocation source, SemanticZoomLocation destination)
        {
            ISemanticZoomInformationHost.StartViewChangeTo(source, destination);
        }

        public bool IsActiveView
        {
            get
            {
                return ISemanticZoomInformationHost.IsActiveView;
            }
            set
            {
                if (ISemanticZoomInformationHost == null)
                {
                    isActiveView = value;
                }
                else
                {
                    ISemanticZoomInformationHost.IsActiveView = value;
                }
            }
        }

        public bool IsZoomedInView
        {
            get
            {
                return ISemanticZoomInformationHost.IsZoomedInView;
            }
            set
            {
                if (ISemanticZoomInformationHost == null)
                {
                    isZoomedView = value;
                }
                else
                {
                    ISemanticZoomInformationHost.IsZoomedInView = value;
                }
            }
        }

        public SemanticZoom SemanticZoomOwner
        {
            get
            {
                return ISemanticZoomInformationHost.SemanticZoomOwner;
            }
            set
            {
                if (ISemanticZoomInformationHost == null)
                {
                    owner = value;
                }
                else
                {
                    ISemanticZoomInformationHost.SemanticZoomOwner = value;
                }
            }
        }

        private SemanticZoom owner;
        private bool isZoomedView;
        private bool isActiveView;

        public ISemanticZoomInformation ISemanticZoomInformationHost
        {
            get { return (ISemanticZoomInformation)GetValue(ISemanticZoomInformationHostProperty); }
            set { SetValue(ISemanticZoomInformationHostProperty, value); }
        }

        public static readonly DependencyProperty ISemanticZoomInformationHostProperty =
            DependencyProperty.Register(
                "ISemanticZoomInformationHost",
                typeof(ISemanticZoomInformation),
                typeof(SemanticZoomHost),
                new PropertyMetadata(null));

        public static bool GetSemanticZoomHost(DependencyObject obj)
        {
            return (bool)obj.GetValue(SemanticZoomHostProperty);
        }

        public static void SetSemanticZoomHost(DependencyObject obj, bool value)
        {
            obj.SetValue(SemanticZoomHostProperty, value);
        }

        public static readonly DependencyProperty SemanticZoomHostProperty =
            DependencyProperty.RegisterAttached(
                "SemanticZoomHost",
                typeof(bool),
                typeof(SemanticZoomHost),
                new PropertyMetadata(false));
    }
}

 

 

Conclusión

En SematicZoom es un control muy útil a la hora de hacer zoom semántico en una aplicación de Windows 8, pero desde mi punto de vista es una limitación que solamente se pueda establecer un ListView o un GridView. En muchas ocasiones los layouts que se puede obtener son muy complejos.

ControlTreeHelper

Como podéis ver en el código se utiliza una clase llamada ControlTreeHelper. Esta clase fue diseñada para usarse en WPF (Windows Presentation Foundation), ¡qué tiempos aquellos!.

La clase contiene métodos que nos permite recorrer el árbol visual de manera cómoda, paso a comentar algunos de esos métodos.

  • List<T> GetAllControlsByType<T>(DependencyObject root): Obtiene todos los controles hijos filtrados por el tipo T y los devuelve en una lista de T.
  • T FindUniqueParentControl<T>(DependencyObject leaf): Busca un padre directo en el arbol visual de tipo T.
  • T FindNameInVisualTree<T>(DependencyObject root, string name): Busca un elemento en el arbol visual de tipo T con el nombre pasado por parametro.

El código de ejemplo se puede descargar de aquí.

Luis Guerrero.

Optimizaciones de JavaScript utilizadas en el proyecto de Prometheus

Introducción

Para los que no lo sepáis, próximamente se estrena la película Prometheus en Estados Unidos y desde Plain Concepts hemos desarrollado el training center del sitio web. Se puede acceder desde este enlace: http://www.projectprometheus.com/trainingcenter/. El proyecto ha estado financiado por Microsoft, más concretamente por el equipo de Internet Explorer, así que como página web que es, se ha desarrollado utilizando las últimas tecnologías web: HTML5 + CSS3.

Training center

El centro de entrenamiento es un sitio web donde los candidatos al proyecto Prometheus, de la empresa Weyland, puede probar su valía. El entrenamiento cuenta con 5 pruebas (juegos) que el recluta tiene que completar en un tiempo determinado. Una vez superadas las cinco pruebas el recluta puede formar parte de Weyland Industries. Los cinco juegos han sido desarrollados por gente de Plain Concepts:

Cada uno de los cuales ha desarrollado uno de los juegos del centro de entrenamiento. En mi caso he desarrollado el cubo de rubick en 2 y 3 dimensiones.

clip_image001

Aquí se puede ver una captura del juego en Internet Explorer llamado Prefrontal Cortex.

HTML5 / Javascript

Todos los juegos han sido desarrollados en HTML5 utilizando JavaScript para la parte de programación, en mi caso he utilizado Canvas para dibujar los cubos. Eso significa que todos los juegos funcionan perfectamente en todos los navegadores modernos, incluyendo Google Chrome, Firefox, Safari, Opera y Internet Explorer 9 y 10.

Para el desarrollo de los juegos se creo un motor en JavaScript que nos permitiera dibujar en un Canvas la geometría de los modelos de los cubos. Este motor no utiliza WebGL para renderizar los cubos, porque Internet Explorer no tiene soporte (además de en el resto es experimental), por lo que se opto por hacer un motor grafico completo desde cero. Es decir, todo el pipeline de grafica se tiene que hacer en JavaScript, esto significa, entre otras cosas, que tenemos que emular por software como funciona una tarjeta gráfica y eso normalmente es más lento que el propio hardware. Así que el desafío de implementar un pipeline gráfico por software es mayor ya que tiene que tener un rendimiento aceptable.

JavaScript 101

JavaScript es un lenguaje en el que existen varios tipos de datos básicos con los que podemos trabajar.

  • Object
  • Array
  • Number
  • String
  • Boolean

Los objetos son la forma más común a la hora de trabajar en JavaScript y se pueden utilizar de muchas maneras.

La forma más sencilla de crear un objeto es:

   1: var myObject = {}

A partir de ahí se pueden ir agregando propiedades al objeto sin ningún tipo de restricción. No son propiedades como las que se puede estar acostumbrado en C#, sino que el tipo object se comporta como una especie de diccionario de pares nombre valor.

Se pueden crear propiedades de la siguiente manera a un objeto previamente definido.

   1: myObject.name = ‘Luis’;

   2: myObject.number = 42;

Así el objeto pasará a tener dos propiedades, una llamada ‘name’ con el valor ‘Luis’ y otra llamada ‘number’ con el valor ‘42’.

También se puede acceder a esas propiedades como si de un diccionario se tratase. Las dos formas son igual de válidas y correctas.

   1: var name = myObject[‘name’];

Después de la ejecución de esta línea de código lo que se establece en la variable name es el valor de ‘Luis’, previamente establecido.

Con esta nueva forma de acceder a las propiedades no solo se pueden leer valores almacenados en un objeto sino que también se pueden guardar.

myObject[‘currentDate’] = new Date();

Vector3

Como ejemplo de objeto se va a definir Vector3; un vector de 3 dimensiones.

var vector3 = {x: 1, y: 1, z: 1}

¿Cuál es el problema con este Vector3?

El rendimiento. Como se ha dicho antes todos los objetos en JavaScript se comportan como un diccionario de pares nombre / valor, así que en cada una de las operaciones en las que se tenga que leer o escribir el valor de x, y o z, el runtime de JavaScript tiene que comprobar que la propiedad existe o no y luego leerla o almacenarla. Todo esto lleva tiempo. Es como si se programase todo el acceso a propiedades y campos en .NET utilizando únicamente la API de Reflexion (System.Reflection).

En el caso del motor de 3D en JavaScript Vector2, Vector3, Vector4, Color y Matrix son tipos que se están usando constantemente para dibujar la geometría de los cubos, así que esos tipos fueron los primero en ser optimizados.

La solución por la que se opto fue eliminar la definición de los tipos, es decir, que por ejemplo Vector2, Vector3, Vector4 y Color pasaron a ser un array de 2, 3, 4 y 4 posiciones respectivamente. Así que por convención lo que se hizo fue que la posición dentro del array representaba una coordenada de las dimensiones del vector.

  • X: array[0]
  • Y: array[1]
  • Z: array[2]
  • W: arrat[3]

En el caso de Matrix que se tenía M11, M12…M21,M22..M31..M44 pasaron a ser también las posiciones de un array.

Veamos como se ha cambiado la multiplicación de matrices, uno de los cuellos de botella, en cuanto a rendimiento se refiere.

Antes

   1: function Multiply(matrix1, matrix2) {

   2:     var matrix = new Matrix();

   3:     matrix.M11 = (((matrix1.M11 * matrix2.M11) + (matrix1.M12 * matrix2.M21)) + (matrix1.M13 * matrix2.M31)) + (matrix1.M14 * matrix2.M41);

   4:     matrix.M12 = (((matrix1.M11 * matrix2.M12) + (matrix1.M12 * matrix2.M22)) + (matrix1.M13 * matrix2.M32)) + (matrix1.M14 * matrix2.M42);

   5:     matrix.M13 = (((matrix1.M11 * matrix2.M13) + (matrix1.M12 * matrix2.M23)) + (matrix1.M13 * matrix2.M33)) + (matrix1.M14 * matrix2.M43);

   6:     matrix.M14 = (((matrix1.M11 * matrix2.M14) + (matrix1.M12 * matrix2.M24)) + (matrix1.M13 * matrix2.M34)) + (matrix1.M14 * matrix2.M44);

   7:     matrix.M21 = (((matrix1.M21 * matrix2.M11) + (matrix1.M22 * matrix2.M21)) + (matrix1.M23 * matrix2.M31)) + (matrix1.M24 * matrix2.M41);

   8:     matrix.M22 = (((matrix1.M21 * matrix2.M12) + (matrix1.M22 * matrix2.M22)) + (matrix1.M23 * matrix2.M32)) + (matrix1.M24 * matrix2.M42);

   9:     matrix.M23 = (((matrix1.M21 * matrix2.M13) + (matrix1.M22 * matrix2.M23)) + (matrix1.M23 * matrix2.M33)) + (matrix1.M24 * matrix2.M43);

  10:     matrix.M24 = (((matrix1.M21 * matrix2.M14) + (matrix1.M22 * matrix2.M24)) + (matrix1.M23 * matrix2.M34)) + (matrix1.M24 * matrix2.M44);

  11:     matrix.M31 = (((matrix1.M31 * matrix2.M11) + (matrix1.M32 * matrix2.M21)) + (matrix1.M33 * matrix2.M31)) + (matrix1.M34 * matrix2.M41);

  12:     matrix.M32 = (((matrix1.M31 * matrix2.M12) + (matrix1.M32 * matrix2.M22)) + (matrix1.M33 * matrix2.M32)) + (matrix1.M34 * matrix2.M42);

  13:     matrix.M33 = (((matrix1.M31 * matrix2.M13) + (matrix1.M32 * matrix2.M23)) + (matrix1.M33 * matrix2.M33)) + (matrix1.M34 * matrix2.M43);

  14:     matrix.M34 = (((matrix1.M31 * matrix2.M14) + (matrix1.M32 * matrix2.M24)) + (matrix1.M33 * matrix2.M34)) + (matrix1.M34 * matrix2.M44);

  15:     matrix.M41 = (((matrix1.M41 * matrix2.M11) + (matrix1.M42 * matrix2.M21)) + (matrix1.M43 * matrix2.M31)) + (matrix1.M44 * matrix2.M41);

  16:     matrix.M42 = (((matrix1.M41 * matrix2.M12) + (matrix1.M42 * matrix2.M22)) + (matrix1.M43 * matrix2.M32)) + (matrix1.M44 * matrix2.M42);

  17:     matrix.M43 = (((matrix1.M41 * matrix2.M13) + (matrix1.M42 * matrix2.M23)) + (matrix1.M43 * matrix2.M33)) + (matrix1.M44 * matrix2.M43);

  18:     matrix.M44 = (((matrix1.M41 * matrix2.M14) + (matrix1.M42 * matrix2.M24)) + (matrix1.M43 * matrix2.M34)) + (matrix1.M44 * matrix2.M44);

  19:     return matrix;

  20: }

La multiplicación simplemente accedía a cada uno de los índices de la matriz, los multiplicaba y luego los asignada de vuelta a la matriz de resultado. Como hemos dicho antes, esto implica leer una gran cantidad de propiedades durante el dibujado de un frame de la escena.

Ahora

   1: function Multiply(matrix1, matrix2) {

   2:     var matrix = new Matrix();

   3:     var position = matrix.position;

   4:     var position1 = matrix1.position;

   5:     var position2 = matrix2.position;

   6:     position[0] = (((position1[0] * position2[0]) + (position1[1] * position2[4])) + (position1[2] * position2[8])) + (position1[3] * position2[12]);

   7:     position[1] = (((position1[0] * position2[1]) + (position1[1] * position2[5])) + (position1[2] * position2[9])) + (position1[3] * position2[13]);

   8:     position[2] = (((position1[0] * position2[2]) + (position1[1] * position2[6])) + (position1[2] * position2[10])) + (position1[3] * position2[14]);

   9:     position[3] = (((position1[0] * position2[3]) + (position1[1] * position2[7])) + (position1[2] * position2[11])) + (position1[3] * position2[15]);

  10:     position[4] = (((position1[4] * position2[0]) + (position1[5] * position2[4])) + (position1[6] * position2[8])) + (position1[7] * position2[12]);

  11:     position[5] = (((position1[4] * position2[1]) + (position1[5] * position2[5])) + (position1[6] * position2[9])) + (position1[7] * position2[13]);

  12:     position[6] = (((position1[4] * position2[2]) + (position1[5] * position2[6])) + (position1[6] * position2[10])) + (position1[7] * position2[14]);

  13:     position[7] = (((position1[4] * position2[3]) + (position1[5] * position2[7])) + (position1[6] * position2[11])) + (position1[7] * position2[15]);

  14:     position[8] = (((position1[8] * position2[0]) + (position1[9] * position2[4])) + (position1[10] * position2[8])) + (position1[11] * position2[12]);

  15:     position[9] = (((position1[8] * position2[1]) + (position1[9] * position2[5])) + (position1[10] * position2[9])) + (position1[11] * position2[13]);

  16:     position[10] = (((position1[8] * position2[2]) + (position1[9] * position2[6])) + (position1[10] * position2[10])) + (position1[11] * position2[14]);

  17:     position[11] = (((position1[8] * position2[3]) + (position1[9] * position2[7])) + (position1[10] * position2[11])) + (position1[11] * position2[15]);

  18:     position[12] = (((position1[12] * position2[0]) + (position1[13] * position2[4])) + (position1[14] * position2[8])) + (position1[15] * position2[12]);

  19:     position[13] = (((position1[12] * position2[1]) + (position1[13] * position2[5])) + (position1[14] * position2[9])) + (position1[15] * position2[13]);

  20:     position[14] = (((position1[12] * position2[2]) + (position1[13] * position2[6])) + (position1[14] * position2[10])) + (position1[15] * position2[14]);

  21:     position[15] = (((position1[12] * position2[3]) + (position1[13] * position2[7])) + (position1[14] * position2[11])) + (position1[15] * position2[15]);

  22:     return matrix;

  23: }

Lo primero que se observa es que el código pasa a ser más críptico que el anterior, es decir, que ahora únicamente se tiene son los diferentes índices de position dentro de tres arrays, que representan las tres matrices con las que se esta trabajando en este momento.

Así que se ha pasado de,

matrix.M11 = (((matrix1.M11 * matrix2.M11) + (matrix1.M12 * matrix2.M21)) + 

(matrix1.M13 * matrix2.M31)) + (matrix1.M14 * matrix2.M41);

a esto:

position[0] = (((position1[0] * position2[0]) + (position1[1] * position2[4])) + 

(position1[2] * position2[8])) + (position1[3] * position2[12]);

Ya que ahora todas las posiciones de la matriz están almacenadas en un array de 16 posiciones lo que se tiene que hacer si se quiere acceder al valor M11 es acceder a la posición 0 de array, en el caso del valor M31 a la posición 8 de array y así sucesivamente.

Otras optimizaciones

Tamaño de los arrays

Si se tiene un array que tiene una propiedad length por la que se quiere iterar para realizar una acción por cada uno de los elementos del array, es recomendable no poner directamente el valor de myArray.length para comprobar si se ha llegado al final de array, sino guardar el tamaño del array en una variable y usar esta variable.

   1: var myArray = new Array();

   2:  

   3: for (var i = 0; i < myArray.length; i++) {

   4:     myArray[i] = i;

   5: }

   6:  

   7: var length = myArray.length;

   8: for (var i = 0; i < length; i++) {

   9:     myArray[i] = i;

  10: }

Cachear variables

Si durante la ejecución de un método se tiene variables que vamos a usar y estas variables son propiedades de un objeto, es mejor definirlas como variables en el ámbito del método que no referenciarlas desde el objeto original.

   1: var myObject =

   2:     {

   3:     name: 'luis',

   4:     company: {

   5:         name: 'PlainConcepts',

   6:         location: 'address'

   7:         }

   8:     };

   9:  

  10: var companyAddress = myObject.company.location;

  11: var company = myObject.company;

  12: companyAddress = company.location;

Espero que estas notas sobre optimización de JavaScript os sean útiles.

Luis Guerrero.