Con l'uscita della nuova Platform Preview 2 di Internet Explorer 10 (IE10PP2), Microsoft conferma il suo forte interesse verso HTML5 e gli standard del Web.
È possibile scaricare Internet Explorer 10 da HTML.it o dal sito IE Test Drive ed installarla sul PC in parallelo ad Internet Explorer 9 per poter provare le novità della versione 10.
Su IE Test Drive c'è anche una serie di esempi che consentono di provare le feature ed anche alcune applicazioni di benchmark per testare le performance dei browser.
Internet Explorer 10 percorre la stessa strada del suo predecessore, che consiste nell'avere diverse Platform Preview prima della release finale. Le Platform Preview consentono di provare le caratteristiche che Microsoft ha deciso di inserire nella release finale del browser (in questo caso la 10) e di fornire feedback sulla implementazione, quindi quello che è nella PP è sicuramente nella versione finale di IE10.
Chi fosse ansioso di provare anche le feature che non hanno ancora raggiunto un livello di maturità tale da essere inserite in una Platform Preview, può seguire il sito HTML5 Labs dove può trovare le implementazioni prototipali di altri standard ancora in evoluzione, da aggiungere a IE e utilizzare per test.
In questo articolo esamineremo i Web Workers e le File API: le caratteristiche che giocano il ruolo delle protagoniste in questa release di Internet Explorer 10 (IE10PP2).
Per chi non li conoscesse, i Web Workers sono un set di API che ha lo scopo di permettere l'esecuzione di codice Javascript in maniera del tutto asincrona rispetto alla UI.
Le applicazioni Web sono sempre più RIA e parte della logica applicativa risiede sul client, perciò si stanno introducendo alcuni concetti precedentemente sconosciuti agli sviluppatori Web, ma ben noti a chi sviluppa applicazioni desktop, come l'async
.
Uno dei principali problemi di Javascript consiste nel 'freeze' del browser durante l'esecuzione del codice. In molti scenari quest'operazione è impercettibile poiché i browser hanno ottime performance e le comuni operazioni non sono molto onerose. Ciò non significa che non possa presentarsi un'eventualità in cui il codice Javascript richieda del tempo per completare le sue funzioni, bloccando l'esecuzione (il 'freeze').
I Web Workers di HTML5nascono con lo scopo di evitare in questo tipo di problema, consentendo di eseguire codice javascript in un thread separato da quello utilizzato per la UI.
Per comprendere cosa è meglio fare con i Web Workers è necessario conoscerne le limitazioni; per esempio è facilmente intuibile che, trattandosi di un'esecuzione asincrona, non sarà possibile in alcun modo accedere al DOM della pagina, e quindi modificare il markup tramite un Web Worker.
Questo non vuol dire che non è possibile interagire con la pagina tramite Web Worker, ma che è necessario rispettare degli appositi canali di comunicazione (eventi) e lasciare alla pagina il compito di utilizzare le informazioni elaborate in maniera asincrona.
<html>
<head><title>Web Worker esempio 1</title></head>
<body>
<p>Valore passato dal worker: <output id="result"></output></p>
<script>
var worker = new Worker('worker.js');
worker.onmessage = function (event) {
document.getElementById('result').textContent = event.data;
};
</script>
</body>
</html>
// Worker.js
var n = 1;
search: while (true) {
n += 1;
for (var i = 2; i <= Math.sqrt(n); i += 1)
if (n % i == 0)
continue search;
// found a prime!
postMessage(n);
}
Come si vede nel codice sopra, la creazione di un Web Worker è veramente semplice ed il codice in esecuzione dovrà risiedere su un file esterno (worker.js
nel nostro esempio).
Ogni qual volta si voglia comunicare qualcosa dal Web Worker
alla UI, è necessario invocare il metodo postMessage passando così le informazioni necessarie. A seguire verrà automaticamente invocato l'evento onmessage
legato all'oggetto worker
.
Per poter provare la demo precedente è necessario che i file vengano "hostati" da un webserver (come IIS Express, IIS, Cassini, Apache, etc.) e quindi richiamati tramite un'url tipo http://localhost:8080/Example1.htm
, e non tramite un path su disco.
A questo punto il browser dovrà avere un render tipo quello mostrato di seguito:
I Web Worker risultano molto semplici da usare e possono essere sfruttati in tantissimi scenari, come nei Timer (eventi temporizzati), elaborazioni di file, etc.
Le specifiche ufficiali dei Web Workers si possono consultare qui.
Le File API sono un'altra importante feature introdotta con l'HTML5. Queste API sono potentissime e coprono scenari interessanti, precedentemente contemplabili solo con dei workaround a volte molto costosi.
Per prima cosa è importante dire che ora è possibile effettuare una selezione multipla di file per l'input type file
. Precedentemente, per effettuare l'upload di più file in un unico round-trip, era necessario ricorrere a dei plugin esterni come Flash o Silverlight, mentre ora è possibile direttamente tramite i browser che supportano questa feature.
Si sta parlando di un'estensione di qualcosa di preesistente (il classico upload di file), la selezione multipla è disabilitata di default, garantendo così la piena retrocompatibilità con i browser che non hanno ancora implementato questa caratteristica.
Se si desidera abilitare la selezione multipla di file, è necessario aggiungere l'attributo multiple
al classico tag input per l'upload, come mostrato di seguito:
<input id="fileUpload" type="file" multiple >
A questo punto, tenendo premuto il tasto CTRL
in Windows e cliccando su più file, sarà possibile effettuare una selezione multipla per poi accedervi via Javascript:
<!DOCTYPE HTML>
<html>
<head>
<title>File API esempio 1</title>
</head>
<body>
<p>Seleziona un file: <input id="file" type="file" multiple ></p>
<p>
output: <br />
<output id="result"></output>
</p>
<a href="javascript:startRead();">Leggi il file</a> |
<script>
function startRead() {
// obtain input element through DOM
var file = document.getElementById('file');
alert(file.files.length);
}
</script>
</body>
</html>
Supponiamo uno scenario in cui si voglia leggere il contenuto di uno o più file selezionati, e di mostrarne il contenuto a video a mo' di preview. Nelle applicazioni comuni è necessario effettuare un upload del file sul server, leggerne il contenuto ed inviarlo nuovamente al client. Questa procedura apre degli scenari molto costosi (validazione sul file, consumo di banda, file temporanei da cancellare, etc) che possono facilmente essere scavalcati grazie alle nuove File API.
Il codice seguente mostra molto semplicemente la situazione appena descritta:
<!DOCTYPE HTML>
<html>
<head><title>File API esempio 2</title></head>
<body>
<p>Seleziona un file: <input id="file" type="file" multiple ></p>
<p>output: <br /><output id="result"></output></p>
<a href="javascript:startRead();">Leggi il file</a> |
<script>
function startRead() {
// obtain input element through DOM
var file = document.getElementById('file').files[0];
if(file) {
getAsText(file);
}
}
function getAsText(readFile) {
var reader = new FileReader();
// Read file into memory as UTF-16
reader.readAsText(readFile, "UTF-8");
// Handle progress, success, and errors
reader.onprogress = updateProgress;
reader.onload = loaded;
reader.onerror = errorHandler;
}
function updateProgress(evt) {
if (evt.lengthComputable) {
// evt.loaded and evt.total are ProgressEvent properties
var loaded = (evt.loaded / evt.total);
if (loaded < 1) {
// Increase the prog bar length
// style.width = (loaded * 200) + "px";
document.getElementById('result').textContent = "caricato il " + loaded +"%";
}
}
}
function loaded(evt) {
// Obtain the read file data
var fileString = evt.target.result;
document.getElementById('result').textContent = fileString;
}
function errorHandler(evt) {
if(evt.target.error.name == "NOT_READABLE_ERR") {
document.getElementById('result').textContent = "si è verificato un errore nel caricamento";
}
}
</script>
</body>
</html>
Risulta tutto piuttosto semplice: la funzione getAsText
non fa altro che istanziare un fileReader
ed invocare i tre metodi necessari per completare la procedura:
Metodo | Descrizione |
---|---|
updateProgress |
serve per mostrare una barra di caricamento finché non è stato letto l'intero document |
loaded |
è l'ultimo metodo invocato e serve per mostrare in pagina il contenuto del file |
errorHandler |
verrà invocato solo se si verificherà un errore nella procedura di lettura |
La lettura e le operazioni su file a volte possono essere molto onerose, motivo per cui potrebbe essere corretto le feature presentate in questo articolo per avere una UI sempre responsive, anche quando si elaborano file di grandi dimensioni.
Le specifiche ufficiali della File API si possono consultare qui.