mercoledì 29 maggio 2013

Mavenizziamoci

Alla costante ricerca del miglior font per UI, ho creato una collection su Google Fonts di alcuni tra i caratteri sans più "puliti" e leggibili qui disponibili.
Al momento il Maven Pro è, a mio insindacabile giudizio ;-), il migliore della brigata.
Ben spaziato, nitido sul piccolo (paragrafi di testo e widgets come bottoni, menu, liste, ecc...) e piacevole sul grande (titoli, header...).
Conserva abbastanza bene le sue caratteristiche cross-device e cross-browser, anche quando è sottoposto ad antialias.
Vince sul Source Sans Pro citato nel post precedente... Un po' troppo tondeggiante e "dispersivo".
Trovo ottimi anche il Droid Sans e l'Ubuntu.

Per inciso... Ho già "mavenizzato" anche questo blog. ;-)

giovedì 18 aprile 2013

Adobe Goodies


Goodie #1
Source Sans Pro è un font open source ideato da Adobe per la leggibilità delle UI.
Comincia ad essere generosamente adottato sul web ed effettivamente è molto pulito.
Tra l'altro è il font (insieme all'Adobe Source Code Pro) utilizzato nel meraviglioso progetto Brackets (o Edge Code, che dir si voglia ;-))

Su FontSquirrel trovate il kit webfont. 
Ovviamente è disponibile anche su Edge Web Fonts e su Google Fonts.

Goodie #2
TopCoat è l’ennesimo kit di UI per il web (desktop e mobile). Sempre da Adobe.
Molto bello, semplice, efficace.
E’ in uno stadio ancora prematuro per l’adozione (v0.2) ed è poco documentato, ma promette bene.
Ritengo più sicuro, nell’immediato, usare Bootstrap, maturo e stabile, ma non mi dispiacerebbe un tema per Bootstrap su questo stile…

lunedì 25 giugno 2012

Ansia da prestazione

Quando e quanto le prestazioni contano, davvero?
Sul web, intendo.
Quando e quanto la ricerca esasperata e maniacale delle migliori performance ha senso?

Ho fatto alcuni ragionamenti partendo dall'ottimo tool YSlow di Yahoo.
Questo consente di analizzare il sito (o web application) e di assegnare un punteggio basato su un set di 23 regole "d'oro" messe a punto da Yahoo stessa (in realtà molte di queste sono già ben conosciute da chi si occupa di web development).
Il tool è molto pratico e restituisce risultati completi e comprensibili, corredati da hints per l'ottimizzazione e il "risanamento" delle carenze.

YSlow all'opera...

Un altro strumento eccezionale, non solo per l'ottimizzazione, ma anche per il debug è Speed Tracer di Google.
Se avete presente la tab Network dei Developer Tools di Chrome... beh... questo ne è una versione agli steroidi e consente di indagare a bassissimo livello anche sugli eventi DOM (per es. il parsing dell'html, painting del layout o l'applicazione degli stili).

Speed Tracer


Qui le mie osservazioni su alcune delle regole di ottimizzazione delle performance formalizzate da Yahoo e sulla loro applicabilità...

"Minimize HTTP Requests"

Ridurre il numero di chiamate HTTP consente di velocizzare il caricamento delle pagine.
E, perché no, di alleggerire il web server...
Una delle vie più pratiche è quella di accorpare/combinare più .js o più .css in un singolo file.
Un'operazione piuttosto scomoda da effettuare a mano, ma ci vengono in aiuto molti tool, sia online che offline.


Io ho scelto Chirpy: un plugin per Visual Studio che ben si integra nel processo di sviluppo.
L'utilizzo è di una semplicità disarmante.
Inoltre è compatibile con LESS (ne compila al volo i sorgenti) e offre la minificazione (ne parleremo dopo) e la validazione contemporanee alla combinazione.








Applicabilità: sempre


"Use a Content Delivery Network"

CDN o non CDN? Questo è il dilemma...
In linea di massima affidarsi a server di grossi provider, potenti, veloci, stabili e dislocati geograficamente sembra buona cosa.
Anche perché è certamente più probabile che il browser di un nuovo visitatore abbia già in cache le librerie di jQuery (per esempio) fornite da Google o Microsoft, in seguito alle precedenti navigazioni, piuttosto che dal nostro server.

Ecco un'interessante comparativa tra alcune delle più grosse CDN disponibili:


CDN Performance

È altresì vero, però, che le performances delle CDN sono molto variabili, in termini di latenza e velocità pura di download. 
E che per applicazioni custom (RIA?) dedicate a pochi utenti unici, specializzati e frequenti utilizzatori della nostra piattaforma, probabilmente il nostro server sarà abbastanza veloce e scarico da fornire prestazioni dignitose. Senza contare che per gli accessi successivi al primo sarà già tutto in cache.

