Computer Coding
Home |  ColdFusion |  IBM |  Java |  JavaScript |  Spring |  Misc |  Sign in



HTML5Rocks


Offline-first, fast, with the sw-precache module

You can?t read about service workers without getting excited?they?re the behind-the-scenes infrastructure that make it possible for web pages to act more like web applications. Upcoming web platform features like background sync and push notifications will rely on service workers, and following the release of Chrome 40, service worker-based caching is available to use today. If you?ve wanted to add service worker-powered offline support to your sites, but weren?t sure how to get started, the sw-precache module is for you! sw-precache hooks into your existing node-based build process (e.g. Gulp or Grunt) and generates a list of versioned resources, along with the service worker code needed to precache them. Your site can start working offline and load faster even while online, by virtue of caching.

The service worker generated by sw-precache will cache and serve the resources that you configure as part of your build process. For smaller, mostly static sites, you can have it precache every image, HTML, JavaScript, and CSS file that makes up your site. Everything will both work offline, and load fast on subsequent visits without any extra effort. For sites with lots of dynamic content, or many large images that aren?t always needed, precaching a ?skeleton? subset of your site often makes the most sense. You can combine sw-precache with one of the service worker ?recipes? or techniques outlined in the offline cookbook to provide a robust offline experience with sensible fallbacks?e.g. when a large, uncached image is requested offline, serve up a smaller, cached placeholder image instead.

Because sw-precache integrates into your site?s build process, you can use wildcards to precache all of the resources that match a pattern?there?s no list of files or URLs that you have to manually keep up to date. What?s more, the module automatically versions all your cached resources based on a hash of each file?s contents. When a change to any file is detected as part of your build process, the generated service worker knows to expire the old version and fetch the new version of the resource. All of the cache entries that remain the same are left untouched.

Here?s a basic example of using sw-precache as part of a gulp build:

gulp.task('generate-service-worker', function(callback) {
  var fs = require('fs');
  var swPrecache = require('sw-precache');
  var rootDir = 'app';

  swPrecache({
    staticFileGlobs: [rootDir + '/**/*.{js,html,css,png,jpg,gif}'],
    stripPrefix: rootDir
  }, function(error, swFileContents) {
    if (error) {
      return callback(error);
    }
    fs.writeFile(path.join(rootDir, 'service-worker.js'), swFileContents, callback);
  });
});

You?ll see information about which resources will be precached, as well as the total precache size as part of the task output:

Starting 'generate-service-worker'...
Caching static resource 'app/css/main.css' (65 B)
Caching static resource 'app/images/one.png' (593 B)
Caching static resource 'app/images/two.png' (641 B)
Caching static resource 'app/index.html' (2.09 kB)
Caching static resource 'app/js/a.js' (7 B)
Caching static resource 'app/js/b.js' (7 B)
Caching static resource 'app/js/service-worker-registration.js' (3.37 kB)
Total precache size is about 6.77 kB for 7 resources.
Finished 'generate-service-worker' after 14 ms

There?s a lot more information at the GitHub project page, including a demo project with gulpfile.js and Gruntfile.js samples, and a script you can use to register the generated service worker. If you?d like to see it in action, just check out the recently launched Google I/O 2015 web app?thanks (in part) to sw-precache, you can browse it at your leisure, online or off.


Getting Literal With ES6 Template Strings

Strings in JavaScript have been historically limited, lacking the capabilities one might expect coming from languages like Python or Ruby. ES6 Template Strings (available in Chrome 41+), fundamentally change that. They introduce a way to define strings with domain-specific languages (DSLs), bringing better:

  • String interpolation
  • Embedded expressions
  • Multiline strings without hacks
  • String formatting
  • String tagging for safe HTML escaping, localisation and more.

Rather than stuffing yet another feature into Strings as we know them today, Template Strings introduce a completely different way of solving these problems.

Syntax

Template Strings use back-ticks (``) rather than the single or double quotes we?re used to with regular strings. A template string could thus be written as follows:

var greeting = `Yo World!`;

