Edit in JSFiddle

(function (d, w, undefined) {
    var ww = new Worker(getInlineJS());
    var tresholdselector = d.querySelector('#treshold');
    var print = Helpers.log2Screen;
    var chunkMssg = d.querySelector("#chunking");
    var chunks = function () {
        var div = d.createElement('div');
        d.body.appendChild(div);
        return div;
    }();
    var chunk = function () {
    	var span = d.createElement('span');
        span.className = "numbers";
        return span;
    }();
    var nchunks;
    
    tresholdselector.addEventListener('change', start);
    start();
    
    ww.onmessage = function (e) {
        // status message during calculation
        if (e.data.status) {
            return print( 'still working ... found <code>' + e.data.found +
                          '</code> prime numbers', 
                          {clear: true, direct: true} );
        }
        
        // chunked writing for large result set
        if (e.data.chunk) {
            var nwChunk = chunk.cloneNode();
            nwChunk.innerHTML = '<br>' + e.data.chunk;
            chunks.appendChild( nwChunk );
            chunkMssg.textContent = e.data.text;
        }
        
        $('#warning').addClass('hidden');
        
        // print result
        print( e.data.msg, ', calculation took ', e.data.duration, 
               ' millisecond', e.data.duration != 1 ? 's': '',
               '<br><b>Prime numbers found</b>:<br>', {clear:true} );
        
        // if n of primes > 10000 write them in chunks of 1000 to screen, 
        // using the webworker. Else just write to screen.
        if( e.data.primes && e.data.primes.length > 10000 ) {
            nchunks = Math.floor(e.data.primes.length/250) + 1;
            ww.postMessage({writechunked: e.data.primes, nchunks: nchunks});
        } else {
            print('<br><div class="numbers">',e.data.primes.join(' '), '</div>');
        }
    };
    
    function start() {
        chunks.innerHTML = "";
        chunkMssg.textContent = "";
        print('start working...', {clear:true, direct: true});
        $('#warning')[+tresholdselector.value > 100000 ? 'removeClass' : 'addClass']('hidden');
        ww.postMessage({value: tresholdselector.value});
    }
    
    function getInlineJS() {
        var ecmaCode = d.querySelector('[data-isworker]').textContent
           ,ecmaBlob = new Blob([ecmaCode], {"type": "application\/javascript"});
        return URL.createObjectURL(ecmaBlob);
    }
}(document, window))
<div class="solink" data-linkid="26312971"></div>

<h3>Using a web worker to calculate prime numbers from 0 to [Threshold]</h3>

<p id="warning" class="hidden">This may take a while (but the browser is not blocked)</p>

<p id="chunking"></p>

Threshold: <select id="treshold">
    <option value="10">10</option>
    <option value="100" selected="selected">100</option>
    <option value="1000">1000</option>
    <option value="10000">10000</option>
    <option value="100000">100000</option>
    <option value="1000000">1000000</option>
    <option value="10000000">10000000</option>
    <option value="100000000">100000000</option>
</select> 



<script type="text/ecmaworker" data-isworker="true">
    String.prototype.padLeft =  String.prototype.padLeft ||
    function padLeft(base, chr) {
      var len = (String(base || 10).length - String(this).length) + 1;
      return len > 0 ? new Array(len).join(chr || '0') + this : this;
    };
    
    Number.prototype.pretty = function (usa, noprecision){
        var somenum = this
           ,dec = (''+somenum).split(/[.,]/)
           ,lendec = dec[1] ? dec[1].length : 0
           ,precision = lendec && !noprecision ? decPrecise(somenum,lendec) : dec[1]
           ,sep = usa ? ',' : '.'
           ,decsep = usa ? '.' : ',';

        // from http://stackoverflow.com/questions/10473994/javascript-adding-decimal-numbers-issue/10474209
        function decPrecise(d,l){
          return String(d.toFixed(12)).split(/[.,]/)[1].substr(0,l);
        }

        function xsep(num,sep) {
          var n = String(num).split('')
             ,i = -3;
          while (n.length + i > 0) {
              n.splice(i, 0, sep);
              i -= 4;
          }
          return n.join('');
        }

        return xsep(dec[0],sep) + (dec[1] ? decsep+precision :'');
      }
    
    onmessage = function (e) {
        if (e.data.writechunked) {
          var arr = e.data.writechunked.slice(0);
          var chunknr = 0;
          do {
            chunknr += 1;
          	postMessage({chunk: arr.splice(0, 250).join(" "), 
                         chunknr: chunknr,
                         text: 'Written chunk # ' + chunknr +' of ' + e.data.nchunks});
          } while (arr.length);
          return;
        }

        var n = 0
           ,total = 0
           ,THRESHOLD = +e.data.value
           ,startTime = new Date
           ,primes = [];
        
        while (++n < THRESHOLD) {
          var isprime = isPrime(n);
          total += isprime ? 1 : 0;
          void( isprime && 
    (primes.push(String(n).padLeft(Math.floor(THRESHOLD/10), '&nbsp;')),
                   primes.length % 100 < 1 &&
                     postMessage({status: true, found: primes.length})) );
        }
        
        postMessage({ msg: 'Found <code>' + total.pretty(1) + 
                       '</code> prime numbers using threshold <code>' + 
                       THRESHOLD.pretty(1) + '</code>',
                  primes: primes,
                  duration: (new Date - startTime).pretty(1)});
        
        function isPrime(number) {
            var start = 2;
            while (start <= Math.sqrt(number)) {
                if (number % start++ < 1) return false;
            }
            return number > 1;
        }
    }
</script>
#warning {
    color: red;
    font-weight: bold;
}

.hidden {
    display: none;
}

.numbers {
    font-family: courier new;
}