{"id":567,"date":"2015-09-25T09:43:03","date_gmt":"2015-09-25T07:43:03","guid":{"rendered":"https:\/\/alistapart.com\/it\/article\/che-i-link-siano-link\/"},"modified":"2015-09-25T09:43:03","modified_gmt":"2015-09-25T07:43:03","slug":"che-i-link-siano-link","status":"publish","type":"article","link":"https:\/\/alistapart.com\/it\/article\/che-i-link-siano-link\/","title":{"rendered":"Che i link siano link!"},"content":{"rendered":"<p><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2015\/09\/n117link.jpg\" border=\"0\" width=\"300px\" style=\"float: left;\" \/>Il concetto del web come piattaforma per applicazioni non \u00e8 mai stato pi\u00f9 popolare, ma gli strumenti usati per creare queste cosiddette \u201cweb app\u201d sono ancora pieni di insidie che spesso vengono ignorate o mal interpretate. I framework per web app single page hanno guadagnato trazione perch\u00e9 possono essere usati in maniera semplice per creare applicazioni veloci e complesse che sembrano pi\u00f9 solide ed interattive dei siti web tradizionali. Tuttavia, questo vantaggio e i cambiamenti nell&#8217;impostazione mentale e nelle pratiche di sviluppo che lo accompagnano, hanno un costo in termini di funzionalit\u00e0 base del browser che a volte i web developer danno per scontato.<\/p>\n<div class=\"paragrafo\">\n<h2>JavaScript pu\u00f2 essere fragile<\/h2>\n<p>Con i produttori di browser che rendono sempre pi\u00f9 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 \u00e8 per nulla l&#8217;unica ragione per cui un browser di un utente pu\u00f2 non farlo girare. Government Digital Service (<abbr title=\"Government Digital Service\">GDS<\/abbr>), il team che mantiene il sito web del governo del Regno Unito, <a href=\"https:\/\/gds.blog.gov.uk\/2013\/10\/21\/how-many-people-are-missing-out-on-javascript-enhancement\/\" title=\"How many people are missing out on JavaScript enhancement?\">ha scoperto<\/a> 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&#8217;alta latenza, o addirittura un errore di sintassi che non \u00e8 stato notato.<\/p>\n<p>Inoltre, JavaScript, a differenza di CSS e HTML, non pu\u00f2 degradare dolcemente (graceful degradation). Questo significa che se gli sviluppatori usano una singola feature di sintassi di <abbr title=\"ECMAScript 6\">ES6<\/abbr> 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\u00e0 dell&#8217;esecuzione o non girare affatto. Quando JavaScript viene usato per <em>migliorare<\/em> i siti web, non importa cos\u00ec tanto: i visitatori possono ancora seguire i link e inviare form e, generalmente, usare il sito web come era stato pensato. Ma quando JavaScript \u00e8 un <em>requisito<\/em>, chiunque usi anche un browser leggermente pi\u00f9 vecchio probabilmente visualizzer\u00e0 una pagina vuota senza alcuna spiegazione su come risolvere il problema.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>La struttura semantica \u00e8 ancora importante<\/h2>\n<p>Per come \u00e8 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&#8217;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\u00f2 implementare un modo per aggiungere eventi definiti con gli elementi <code>time<\/code> al calendario di un utente, uno screen reader pu\u00f2 leggere una lista in maniera diversa da come leggerebbe un paragrafo. La differenza tra una lista e un paragrafo \u00e8 chiara all&#8217;osservatore umano di un documento, la struttura comune messa a disposizione da HTML la rende chiara anche ai computer.<\/p>\n<p>Il significato semantico dietro a HTML distingue il web dagli ambienti per applicazioni native come Cocoa, Windows Presentation Foundation e Qt. L&#8217;informazione strutturata \u00e8 pi\u00f9 importante per il web per via dei modi diversi in cui vi si pu\u00f2 accedere. Quando crea un&#8217;applicazione per iPhone, posso presumere con sicurezza che tutte le persone che utilizzeranno quell&#8217;applicazione la useranno in maniera simile. L&#8217;informazione presentata dalla mia app sar\u00e0 sempre presente pi\u00f9 o meno nello stesso modo e avr\u00f2 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\u00e0 visiva), interagiranno ancora con l&#8217;applicazione in maniera simile ad un utente vedente: toccando lo schermo. L&#8217;unica differenza \u00e8 che ascolteranno il testo invece di vederlo.<\/p>\n<p>Il web non funziona cos\u00ec. 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&#8217;informazione strutturata di una pagina web per estrarne il suo contenuto rilevante. Un browser su uno smartwatch potrebbe ignorare il layout e presentare l&#8217;informazione in maniera pi\u00f9 adatta a uno schermo da un pollice. Oppure &#8211; chi pu\u00f2 dirlo &#8211; il vostro sito web potrebbe essere usato attraverso un device futuro che trasformer\u00e0 l&#8217;informazione in pensieri inviati direttamente nel cervello dell&#8217;utente. Perfino gli screen reader web non funzionano come VoiceOver sull&#8217;iPhone, leggendo il testo nell&#8217;ordine delineato sotto al dito dell&#8217;utente. Gli screen reader web leggono l&#8217;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 \u00e8 la recente introduzione dell&#8217;elemento <code>main<\/code>, 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 <code>&lt;main&gt;<\/code> o <code>&lt;div id=\u201cmain\u201d&gt;<\/code>. Tuttavia, per qualcuno che usa un altro client web, come uno screen reader o Instapaper, il significato implicito dell&#8217;elemento <code>main<\/code> \u00e8 molto importante per il loro software come aiuto alla navigazione del vostro documento.<\/p>\n<p>Sviluppare un&#8217;applicazione per il web, pertanto, non \u00e8 cos\u00ec semplice come svilupparne una per una piattaforma nativa. Assicurarsi che funzioni come vogliamo nei cinque principali browser e pubblicarla non \u00e8 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\u00f9 metadati semantici possibile, non solo per i web client di oggi, ma anche per quelli di domani.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Framework per web app single-page<\/h2>\n<p>Quando utilizzate dei framework \u201cper web app single-page\u201d come Angular e Ember, il trend \u00e8 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\u00f2 portare questa forma mentale, considerate il markup di un pulsante per il login (<a href=\"http:\/\/web.archive.org\/web\/20150202162736\/https:\/\/www.patreon.com\/\">che nel frattempo \u00e8 cambiato<\/a>) che ho recentemente trovato sul sito di <a href=\"https:\/\/patreon.com\/\">Patreon<\/a>:<\/p>\n<pre id=\"snippet1\"><code><span class=\"tag\"><span class=\"tag\"><span class=\"punctuation\">&lt;<\/span>span<\/span> <span class=\"attr-name\">class<\/span><span class=\"attr-value\"><span class=\"punctuation\">=<\/span><span class=\"punctuation\">\"<\/span>patreon-button sub-section navigation-active<span class=\"punctuation\">\"<\/span><\/span> <span class=\"attr-name\">data-ng-click<\/span><span class=\"attr-value\"><span class=\"punctuation\">=<\/span><span class=\"punctuation\">\"<\/span>triggerChangeWindow(navigation.login_url)<span class=\"punctuation\">\"<\/span><\/span><span class=\"punctuation\">&gt;<\/span><\/span>Log In<span class=\"tag\"><span class=\"tag\"><span class=\"punctuation\">&lt;\/<\/span>span<\/span><span class=\"punctuation\">&gt;<\/span><\/span><\/code><\/pre>\n<div class=\"illustration full\"><img decoding=\"async\" src=\"http:\/\/alistapart.com\/it\/wp-content\/uploads\/sites\/2\/2015\/09\/penman_patreon_login.png\" border=\"0\" alt=\"Esempio di un pulsante di login che appariva un tempo sul sito Patreon\" \/><\/p>\n<p>Il pulsante di login di Patreon, piuttosto standard, agisce proprio come un link. Non c&#8217;\u00e8 bisogno di un JavaScript speciale in questo caso.<\/p>\n<\/div>\n<p>Questo link funziona bene per me in Safari, ma in un qualsiasi ambiente diverso da un browser mainstream attuale, questo pulsante \u00e8 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&#8217;utente pu\u00f2 navigare perch\u00e9 questo particolare smartwatch non ha un cursore che pu\u00f2 interagire con la pagina. Poich\u00e9 HTML definisce un modo standard per creare link su una pagina web (l&#8217;elemento <code>a<\/code>), WatchBrowse potrebbe in teoria elencare semplicemente ogni tag <code>a<\/code> sulla pagina con il suo attributo <code>href<\/code> e con il suo contenuto, finch\u00e9 non arriva un sito come Patreo che decide di evitare gli standard web per reimplementare da zero le funzioni base del browser.<\/p>\n<p>Se Patreon avesse usato un tag <code>a<\/code> invece di uno <code>span<\/code>, WatchBrowse avrebbe magari trovato il link e l&#8217;avrebbe mostrato nell&#8217;elenco. Se un utente selezionasse il link, potrebbe simulare un click event invece di usare semplicemente l&#8217;attributo <code>href<\/code>. Ma cosa succede alla funzionalit\u00e0 che richiede al browser di sapere in anticipo dove andr\u00e0 il link? Un&#8217;estensione del browser potrebbe permettervi di cercare i link su una pagina utilizzando i loro valori <code>href<\/code>, 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\u00e0 un link quando ci passo sopra. Quando gli attributi <code>href<\/code> non sono pi\u00f9 valori statici ma, al contrario, decisi da del JavaScript arbitrario nei click handler, queste utili feature non sono pi\u00f9 possibili.<\/p>\n<p>Il sito di Patreon \u00e8 creato con <a href=\"https:\/\/www.angularjs.org\/\">Angular<\/a> e, sebbene in questo caso non sia colpa di Angular di per s\u00e9, la mentalit\u00e0 di trattare l&#8217;HTML come un view layer, che va a braccetto con l&#8217;utilizzo di questi framework, ha probabilmente contribuito alla pessima decisione di Patreon.<\/p>\n<p>E se avessimo creato lo stesso link nel modo in cui gli sviluppatori di framework raccomandano nella loro documentazione? Un modo pi\u00f9 standard per rendere un link in Angular potrebbe essere questo:<\/p>\n<pre id=\"snippet2\" class=\"  language-markup\"><code class=\"  language-markup\"><span class=\"tag\"><span class=\"tag\"><span class=\"punctuation\">&lt;<\/span>a<\/span> <span class=\"attr-name\">ng-href<\/span><span class=\"attr-value\"><span class=\"punctuation\">=<\/span><span class=\"punctuation\">\"<\/span>\/login<span class=\"punctuation\">\"<\/span><\/span><span class=\"punctuation\">&gt;<\/span><\/span>Log In<span class=\"tag\"><span class=\"tag\"><span class=\"punctuation\">&lt;\/<\/span>a<\/span><span class=\"punctuation\">&gt;<\/span><\/span><\/code><\/pre>\n<p>Quando viene resa nel DOM dal JavaScript client-side, questa snippet si trasforma cos\u00ec:<\/p>\n<pre id=\"snippet3\" class=\"  language-javascript\"><code class=\"  language-javascript\"><span class=\"operator\">&lt;<\/span><span class=\"number\">a<\/span> ng<span class=\"operator\">-<\/span>href<span class=\"operator\">=<\/span><span class=\"string\">\"\/login\"<\/span> class<span class=\"operator\">=<\/span><span class=\"string\">\"ng-binding\"<\/span> href<span class=\"operator\">=<\/span><span class=\"string\">\"\/login\"<\/span><span class=\"operator\">&gt;<\/span>Log In<span class=\"operator\">&lt;<\/span><span class=\"operator\">\/<\/span><span class=\"number\">a<\/span><span class=\"operator\">&gt;<\/span><\/code><\/pre>\n<p><a href=\"http:\/\/emberjs.com\/\">Ember<\/a> gestisce la cosa in maniera simile. Un link \u00e8 definito cos\u00ec in un template Emeber:<\/p>\n<pre id=\"snippet4\" class=\"  language-javascript\"><code class=\"  language-javascript\"><span class=\"punctuation\">{<\/span><span class=\"punctuation\">{<\/span>#link<span class=\"operator\">-<\/span>to sessions<span class=\"punctuation\">.<\/span><span class=\"keyword\">new<\/span><span class=\"punctuation\">}<\/span><span class=\"punctuation\">}<\/span>Log In<span class=\"punctuation\">{<\/span><span class=\"punctuation\">{<\/span><span class=\"operator\">\/<\/span>link<span class=\"operator\">-<\/span>to<span class=\"punctuation\">}<\/span><span class=\"punctuation\">}<\/span><\/code><\/pre>\n<p>E, quando viene reso nel DOM, diventa questo:<\/p>\n<pre id=\"snippet5\" class=\"  language-markup\"><code class=\"  language-markup\"><span class=\"tag\"><span class=\"tag\"><span class=\"punctuation\">&lt;<\/span>a<\/span> <span class=\"attr-name\">id<\/span><span class=\"attr-value\"><span class=\"punctuation\">=<\/span><span class=\"punctuation\">\"<\/span>ember-563<span class=\"punctuation\">\"<\/span><\/span> <span class=\"attr-name\">class<\/span><span class=\"attr-value\"><span class=\"punctuation\">=<\/span><span class=\"punctuation\">\"<\/span>ember-view<span class=\"punctuation\">\"<\/span><\/span> <span class=\"attr-name\">href<\/span><span class=\"attr-value\"><span class=\"punctuation\">=<\/span><span class=\"punctuation\">\"<\/span>\/sessions\/new<span class=\"punctuation\">\"<\/span><\/span><span class=\"punctuation\">&gt;<\/span><\/span>Log In<span class=\"tag\"><span class=\"tag\"><span class=\"punctuation\">&lt;\/<\/span>a<\/span><span class=\"punctuation\">&gt;<\/span><\/span><\/code><\/pre>\n<p>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 <code>href<\/code>, non ci sarebbe alcuna differenza visibile per l&#8217;utente al di l\u00e0 di un reload extra della pagina, perch\u00e9 Ember e Angular, di default, non cercano di reinventare la ruota definendo il loro routing in termini di URL.<\/p>\n<p>Nella loro forma attuale, tuttavia, Emeber e Angular richiedono ancora JavaScript per rendere i loro template e creare <em>per prima cosa<\/em> quei link. Quattro persone su 500 che visitano un sito web costruito con Angular o Ember incontreranno una pagina completamente vuota.<\/p>\n<\/div>\n<div class=\"paragrafo\">\n<h2>Una soluzione?<\/h2>\n<p>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 \u00e8 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\u00e9 non offrono quella variante di esperienza di rich application che possono fornire i siti resi dai client. Per\u00f2, io penso che ci sia ancora un ruolo per il server rendering nel nuovo mondo delle applicazioni client-side.<\/p>\n<p>Ad oggi, richiedere JavaScript \u00e8 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\u00e9 scriviamo il codice di un&#8217;applicazione per il web in uno dei linguaggi di programmazione pi\u00f9 universali che siano mai esistiti. Se gli sviluppatori di framework mettessero un po&#8217; di impegno (che, devo ammetterlo, sembra enorme) per far s\u00ec 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&#8217;attivit\u00e0 seguente gestita dal browser. In maniera cruciale, se un server pu\u00f2 mostrare i link con i tag <code>a<\/code>, 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&#8217;inizio da un framework maintainer, allora tutti gli sviluppatori che utilizzano quel framework potrebbero immediatamente trasformare un&#8217;app che funzionava solo nell&#8217;ultimissimo web browser in un&#8217;esperienza &#8220;progressively enhanced&#8221; compatibile virtualmente con ogni client, passato, presente o futuro.<\/p>\n<p>Il <a href=\"http:\/\/alistapart.com\/article\/understandingprogressiveenhancement\">progressive enhancement<\/a> \u00e8 da un po&#8217; che \u00e8 importante per i web developer. Riconosce che la parte vitale dell&#8217;esperienza web \u00e8 il <em>contenuto<\/em> e che qualunque miglioramente in pi\u00f9 all&#8217;esperienza utente non dovrebbe minare la disponibilit\u00e0 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.<\/p>\n<p>Infatti, si stanno facendo dei progressi in questa arena. Per migliorare la compatibilit\u00e0 di Ember con i motori di ricerca, per esempio, <a href=\"https:\/\/github.com\/emberjs\/ember.js\/issues\/9938\" title=\"Implement Server-Side Rendering for SEO\">un team in-house sta lavorando all&#8217;implementazione del rendering server-side<\/a>. Ma la soluzione ai problemi causati dalla web app single-page non \u00e8 puramente tecnico: c&#8217;\u00e8 un problema crescente nel modo in cui le persone pensano al web. \u00c8 diventato comune trattare il web esattamente come un&#8217;altra piattaforma per applicazioni, ma il web \u00e8 molto pi\u00f9 di questo. Il web \u00e8 <em>la<\/em> piattaforma per l&#8217;informazione universale. Non importa se qualcuno visita un sito web da un iMac da 2000\u20ac o da un tablet Android da 50\u20ac o dal web client da 5\u20ac di un futuro che ancora non possiamo immaginare &#8211; in teoria, almeno. In pratica, \u00e8 importante assicurarsi di non sacrificare le esperienze di un piccolo numero di utenti perch\u00e9 cos\u00ec possiamo leggermente migliorare le esperienze del reso, danneggiando in questo processo la natura universale del web.<\/p>\n<p>Illustrazioni: {carlok}<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>La nozione del web come piattaforma per applicazioni non \u00e8 mai stata pi\u00f9 popolare. I framework single-page come Ember e Angular rendono semplice creare applicazioni complesse che offrono esperienze pi\u00f9 ricche e pi\u00f9 robuste di quello che possono fare i siti web tradizionali. Ma questo beneficio ha un costo. Ross Penman ci dice cosa possiamo fare per questo problema.<\/p>\n","protected":false},"author":818,"featured_media":7000774,"comment_status":"open","ping_status":"open","template":"","categories":[269,242,4,244,7,247,271,134,86],"tags":[],"coauthors":[456],"class_list":["post-567","article","type-article","status-publish","has-post-thumbnail","hentry","category-application-development","category-browser","category-codice","category-css","category-design","category-html","category-javascript","category-numero-117-22-settembre-2015","category-user-experience"],"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article\/567","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/article"}],"about":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/types\/article"}],"author":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/users\/818"}],"replies":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/comments?post=567"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media\/7000774"}],"wp:attachment":[{"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/media?parent=567"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/categories?post=567"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/tags?post=567"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/alistapart.com\/it\/wp-json\/wp\/v2\/coauthors?post=567"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}