So far, Template Strings haven?t given us anything more than normal strings do. Let?s change that.

String Substitution

One of their first real benefits is string substitution. Substitution allows us to take any valid JavaScript expression (including say, the addition of variables) and inside a Template Literal, the result will be output as part of the same string.

Template Strings can contain placeholders for string substitution using the ${ } syntax, as demonstrated below:

// Simple string substitution
var name = "Brendan";
console.log(`Yo, ${name}!`);

// => "Yo, Brendan!"

As all string substitutions in Template Strings are JavaScript expressions, we can substitute a lot more than variable names. For example, below we can use expression interpolation to embed for some readable inline math:

var a = 10;
var b = 10;
console.log(`JavaScript first appeared ${a+b} years ago. Crazy!`);

//=> JavaScript first appeared 20 years ago. Crazy!

console.log(`The number of JS MVC frameworks is ${2 * (a + b)} and not ${10 * (a + b)}.`);
//=> The number of JS frameworks is 20 and not 2000.

They are also very useful for functions inside expressions:

function fn() { return "I am a result. Rarr"; }
console.log(`foo ${fn()} bar`);
//=> foo I am a result. Rarr bar.

The ${} works fine with any kind of expression, including member expressions and method calls:

var user = {name: 'Caitlin Potter'};
console.log(`Thanks for getting this into V8, ${user.name.toUpperCase()}.`);

// => "Thanks for getting this into V8, CAITLIN POTTER";

// And another example
var thing = 'drugs';
console.log(`Say no to ${thing}. Although if you're talking to ${thing} you may already be on ${thing}.`);

// => Say no to drugs. Although if you're talking to drugs you may already be on drugs.

If you require backticks inside of your string, it can be escaped using the backslash character \ as follows:

var greeting = `\`Yo\` World!`;

Multiline Strings

Multiline strings in JavaScript have required hacky workarounds for some time. Current solutions for them require that strings either exist on a single line or be split into multiline strings using a \ (blackslash) before each newline. For example:

var greeting = "Yo \
World";

Whilst this should work fine in most modern JavaScript engines, the behaviour itself is still a bit of a hack. One can also use string concatenation to fake multiline support, but this equally leaves something to be desired:

var greeting = "Yo " +
"World";

Template Strings significantly simplify multiline strings. Simply include newlines where they are needed and BOOM. Here?s an example:

Any whitespace inside of the backtick syntax will also be considered part of the string.

console.log(`string text line 1
string text line 2`);

Tagged Templates

So far, we?ve looked at using Template Strings for string substitution and for creating multiline strings. Another powerful feature they bring is tagged templates. Tagged Templates transform a Template String by placing a function name before the template string. For example:

fn`Hello ${you}! You're looking ${adjective} today!`

The semantics of a tagged template string are very different from those of a normal one. In essence, they are a special type of function call: the above ?desugars? into

fn(["Hello ", "! You're looking ", " today!"], you, adjective);

Note: Nicholas Zakas goes into more detail on the break-down of these arguments in the Template Strings section of his excellent book, Understanding ES6.

Note how the (n + 1)th argument corresponds to the substitution that takes place between the nth and (n + 1)th entries in the string array. This can be useful for all sorts of things, but one of the most straightforward is automatic escaping of any interpolated variables.

For example, you could write a HTML-escaping function such that..

html`<p title="${title}">Hello ${you}!</p>`

returns a string with the appropriate variables substituted in, but with all HTML-unsafe characters replaced. Let?s do that. Our HTML-escaping function will take two arguments: a username and a comment. Both may contain HTML unsafe characters (namely ?, ?, <, >, and &). For example, if the username is ?Domenic Denicola? and the comment is ?& is a fun tag?, we should output:

<b>Domenic Denicola says:</b> "&amp; is a fun tag"

Our tagged template solution could thus be written as follows:

