No. 207

Titolo originale: Let Links Be Links

Pubblicato in: Application Development, Browser, CSS, HTML, JavaScript

Scritto da Ross Penman

Il concetto del web come piattaforma per applicazioni non è mai stato più popolare, ma gli strumenti usati per creare queste cosiddette “web app” sono ancora pieni di insidie che spesso vengono ignorate o mal interpretate. I framework per web app single page hanno guadagnato trazione perché possono essere usati in maniera semplice per creare applicazioni veloci e complesse che sembrano più solide ed interattive dei siti web tradizionali. Tuttavia, questo vantaggio e i cambiamenti nell'impostazione mentale e nelle pratiche di sviluppo che lo accompagnano, hanno un costo in termini di funzionalità base del browser che a volte i web developer danno per scontato.

JavaScript può essere fragile

Con i produttori di browser che rendono sempre più difficile disabilitarlo, possiamo essere indotti a pensare di non aver bisogno di un fallback per gli utenti i cui browser non eseguono JavaScript. Ma scegliere esplicitamente di disabilitare JavaScript non è per nulla l'unica ragione per cui un browser di un utente può non farlo girare. Government Digital Service (GDS), il team che mantiene il sito web del governo del Regno Unito, ha scoperto che, per ogni 500 visitatori di GOV.UK, a cinque non arriva JavaScript, ma solo uno ha JavaScript esplicitamente disabilitato. Gli altri quattro potrebbero essersi persi JavaScript per una qualsiasi tra molteplici ragioni: un server proxy aziendale super zelante, un timeout di una richiesta JavaScript dovuto ad un'alta latenza, o addirittura un errore di sintassi che non è stato notato.

Inoltre, JavaScript, a differenza di CSS e HTML, non può degradare dolcemente (graceful degradation). Questo significa che se gli sviluppatori usano una singola feature di sintassi di ES6 o addirittura fanno una sola chiamata di funzione di una libreria standard senza controllare che quella funzione sia stata prima definita, il loro JavaScript potrebbe o smettere di girare a metà dell'esecuzione o non girare affatto. Quando JavaScript viene usato per migliorare i siti web, non importa così tanto: i visitatori possono ancora seguire i link e inviare form e, generalmente, usare il sito web come era stato pensato. Ma quando JavaScript è un requisito, chiunque usi anche un browser leggermente più vecchio probabilmente visualizzerà una pagina vuota senza alcuna spiegazione su come risolvere il problema.

La struttura semantica è ancora importante

Per come è stato progettato da Tim Berners-Lee nel 1993, HTML definiva una struttura comune per la rete di documenti interconnessi che oggi conosciamo come il web. Questi significati semantici permeati in questa struttura comune forniscono un contesto machine-readable per l'informazione contenuta in una pagina web. In termini pratici, questa informazione extra permette ai browser web di migliorare la user experience. Per esempio, un browser web può implementare un modo per aggiungere eventi definiti con gli elementi time al calendario di un utente, uno screen reader può leggere una lista in maniera diversa da come leggerebbe un paragrafo. La differenza tra una lista e un paragrafo è chiara all'osservatore umano di un documento, la struttura comune messa a disposizione da HTML la rende chiara anche ai computer.

Il significato semantico dietro a HTML distingue il web dagli ambienti per applicazioni native come Cocoa, Windows Presentation Foundation e Qt. L'informazione strutturata è più importante per il web per via dei modi diversi in cui vi si può accedere. Quando crea un'applicazione per iPhone, posso presumere con sicurezza che tutte le persone che utilizzeranno quell'applicazione la useranno in maniera simile. L'informazione presentata dalla mia app sarà sempre presente più o meno nello stesso modo e avrò il controllo completo su quella presentazione. Anche se qualcuno sta usando la mia app per interagire con essa con VoiceOver (la tecnologia assistiva di Apple per le persone con disabilità visiva), interagiranno ancora con l'applicazione in maniera simile ad un utente vedente: toccando lo schermo. L'unica differenza è che ascolteranno il testo invece di vederlo.