In questi casi, forse, vale la pena conservare l'autoconsistenza del package di deploy, senza appoggiarsi a server esterni; ciò che consente anche di scongiurare eventuali blocchi di proxy/firewall in reti aziendali particolarmente blindate.


Applicabilità: dipende


"Add an Expires or a Cache-Control Header"

Aggiungere esplicitamente gli http header che segnalano al browser il periodo di validità delle risorse consente di evitare anche la piccola richiesta http che il browser stesso compie per confrontare il file remoto con quello in cache.
Anche questa regola, quindi, pare un ulteriore ottimo consiglio.

Ma nella situazione di cui sopra (RIA custom) potrebbero esserci delle "grane": per esempio potremmo trovarci a dover aggiornare una risorsa (immagine, css, script o perfino pagina intera) per implementare una nuova funzionalità, un ritocco chiesto dal cliente o correggere una bug e a dover aspettare che scada il periodo di validità per essere certi che le modifiche si propaghino su tutti i client (in questo caso infatti il browser non verificherà neppure se esiste una nuova versione remota del file).
O a chiedere a tutti di svuotare la cache manualmente!


Applicabilità: dipende


"Compress Components with gzip"

Non siamo certo in presenza di una novità...
Ricordo, per esempio, che sul vecchio  IIS 5.0 era necessario ricorrere a un filtro ISAPI, poiché il meccanismo di compressione nativo era davvero scomodo e buggoso.

Oggi i web server offrono ottimi motori integrati di compressione gzip (generalmente già attivi per default) e i browser supportano da tempo la negoziazione http di risorse compresse.
Non vedo quindi controindicazioni nell'adozione di questa regola nel 100% dei casi (salvo un minimo carico aggiuntivo del server).

Volendo si potrebbero perfino comprimere staticamente i file prima del deploy, ma credo sia un'alternativa che rende difficile la manutenibilità.

Applicabilità: sempre


"Minify Javascript and CSS"

La minificazione (rimozione di commenti e spazi inutili) delle risorse testuali (scripts e css) permette risparmi di dimensioni davvero impressionanti. Questo, unito alla compressione gzip, permette di ridurre corpose librerie anche del 90%.

C'è un'unica controindicazione nella minificazione: script e css diventano non human-readable...
E quindi le operazioni di sviluppo e debug si complicano.

Fortunatamente Chirpy, di cui ho parlato sopra, automatizza anche questa procedura: in un colpo solo possiamo accorpare e minificare più sorgenti solo in fase di deploy, mantenendo le versioni originali inalterate e... leggibili!

Applicabilità: sempre


"Put Javascript at bottom"

Linkare, com'è d'uopo, gli script nell'header forza il browser a scaricarli in sequenza, disattivando di fatto la parallelizzazione.
In questo senso "appendere" i javascript al fondo del body consente un boost di performance notevole, anche grazie al fatto che nel frattempo il DOM viene renderizzato progressivamente.

Però...
Spesso gli script hanno dipendenze l'uno con l'altro ed è indispensabile che vengano caricati nella sequenza corretta.
Pensiamo solo a tutto ciò che si appoggia su jQuery, per esempio.
Grande attenzione va posta quindi nel compiere consapevolmente questa scelta.

Applicabilità: dipende



In conclusione la mia opinione è che non esista una regola buona per tutte le stagioni: gli analisti di Yahoo basano le loro considerazioni su volumi, target e domini applicativi tipici di web company del calibro di Yahoo stessa.
Considerazioni che potrebbero rivelarsi addirittura controproducenti in altri ambiti.

Un'unica regola, sopra a tutte, è sempre vincente: sviluppare (codice e design) con estrema attenzione alla qualità, all'ottimizzazione dei contenuti e alla percezione reale dell'utente. ;-)


giovedì 24 maggio 2012

Blend Workspaces

Visual Studio consente un export/import dei settings molto completo, Blend no.
Peccato, perché sarebbe molto comodo poter trasferire da una postazione all'altra almeno i Workspaces: ogni developer e/o designer (soprattutto ;-)) ha un proprio modo di organizzare palette e strumenti.
Nel mio caso la configurazione dell'ambiente di lavoro è una vera e propria mania!

E' possibile, però, trasferire manualmente la configurazione dei propri workspaces da filesystem...

Con Windows 7 e Blend 4 il path è questo:
%APPDATA%\Microsoft\Expression\Blend 4\Workspaces