// HTML Escape helper utility
var util = (function () {
  // Thanks to Andrea Giammarchi
  var
    reEscape = /[&<>'"]/g,
    reUnescape = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g,
    oEscape = {
      '&': '&amp;',
      '<': '&lt;',
      '>': '&gt;',
      "'": '&#39;',
      '"': '&quot;'
    },
    oUnescape = {
      '&amp;': '&',
      '&#38;': '&',
      '&lt;': '<',
      '&#60;': '<',
      '&gt;': '>',
      '&#62;': '>',
      '&apos;': "'",
      '&#39;': "'",
      '&quot;': '"',
      '&#34;': '"'
    },
    fnEscape = function (m) {
      return oEscape[m];
    },
    fnUnescape = function (m) {
      return oUnescape[m];
    },
    replace = String.prototype.replace
  ;
  return (Object.freeze || Object)({
    escape: function escape(s) {
      return replace.call(s, reEscape, fnEscape);
    },
    unescape: function unescape(s) {
      return replace.call(s, reUnescape, fnUnescape);
    }
  });
}());
 
// Tagged template function
function html(pieces) {
    var result = pieces[0];
    var substitutions = [].slice.call(arguments, 1); 
    for (var i = 0; i < substitutions.length; ++i) {
        result += util.escape(substitutions[i]) + pieces[i + 1];
    }
 
    return result;
}
 
var username = "Domenic Denicola";
var tag = "& is a fun tag";
console.log(html`<b>${username} says</b>: "${tag}"`);
//=> <b>Domenic Denicola says</b>: "&amp; is a fun tag"

Other possible uses include auto-escaping, formatting, localisation and in general, more complex substitutions:

// Contextual auto-escaping
qsa`.${className}`;
safehtml`<a href="${url}?q=${query}" onclick="alert('${message}')" style="color: ${color}">${message}</a>`;

// Localization and formatting
l10n`Hello ${name}; you are visitor number ${visitor}:n! You have ${money}:c in your account!`

// Embedded HTML/XML
jsx`<a href="${url}">${text}</a>` // becomes React.DOM.a({ href: url }, text)

// DSLs for code execution
var childProcess = sh`ps ax | grep ${pid}`;

Summary

Template Strings are in Chrome 41 beta+, IE Tech Preview, Firefox 35+ and io.js. Practically speaking if you would like to use them in production today, they?re supported in major ES6 Transpilers, including Traceur and 6to5. Check out our Template Strings sample over on the Chrome samples repo if you?d like to try them out. You may also be interested in ES6 Equivalents in ES5, which demonstrates how to achieve some of the sugaring Template Strings bring using ES5 today.

Template Strings bring many important capabilities to JavaScript. These include better ways to do string & expression interpolation, multiline strings and the ability to create your own DSLs.

One of the most significant features they bring are tagged templates - a critical feature for authoring such DSLs. They receive the parts of a Template String as arguments and you can then decide how to use the strings and substitutions to determine the final output of your string.

Further Reading


What the Virtual Viewport?

In Chrome M40 there is a change to the viewport that is pretty subtle, but should make a big difference to users.

When mobile browsers started out, the lack of a viewport meta tag meant they would make the web page think it had approximately 980px of screen real estate and render at this size. With a viewport meta tag, developers could define the width, most common of which is ?device-width?, which sets the screen size to that of the device. You can learn more on Web Fundamentals.

The way Rick Byers describes the virtual viewport is as follows: the idea of the virtual viewport is to split the notion of ?the viewport? into two, ?the layout viewport? (where fixed position items are attached) and ?the visual viewport? (What the users actually see).

Super Simple Example

The website videojs.com is a good example because it?s appbar is fixed to the top and has links on both the left and right side of the appbar.

The image below shows what you would see if you zoomed in on a site and tried panning left and right.

The top devices are Chrome M39, which doesn?t have a virtual viewport and the bottom 3 are from Chrome M40, which has a virtual viewport.

pixelated rendering

pixelated rendering

In Chrome M39, you will see the appbar after you zoom in, but scrolling to the right doesn?t allow you to view the links on the right side of the bar, you?ll only ever see the logo.

Compare this to Chrome M40 (which has a ?virtual viewport?) and you?ll see that the ?visual viewport? scrolls everything inside the ?layout viewport?, allowing you to view the links on the right.

Internet Explorer already has this behaviour and these changes bring us more closely inline with them.

html { overflow: hidden; }

The only major developer facing change that comes with this is that in M39, you could apply overflow: hidden to the html element and your page would still scroll, in M40, this is no longer supported, the page will simply not scroll.

More Solid Info

You want to learn more huh?

Well then, you can view the slide deck below OR check out Rick?s Google+ Post, which you really should do since he?s much better at this stuff than me ;)