Il web non funziona così. I siti web non vengono visitati solo con i browser web. La gente consuma i siti web attraverso app come Pocket o Instapaper, che cercano di usare l'informazione strutturata di una pagina web per estrarne il suo contenuto rilevante. Un browser su uno smartwatch potrebbe ignorare il layout e presentare l'informazione in maniera più adatta a uno schermo da un pollice. Oppure - chi può dirlo - il vostro sito web potrebbe essere usato attraverso un device futuro che trasformerà l'informazione in pensieri inviati direttamente nel cervello dell'utente. Perfino gli screen reader web non funzionano come VoiceOver sull'iPhone, leggendo il testo nell'ordine delineato sotto al dito dell'utente. Gli screen reader web leggono l'intero documento, ignorando il layout e deducono il significato dalle definizioni semantiche standardizzate dei tag HTML. Un semplice esempio di quando semantiche come questa siano importanti è la recente introduzione dell'elemento main, utilizzato per definire la parte principale di un documento. Per un utente vedente che visualizza la pagina con Google Chrome non fa alcuna differenza che voi usiate <main> o <div id=“main”>. Tuttavia, per qualcuno che usa un altro client web, come uno screen reader o Instapaper, il significato implicito dell'elemento main è molto importante per il loro software come aiuto alla navigazione del vostro documento.

Sviluppare un'applicazione per il web, pertanto, non è così semplice come svilupparne una per una piattaforma nativa. Assicurarsi che funzioni come vogliamo nei cinque principali browser e pubblicarla non è sufficientemente buono per il web. Dobbiamo testare il nostro lavoro con gli screen reader. Dobbiamo rivedere il nostro markup per essere sicuri che fornisca quanti più metadati semantici possibile, non solo per i web client di oggi, ma anche per quelli di domani.

Framework per web app single-page

Quando utilizzate dei framework “per web app single-page” come Angular e Ember, il trend è di trattare i siti web come app native, con poco riguardo per le sfumature che rendono il web unico. Gli sviluppatori fanno assunzioni sui propri utenti che possono seriamente danneggiare le esperienze delle persone che non rientrano in quelle assunzioni. Come esempio dei risultati a cui può portare questa forma mentale, considerate il markup di un pulsante per il login (che nel frattempo è cambiato) che ho recentemente trovato sul sito di Patreon:

<span class="patreon-button sub-section navigation-active" data-ng-click="triggerChangeWindow(navigation.login_url)">Log In</span>
Esempio di un pulsante di login che appariva un tempo sul sito Patreon

Il pulsante di login di Patreon, piuttosto standard, agisce proprio come un link. Non c'è bisogno di un JavaScript speciale in questo caso.

Questo link funziona bene per me in Safari, ma in un qualsiasi ambiente diverso da un browser mainstream attuale, questo pulsante è totalmente inutile. Supponiamo di avere un ipotetico browser su uno smartwatch e lo chiamiamo WatchBrowse. Potrebbe ad esempio mostrare un elenco di link in cui l'utente può navigare perché questo particolare smartwatch non ha un cursore che può interagire con la pagina. Poiché HTML definisce un modo standard per creare link su una pagina web (l'elemento a), WatchBrowse potrebbe in teoria elencare semplicemente ogni tag a sulla pagina con il suo attributo href e con il suo contenuto, finché non arriva un sito come Patreo che decide di evitare gli standard web per reimplementare da zero le funzioni base del browser.

Se Patreon avesse usato un tag a invece di uno span, WatchBrowse avrebbe magari trovato il link e l'avrebbe mostrato nell'elenco. Se un utente selezionasse il link, potrebbe simulare un click event invece di usare semplicemente l'attributo href. Ma cosa succede alla funzionalità che richiede al browser di sapere in anticipo dove andrà il link? Un'estensione del browser potrebbe permettervi di cercare i link su una pagina utilizzando i loro valori href, che sarebbe utile, per esempio, nel caso in cui vorreste trovare rapidamente il posto in cui qualcuno link al proprio account Twitter. Firefox mostra dove mi porterà un link quando ci passo sopra. Quando gli attributi href non sono più valori statici ma, al contrario, decisi da del JavaScript arbitrario nei click handler, queste utili feature non sono più possibili.

Il sito di Patreon è creato con Angular e, sebbene in questo caso non sia colpa di Angular di per sé, la mentalità di trattare l'HTML come un view layer, che va a braccetto con l'utilizzo di questi framework, ha probabilmente contribuito alla pessima decisione di Patreon.

E se avessimo creato lo stesso link nel modo in cui gli sviluppatori di framework raccomandano nella loro documentazione? Un modo più standard per rendere un link in Angular potrebbe essere questo:

<a ng-href="/login">Log In</a>

Quando viene resa nel DOM dal JavaScript client-side, questa snippet si trasforma così:

<a ng-href="/login" class="ng-binding" href="/login">Log In</a>

Ember gestisce la cosa in maniera simile. Un link è definito così in un template Emeber:

