lundi 30 septembre 2013

Optimisation dart2js

L’optimisation qui tire plus vite que son ombre
#dartlang #javascript #dart2js

+Kasper Lund a dévoilé la dernière optimisation du compilateur Dart vers JavaScript, dart2js. Cette optimisation a permit de gagner 13% de performance sur le benchmark Richards, grâce à une astuce découverte par +Nicolas Geoffray, un français de l’équipe Dart :)

Attention, l’explication est compliquée !
L’astuce concerne l’appel d‘une méthode qui a été inlinée dans le code JavaScript généré, sur un objet qui peut être null. Il est nécessaire d’ajouter une vérification pour avoir la bonne exception. Dans l’hypothèse où l’on connaît le type de l’objet o, l’appel Dart suivant :
  o.foo();
donnait en JavaScript :
  o.foo;  // Permet de vérifier la nullité de l’objet.
  <<contenu de la méthode inlinée>>

Ainsi, on obtenait la bonne exception si l’objet o était null donc tout allait bien. Sauf lorsque le tree shaking, qui a pour rôle d'enlever le code non appelé pour alléger le code généré, enlève la vrai méthode o.foo(). Le moteur JavaScript a horreur des propriétés qui n’existent pas sur un objet, ça ralenti l’évaluation de ce code. Du coup, au lieu de vérifier la nullité en vérifiant la méthode foo, on va vérifier sur une méthode qui existe dans tous les objet, à savoir, toString.
  o.toString;  // Permet de vérifier la nullité de l’objet.
  <<contenu de la méthode inlinée>>

mercredi 25 septembre 2013

PostgreSQL en Dart

DB or not DB?
#dartlang #postgresql 

+Thomas Pedersen a tenté d’explorer les possibilités pour communiquer avec une base de données PostgreSQL à partir de Dart. Il fait part de son expérience et a partagé son code.

Il a bien sûr commencé par installer un package indispensable, postgresql :
  dependencies:
    postgresql: 0.2.8

Deuxième étape, il s’est connecté à la base de données, c’est simple et c’est en asynchrone :
  var uri = 'postgres://username:password@localhost:5432/dbname';
  
  connect(uri).then((Connection connection) {
    // Queries...
    connection.close();
  });

Enfin, il a lancé ses requêtes, aussi en asynchrones :
  final String query = "SELECT id, firstname, lastname, height FROM person";
  connection.query(query).listen((row) {
    print("(${row.id}) ${row.firstname} ${row.lastname} - ${row.height}m");
  });

  final String query = “INSERT INTO person (firstname, lastname, dateofbirth, height) VALUES ('$firstname', '$lastname', '$dateOfBirth', $height);";
  connection.execute(query).then((rowsAffected) {
    print("Rows Affected: $rowsAffected");
  });

Il a été surpris par la simplicité d’utilisation de la librairie. Celle-ci profite des possibilités du langage dynamique tel que l’accès direct aux colonnes mais aussi de l’exécution des requêtes en asynchrone grâce à l’utilisation de Future et de Stream. Elle propose d’autres fonctionnalités dont la gestion de paramètres pour les requêtes et la gestion d’un pool de connexion.

jeudi 12 septembre 2013

Dart JSONP


Ou comment contourner CORS
#dartlang #jsonp

Pour faire une requête XmlHttpRequest (HttpRequest en Dart) sur un autre domaine, on est souvent confronté à une restriction de sécurité dénommé CORS, Cross-origin resource sharing. Elle a pour but d’éviter de charger des données d’un serveur autre que celui hébergeant l’application qui n’a pas les bonnes permissions. Cette fonctionnalité est supportée par la majorité des navigateurs modernes, cependant, la plupart des serveurs ne définissent pas les entêtes nécessaires pour le bon fonctionnement de ces requêtes. Du coup, la communauté javascript a inventé un système de contournement : JSONP.

Le principe de JSONP est de charger l’url via une balise script ajouter dynamiquement. Il n’y a plus les mêmes vérifications sur des domaines différents, c’est ouvert.
  <script type="application/javascript" src="http://server2.example.com/Users/1234"></script>