Chrome Dev Summit 2014: Let's build some apps with Polymer!

Let?s build some apps with Polymer!

Over the previous year, the Polymer team has spent a lot of time teaching developers how to create their own elements. This has lead to a rapidly growing ecosystem, buoyed in large part by Polymer?s Core and Paper elements, and the Brick elements created by the team at Mozilla.

As developers become more familiar with creating their own elements and start to think about building applications, it opens up a number of questions:

  • How should you structure the UI of your application?
  • How do you transition through different states?
  • What are some strategies to improve performance?
  • And how should you provide an offline experience?

For Chrome Dev Summit, I tried to answer these questions by building a small contacts application and analyzing the process I went through to build it. Here?s what I came up with:

Structure

Breaking an application into modular pieces that can be combined and reused is a central tenant of Web Components. Polymer?s core-* and paper-* elements make it easy to start with small pieces, like core-toolbar and paper-icon-button?

Polymer helps developers build applications faster

?and through the power of composition, combine them with any number of elements to create an application scaffold.

Polymer makes Web Components sweeter

Once you have a generic scaffold in place, you can apply your own CSS styles to transform it into an experience unique to your brand. The beauty of doing this with components is that it enables you to create very different experiences while leveraging the same app building primitives. With a scaffold in place you can move on to thinking about content.

One element that is especially well suited for dealing with lots of content is the core-list.

Polymer makes Web Components sweeter

The core-list can be connected to a data source (basically an array of objects), and for each item in the array, it will stamp out a template instance. Within the template you can leverage the power of Polymer?s data binding system to quickly wire up your content.

Transitions

With the various sections of your app designed and implemented, the next task is figuring out how to actually navigate between them.

Although still an experimental element, core-animated-pages provides a pluggable animation system that can be used to transition between different states in your application.

Polymer report card needs improvement

But animation is only half of the puzzle, an application needs to combine those animations with a router to properly manage its URLs.

In the world of Web Components routing comes in two flavors: imperative and declarative. Combining core-animated-pages with either approach can be valid depending on your project needs.

An imperative router (such as Flatiron?s Director) can listen for a matching route, and then instruct core-animated-pages to update its selected item.

Polymer report card needs improvement

This can be useful if you need to do some work after a route matches and before the next section has transitioned in.

On the other hand, a declarative router (like app-router) can actually combine routing and core-animated-pages into a single element, so managing the two becomes more streamlined.

Polymer report card needs improvement

If you?d like more fine grained control, you can look at a library like more-routing, which can be combined with core-animated-pages using data binding and possibly give you the best of both worlds.

Performance

As your application is taking shape, you have to keep a watchful eye on performance bottlenecks, especially anything associated with the network since this is often the slowest part of a mobile web application.

An easy performance win comes from conditionally loading the Web Components polyfills.

Polymer report card needs improvement

There?s no reason to incur all that cost if the platform already has full support! In every release of the new webcomponents.js repo, the polyfills have also been broken out into standalone files. This is helpful if you want to conditionally load a subset of the polyfills.

<script>
  if ('import' in document.createElement('link')) {
    // HTML Imports are supported
  } else {
    document.write(
      '<script src=?bower_components/webcomponentsjs/HTMLImports.min.js"><\/script>'
    );
  }
</script>

There are also significant network gains to be had from running all of your HTML Imports through a tool like Vulcanize.

Polymer report card needs improvement