{{#link-to sessions.new}}Log In{{/link-to}}

E, quando viene reso nel DOM, diventa questo:

<a id="ember-563" class="ember-view" href="/sessions/new">Log In</a>

Poi, Ember e Angular intercettano il click event del link per rendere il nuovo contenuto senza ricaricare la pagina. Tuttavia, in modo determinante, se il click event non fosse mai attivato e il browser caricasse il valore di href, non ci sarebbe alcuna differenza visibile per l'utente al di là di un reload extra della pagina, perché Ember e Angular, di default, non cercano di reinventare la ruota definendo il loro routing in termini di URL.

Nella loro forma attuale, tuttavia, Emeber e Angular richiedono ancora JavaScript per rendere i loro template e creare per prima cosa quei link. Quattro persone su 500 che visitano un sito web costruito con Angular o Ember incontreranno una pagina completamente vuota.

Una soluzione?

Quando il contenuto di una pagina dinamica viene reso da un server, il codice del rendering deve solo essere in grado di girare su quel server. Quando è reso sul client, il codice deve ora lavorare con ogni client che potrebbe eventualmente visitare il sito web. Gli sviluppatori adesso si stanno spostando dai siti web resi via server perché non offrono quella variante di esperienza di rich application che possono fornire i siti resi dai client. Però, io penso che ci sia ancora un ruolo per il server rendering nel nuovo mondo delle applicazioni client-side.

Ad oggi, richiedere JavaScript è un compromesso che devono fare gli sviluppatori che usano framework per web app single-page, ma a me pare che questo sia esattamente il tipo di problema che dovrebbe essere gestito da un framework. Come web developer siamo fortunati perché scriviamo il codice di un'applicazione per il web in uno dei linguaggi di programmazione più universali che siano mai esistiti. Se gli sviluppatori di framework mettessero un po' di impegno (che, devo ammetterlo, sembra enorme) per far sì che le app che girano in Node funzioni esattamente come se girassero nel browser, il rendering della pagina iniziale potrebbe essere gestito dal server, con tutta l'attività seguente gestita dal browser. In maniera cruciale, se un server può mostrare i link con i tag a, come fa attualmente Emeber sul client, sarebbe possibile, per un utente che non riceve (per un qualsiasi motivo) JavaScript, navigare nel sito web. Potrebbe essere possibile avere anche le form funzionanti, facendo girare tutta la logica di validazione e inserimento sul server invece che sul client. Se questo sforzo potesse essere fatto all'inizio da un framework maintainer, allora tutti gli sviluppatori che utilizzano quel framework potrebbero immediatamente trasformare un'app che funzionava solo nell'ultimissimo web browser in un'esperienza "progressively enhanced" compatibile virtualmente con ogni client, passato, presente o futuro.

Il progressive enhancement è da un po' che è importante per i web developer. Riconosce che la parte vitale dell'esperienza web è il contenuto e che qualunque miglioramente in più all'esperienza utente non dovrebbe minare la disponibilità universale del contenuto fornito dal web. Gli approcci attuali alle web app single-page tende ad abbandonare questo principio, ma il progressive enhancement e le web app single-page non sono fondamentalmente incompatibili.

Infatti, si stanno facendo dei progressi in questa arena. Per migliorare la compatibilità di Ember con i motori di ricerca, per esempio, un team in-house sta lavorando all'implementazione del rendering server-side. Ma la soluzione ai problemi causati dalla web app single-page non è puramente tecnico: c'è un problema crescente nel modo in cui le persone pensano al web. È diventato comune trattare il web esattamente come un'altra piattaforma per applicazioni, ma il web è molto più di questo. Il web è la piattaforma per l'informazione universale. Non importa se qualcuno visita un sito web da un iMac da 2000€ o da un tablet Android da 50€ o dal web client da 5€ di un futuro che ancora non possiamo immaginare - in teoria, almeno. In pratica, è importante assicurarsi di non sacrificare le esperienze di un piccolo numero di utenti perché così possiamo leggermente migliorare le esperienze del reso, danneggiando in questo processo la natura universale del web.

Illustrazioni: Carlo Brigatti

Share/Save/Bookmark
 

Discutiamone

Ti sembra interessante? Scrivi tu il primo commento


Cenni sull'autore

Ross Penman

Ross Penman è un web developer e un entusiasta tecnologo Scozzese. Finalista nella categoria Emerging Talent of the Year dei 2014 Net Awards, Ross si contraddistingue per il suo lavoro per promuovere i giovani talenti nel settore tecnologico. Twitta di web development e, talvolta, di addestramento dei Pokémon.

Questo sito per poter funzionare utilizza i cookie. Per saperne di più visita la pagina relativa all' INFORMATIVA