Bisogna poi modificare il file %APPDATA%\Microsoft\Expression\Blend 4\user.config in questo modo:
<ConfigurationObject Name="WorkspaceService">
    <PrimitiveObject Name="ActiveWorkspace">[defaultworkspace]</PrimitiveObject>
    <PrimitiveObject Name="UserWorkspaces">[workspace1]|[workspace2]</PrimitiveObject>
 </ConfigurationObject>

lunedì 14 maggio 2012

Custom bindings rulez (again)

Continua l'implementazione di custom bindings per BS/KO (vd. Tre piccioni con un custom binding). Questa volta mi occorreva simulare il comportamento tipico del checkbox/toggle e di un gruppo di radiobuttons utilizzando però i button di BS.
Qui il binding:
/*****************************
** KnockOut Custom Binding for Bootstrap common property .active
** Author: lightwalker
** Usage:
** a)  VM property is a bool -> data-bind="bsActive: [vmpropertyname]" 
**     for example togglebutton (checkbox behavior)
** b)  two parameters -> data-bind="bsActive: {value: [viewvalue], property: [vmpropertyname]}"
**     for example buttons group (radiobuttons behavior)
** http://twitter.github.com/bootstrap/javascript.html#buttons
*******************************/

        ko.bindingHandlers.bsActive = {
            'init': function (element, valueAccessor, allBindingsAccessor) {
                var updateHandler = function () {
                    var valueToWrite = null;
                    var modelValue = null;
                    if (valueAccessor().value != undefined) {
                        modelValue = valueAccessor().property;
                        valueToWrite = ko.utils.unwrapObservable(valueAccessor().value);
                    }
                    else {
                        modelValue = valueAccessor();
                        valueToWrite = !ko.utils.unwrapObservable(modelValue);
                    }


                    if (ko.isWriteableObservable(modelValue) && modelValue !== valueToWrite) {
                        modelValue(valueToWrite);
                    }
                };
                ko.utils.registerEventHandler(element, "click", updateHandler);
            },
            'update': function (element, valueAccessor) {
                    var valueToCompare = null;
                    var modelValue = null;
                    var toToggle = true;
                    if (valueAccessor().value != undefined) {
                        modelValue = ko.utils.unwrapObservable(valueAccessor().property);
                        valueToCompare = ko.utils.unwrapObservable(valueAccessor().value);
                        toToggle = (modelValue.toString() == valueToCompare.toString());
                    }
                    else {
                        toToggle = ko.utils.unwrapObservable(valueAccessor());
                    }
                    $(element).toggleClass('active', toToggle);
                }
       }
E qui il frammento di view:
<!-- int value binding -->
<div class="btn-group">
  <button class="btn" data-bind="bsActive: {value: 0, property: intVMObservable}">Value 0</button>
  <button class="btn" data-bind="bsActive: {value: 1, property: intVMObservable}">Value 1</button>
  <button class="btn" data-bind="bsActive: {value: 2, property: intVMObservable}">Value 2</button>
</div>
<!-- bool value binding -->
<button class="btn" data-bind="bsActive:boolVMObservable">Yes/No</button>

martedì 8 maggio 2012

Tre piccioni con un Custom Binding

Sulla falsariga dei Custom Bindings di Knockout per jQueryUI trovati qui e qui ne ho implementato uno per il PopOver di Bootstrap.

L'obiettivo principale era, ovviamente, rispettare il pattern MVVM anche nell'uso del framework di Twitter ed evitare che l'iniezione asincrona nel DOM di pezzi di UI rompesse l'applicazione del plugin al $(document).ready().
Mi si è aperta, però, un'altra possibilità...

I Popovers di BS non supportano nativamente l'opzione target, come invece fanno i Modals.
E questo è un peccato: definire direttamente nel markup il contenuto html è, di nuovo, perfettamente compliant al MVVM e offre una flessibilità impagabile.
Ho quindi delegato al binding la valorizzazione del content nei due casi:

  • che sia valorizzata l'opzione content
  • che sia valorizzata l'opzione target (non nativa) con il selettore di un oggetto definito nel DOM

Qui il binding:
/**
KnockOut Custom Binding for Bootstrap Popovers (http://twitter.github.com/bootstrap/javascript.html#popovers)
Author: lightwalker
**/

(function ($) {

    if (ko && ko.bindingHandlers) {

        ko.bindingHandlers.bsPopover = {
            init: function (element, valueAccessor) {
                var val = ko.utils.unwrapObservable(valueAccessor());
                var options = { title: val.title,
                    animation: val.animation,
                    placement: val.placement,
                    trigger: val.trigger,
                    delay: val.delay,
                    //can grab html content from a target option
                    content: ($(val.target).html() != null) ? $(val.target).html() : val.content
                };
                $(element).popover(options);
            }
        };

    };

})(jQuery);
E qui il frammento di view:
<!-- popover activator -->
<a href="#" class="btn btn-danger" rel="popover" data-bind="bsPopover:{title: vmObservable(), target:'#popover-content'}">Hover Me!</a>
<!-- popover html content -->
<div id="popover-content" class="hide"><b>Custom HTML Content</b></div>
E allora... Buon binding a tutti!

Edit: continua con: Custom bindings rulez (again)

Il kit del bravo Web Designer/Developer

L'azienda ha deciso recentemente (con generale e persistente rammarico di tutti) di abbandonare lo sviluppo di RIA su piattaforma ASP .NET e di migrare verso altri misteriosi e minacciosi net-lidi.
Hallelujah. ;-)
Cercando di scrollare di dosso la ruggine ho quindi rastrellato il web alla ricerca del miglior mix di tecnologie correnti per lo sviluppo di front-end web avendo in mente questi obiettivi:

  • parallelizzazione design/development

  • rapidità di implementazione

  • scalabilità

  • riuso

  • flessibilità

  • compatibilità cross-browser


E la mia salute mentale ha vacillato...
Troppi framework, troppi componenti, troppe librerie, TROPPO di tutto!
Ma alla fine (forse) ho trovato un approdo.
Grazie anche al pregevole tentativo di metter ordine da parte di BoilerPlate e Initializr.
Qualche appunto sul percorso fatto...


Pattern


Forti della solida e gratificante esperienza sul paradigma MVVM maturata con WPF/Silverlight, non potevamo rinunciare alle potenzialità di questo modello, soprattutto nella separazione delle professionalità... ma non solo.
E quindi abbiamo optato per l'incredibile framework KnockOut, dribblando il diffusissimo (e pur potente ed efficace) ASP.NET MVC.
Razor resta relegato, eventualmente, al semplice assemblaggio delle pagine nelle composite application e al modello di navigazione.
C'è un contro...

Il pattern MVVM mette in crisi l’applicazione di alcuni comportamenti di UI, soprattutto quando vengono iniettati in modo asincrono frammenti del DOM (per esempio con i template): quando accade cosa?

E quindi? Implementare un’instrumentazione nel “code-behind” delle view?
Funziona, ma non è una soluzione particolarmente performante e snella.
Pare molto più compliant al pattern ed efficace l’uso di custom bindings di KO, come quelli, per esempio, già disponibili in rete per jQueryUI (qui e qui).

Non affronto intenzionalmente il tema dell'accesso al datamodel: non è mia competenza.


UI Components


jQueryUI pare scelta obbligata.
Ma....
Trovo che soffra di una certa legnosità, che conti troppo sulla stesura di codice javascript per l'implementazione e troppo poco sul markup, che sia poco moderno nell'aspetto e ostico da customizzare, che sia ancora molto incompleto nella dotazione di serie.
Ok, ci sono zillioni di plugin, ma il rischio è di perdere in uniformità e di riempire l’applicazione di scripts).
L'alternativa: Twitter Bootstrap.
Pulito, versatile, leggero, veloce, completo, smart.
La maggior parte dei componenti viene istanziata nel markup con la semplice applicazione di classi CSS predefinite


CSS


Trovo molto interessanti Sass e LESS: entrambi estendono il CSS portandolo al livello di un vero e proprio linguaggio di programmazione dinamico e superando le sue rigide limitazioni (per esempio l'impossibilità di utilizzare variabili).
[Ci sono anche Stylus, CSSCrush, CleverCSS, HSS, XCSS e ilMioCSSèpiùBellodelTuo... e via così...]
Questo obbliga a compilare i sorgenti scritti con queste sintassi per ottenere un output compatibile con il vero CSS. E' possibile farlo in fase di deploy o al volo su web server.
Quale dei due preferire (qui, qui e qui a confronto)?
Sono molto simili, ma LESS offre in più:

  • javascript DENTRO il css

  • compilazione on-the-fly sul client via javascript (può essere utile in fase di sviluppo)

  • è usato in Bootstrap


Sass ha dalla sua un compagno usatissimo: Compass, che agevola il mixin soprattutto per quanto riguarda il CSS3.
Però per LESS si trova una tonnellata di mixins già pronti come Less Elements o -lessins-.
Il contro di questi processori è che non si può fare (ancora) editing WYSIWYG dei CSS, ma credo che con un po’ di fatica in più si possa lavorare di cut&paste dall'ottimo Stylizer.
Per concludere, ecco il nostro kit:

Ah, poi si sono SproutCore, Wijmo, Kendo UI, ecc...
Ma bastaaaaa! ;-)