Vulcanize will concatenate your imports into a single bundle, significantly reducing the number of HTTP requests that your app makes.

Offline

But just building a performant app doesn?t solve the dilemma of a user with little or no connectivity. In other words, if your app doesn?t work offline, then it?s not really a mobile app. Today you can use the much maligned application cache to offline your resources, but looking to the future, Service Worker should soon make the offline development experience much nicer.

Jake Archibald has recently published an amazing cookbook of Service Worker patterns but I?ll give you the quick start to get you going:

Installing a Service Worker is quit easy. Create a worker.js file, and register it when your application boots up.

Polymer report card needs improvement

It?s important that you locate your worker.js in the root of your application, this allows it to intercept requests from any path in your app.

In the worker?s install handler, I cache a boatload of resources (including the data that powers the app).

Polymer report card needs improvement

This allows my app to provide at least a fallback experience to the user if they?re accessing it offline.

Onward!

Web Components are a big addition to the web platform, and they?re still in their infancy. As they land in more browsers, it?ll be up to us, the developer community, to figure out the best practices for structuring our applications. The above solutions give us a starting point, but there?s still much more to learn. Onward to building better apps!


image-rendering: pixelated

As web developers we play with images all the time and in most cases browsers are great at scaling images to fit the boundaries of our site designs whilst keeping the images pretty. But what happens when you want to control how the browser scales the images on your page?

Chrome 41 (Beta in January 2015) introduces a new CSS property image-rendering: pixelated (Spec) that gives you a little more control over how the browser renders a scaled up image.

The CSS property image-rendering and the value pixelated are interesting because they turn off the browser?s standard smooth scaling (normally bi-linear interpolation) and replaces it with another scaling algorithm (nearest neighbor in most cases) when resizing the images.

Imagine you had an image that was 22 pixels and you scaled it up to 100100 pixels, the browser would render it in a way that didn?t make it look blocky. Something like:

smooth rendering

There are many cases where you would not want this smoothing behavior and instead use a method that preserves a more accurate representation of the image.

To get this effect, you simply apply image-rendering: pixelated; to your image as follows.

<img
     style="image-rendering: pixelated;"
     width="100" height="100"
     src="data:image/png;base64,iVBORw0KGgoAAAA....Ik2kAAAAASUVORK5CYII=">

pixelated rendering

Try the Demo. As you can see the application of the property has a significant effect on how the image is rendered.

This property can be applied in many places:

  • <img> elements
  • <canvas style="image-rendering: pixelated"> elements
  • Any element with a background-image property

I still don?t get it. Where should I use this?

If you are just showing photos on your site, then you probably don?t want this.

A great use-case is games, you frequently have to scale up the canvas to make it fit the screen size correctly. Prior to this CSS property the browser would interpolate the canvas in such a way that it would look blurry (see below [sic]).

If you are building an airline ticketing tool, or an app that displays QR codes then frequently the user will want it to be full screen so that it is easier to scan, so controlling the image-rendering is critical.

Default Smoothing Preserving pixelation (only visible in Chrome M41+ or Opera 26+)

If you are interested in seeing the implementation, checkout Issue 317991 (it is left open for the implementation of the crisp-edges value. Star the issue to track the implementation).


Introduction to Service Worker: How to use Service Worker

Service Worker will revolutionize the way we build for the web. Learn about what it is, why it is important and how to use it.


The Hobbit Experience 2014: Adding WebRTC gameplay to the Hobbit Experience

Learn how North Kingdom built an immersive multimedia experience optimized for modern mobile browsers using Web RTC


Getting Started with CSS Shapes: Wrapping content around custom paths

Using CSS Shapes we can create experiences that we have never been able to create on the web before.


Built-in Browser Support for Responsive Images

Take advantage of the new element and new features of in your next responsive website.


DevTools Digest - Chrome 35: Updates to the Developer Tools in Chrome 35

Updates to the Chrome Developer Tools: CSS property quick search, memory stats for heap snapshots, CodeMirror upgrade and more.



@2014 CompCoding.com