Mais comment savoir quand la requête est terminé et surtout comment récupérer les données ?
C’est la magie de la méthode sioux, on va indiquer un callback à appeler et le serveur va générer le javascript qui va bien pour appeler cette méthode :
  <script type="application/javascript" src="http://server2.example.com/Users/1234?jsonp=*parseResponse*"></script>
Et le serveur retourne par exemple :
  parseResponse({"Name": "Foo", "Id": 1234, "Rank": 7});
On a donc une faille de sécurité monstrueuse si le serveur qu’on appelle n’est pas sûr : il peut exécuter n’importe quel code javascript !

C’est possible d’utiliser ce principe en Dart, grâce au package _jsonp_ et à la librairie sous-jacente, js-interop. 

L’utilisation est assez simple :
  Future<js.Proxy> result = jsonp.fetch(uri: "http://example.com/rest/object/1?callback=?");

  result.then((js.Proxy proxy) {
    print(proxy.data);

    // It is important to release the data!
    js.release(proxy);
  });

Cette technique d’ajout d’une balise script ne fonctionne pas en pure Dart. Par contre, après quelques essais j’ai réussi a chargé du code Dart sur un autre domaine grâce à la méthode spawnUri. Les serveurs n’ont plus qu’à s’adapter pour générer du Dart !

lundi 9 septembre 2013

Polymer Toolkit


Tout le nécessaire pour débuter avec Polymer.dart
#dartlang #polymer

Lors de mes essais avec Polymer.dart, je me suis heurté à quelques problèmes, d’une part à cause d’une documentation obsolète liée à WebUI, le précurseur de Polymer, mais également du fait que Polymer est encore en phase de développement et que certaines fonctionnalités manquent encore à l’appel ou sont bugguées.

L’équipe Dart a publié très récemment une page dédié à Polymer.dart. C’est un bon début pour commencer avec quelques exemples de custom element, de binding et de templates. Cette page donne également les liens vers les sources et le support.

Pour compléter cette page, rien de mieux que des exemples. +Seth Ladd en a crée de nombreux :
Les tutoriaux “A Game of Darts” et leurs exemples sont progressivement mis à jour vers Polymer. C’est un bon moyen de comparer WebUi et Polymer.

Et enfin pour ceux qui ont déjà fait du WebUI et qui veulent migrer vers Polymer, voici deux ressources :

mercredi 4 septembre 2013

Pub + Barback, le duo gagnant

À boire et à manger !
#dartlang #pub

En juin, Bob Nystrom de l'équipe Dart annoncait Bartender, un fournisseur de ressources embarquées dans des packages Dart tel que des images, des css, … Il n’était qu’au stade de la spécification mais il a eu le temps de changer de nom, désormais Barback, mais aussi d’être implémenter au cours de l’été. Nous n’allons pas revenir sur ses fonctionnalités, tel que la génération de ressource, ou bien la transformation d’une ressource d’un type vers un autre, mais plutôt vous annoncer que cette librairie est embarquée dans pub ! What else ?
Et bien, ce ne serait intéressant de publier des ressources que si on a un serveur sur lesquelles les publier. C’est désormais possible grâce à la commande pub serve !
A la racine de votre projet, lancez la commande pub serve et vous voilà avec votre appli sur localhost:8080. Voici comment s'architecture le serveur :
  localhost/<...>/packages/<pkg>/<path> → <pkg>/lib/<path>
  localhost/<...>/assets/<pkg>/<path> → <pkg>/asset/<path>
  localhost/<anything else> → <your pkg>/web/<anything else>

On retrouve donc le fichier _dart.js_ à cette adresse :
  http://localhost:8080/packages/browser/dart.js
Mais aussi :
  http://localhost:8080/par-là/packages/browser/dart.js

Grâce à ça, on peut pointer vers des ressources directement avec les imports “package:...” et il n’y a plus besoins des liens symboliques vers les répertoires des packages !

La fonctionnalité de transformation n’est pas encore disponible, mais le sera dans les prochaines versions. Peut-être que ce serveur embarqué sera aussi capable de compiler le JavaScript à la volé ?

Sources: