Quantcast
Channel: Updates
Viewing all 599 articles
Browse latest View live

Detecting if a web app is launched from the home screen

$
0
0

During the past year we have focused on enabling users to build app like experiences on the web by making it possible for apps to work offline using Service Worker and to get a presence on the homescreen using the Web App Manifest.

Now apps tend to offer different experiences as sites, and developers might want to offer different experiences depending on whether the site is viewed in the browser or launched as a standalone web app, from the homescreen.

One example could be to show a navigation drawer only when launched as an app (ie. without any browser chrome).

A way to accomplish this has been to encode a custom parameter on the URL defined in start_url in the manifest, which when launched will be accessible to the page via window.location:

{
  "name": "Air Horner",
  "short_name": "Air Horner",
  ...
  "start_url": "/?homescreen=1",
  "display": "standalone",
  "background_color": "#2196F3",
  "theme_color": "#2196F3"
}

While this works, it means that the developer needs to handle everything from directly JavaScript, including modifying CSS, or applying different CSS rules.

The web already has a very nice way of working with conditional CSS, called media queries. Since M46, Chrome in Android supports the display-mode media query feature, which can be used to find out what the current display-mode is being used for displaying the app, ie. is it being displayed by a browser, standalone or fullscreen. display-mode is also supported for standalone Chrome apps, which will mean that (display-mode: standalone) is true.

To apply a different background color for the app above when being launched from the homescreen, all we need to do it use the following conditional CSS:

@media all and (display-mode: standalone) {
  body {
    background-color: yellow;
  }
}

It is also possible to detect is the display-mode is standalone from JavaScript:

if (window.matchMedia('(display-mode: standalone)').matches) {
  console.log("Thank you for installing our app!");
}

Unfortunately, you cannot check whether the display-mode media query feature is available, as (display-mode) returns false in M46. This issue has since been fixed and should ship in M48.

Best practices

As a general note, it is recommended to not use the media query to hide or show so-called manual “install banners”, telling people to add the app to the home screen manually. This is better done by using the rules set out in “Increasing engagement with Web App install banners”.

It is also recommended to not add back-buttons which are visible in the standard Chrome UI. If a back-button is needed, the "display": "browser" mode can be used in the Web App Manifest instead.

FAQ

  • Will this work on Chrome for iOS or on Desktop?
    • This feature works on any platform where web apps can be added to the homescreen, meaning it works for Android as well as for desktop “Add to desktop” apps. It additional works for Chrome Apps distributed through the Chrome store. It currently does not work on iOS.
  • Can’t I use “display”: “minimal-ui” instead of “display”: “browser” if I want a simple back-button?
    • Chrome currently doesn’t support “minimal-ui”, nor is such support planned for the foreseeable future.

Notification requireInteraction — A smoother notification UX on desktop

$
0
0

We’ve learnt a lot since Notifications and Push Messaging landed in the Chrome. One specific piece of feedback about Desktop class devices was that notifications would stay around and visible on the users screen until were actively dismissed by the user.

When the page is open it is possible to create a simple JavaScript timer that will automatically close the notification. But we now live in a world with Service Worker: where web apps can live past the lifetime of a window and the Service Workers are put to sleep as quickly as possible to save resources. This means we need another way to create a good experience for users.

The Nofitification spec has recently been updated to give the developer the ability to indicate that the notfication should not be automaticaly dismissed by the system.

A notification has an associated require interaction preference flag which is initially unset. When set, indicates that on devices with a sufficiently large screen, the notification should remain readily available until the user activates or dismisses the notification.

This might seem odd, but what it implies that unless told otherwise the notification should be removed from view after a short period of time.

Chrome 47 (beta in October 2015) now supports the requireInteraction option and unless explicitly provided and set to true, this will mean that all notifications on desktop will be dismissed after approximately 20 seconds. The interesting part though is that Chrome has recently just removed the Notification Center from all desktop platforms (but Chrome OS), this means that minimized notifications are considered to be dismissed and are not accessible in a call to getNotifications in a Service Worker.

On Chrome for Android, because the notifications are minimized in the notifications tray area, the requireInteraction option is ignored.

navigator.serviceWorker.register('sw.js');

function showNotifications() {
  Notification.requestPermission(function(result) {
    if (result === 'granted') {
      navigator.serviceWorker.ready.then(function(registration) {
        registration.showNotification('requireInteraction: true', {
          body: 'Requires interaction',
          icon: '../images/touch/chrome-touch-icon-192x192.png',
          requireInteraction: true,
          tag: 'require-interaction'
        });

        registration.showNotification('requireInteraction: false', {
          body: 'Does not require interaction',
          icon: '../images/touch/chrome-touch-icon-192x192.png',
          requireInteraction: false,
          tag: 'no-require-interaction'
        });
      });
    }
  });
}

Try the demo.

Manage the triggering of Touch to Search

$
0
0

Touch to Search launched in June of 2015 on Chrome 43 for most Android phones. When the user taps text on any page in Chrome, the word is selected along with relevant surrounding text. The search term appears in a bar at the bottom of the screen, which users can open in an overlay panel to show full search results.

Tap triggering is enabled for any plain text that is selectable and non interactive or not focusable. When the page has a click handler that responds to a tap on text, Touch to Search automatically detects the response and ignores it since we know the developer intended to handle the event. Using a touch-and-hold gesture to manually select text also triggers the Touch to Search bar. Users can enable or disable the feature using a preference under Chrome’s Privacy settings.

As the author of a site there are often times when you don’t want a tap gesture on certain element to trigger a search. To ensure that Chrome does what you intend, make those elements:

  1. Focusable: add a tabindex=-1 property on the element.
  2. Interactive: Use any of several standard ways to indicate that an element is interactive:
    • Use accessibility markup to indicate the element has a widget role, or widget attributes. For example, any element with role=button won’t trigger. Adding accessibility markup has the added benefit that your page will be more readable by visually impaired users.
    • Any JavaScript click handler that calls preventDefault(), or manipulates the DOM or CSS will not trigger Touch-to-Search.
  3. Non-selectable: using -webkit-user-select: none; Non-selectable text will not trigger Touch-to-Search even when using the touch-and-hold gesture.

If Touch to Search does not trigger when or where it should trigger, or triggers intermittently, then elements are probably marked focusable or interactive when they should not be. Use the following procedure to help determine what’s preventing Touch to Search from triggering:

  1. Check if the text is selectable using the touch-and-hold gesture. If the text selects, but the Touch-to-Search bar does not appear, check that the feature has not been disabled on your phone in the Touch to Search setting under Privacy in Chrome. Also note that some low-end devices do not support Touch-to-Search.
  2. If the Touch-to-Search bar shows when text is selected, but not when you tap, then there is some tap triggering issue. If the triggering is intermittent, then the problem is likely due to animation being conditionally activated by a JavaScript handler for the element.
  3. If the triggering never happens, consult the trigger reasons listed above (check if the element is focusable or interactive).

If your page still doesn’t behave the way you’d like, file a bug at crbug.com and add the label Cr-UI-Browser-Mobile-TouchToSearch.

Improved DOM breadcrumbs

$
0
0

An improved breadcrumb trail for the DOM

Did you know the Elements Panel has a Breadcrumb trail? It can help you trace your steps when you navigate the DOM.

In Canary, you can enable the Material Design experiment. A few nice things:

  • The breadcrumb trail looks better from a visual point of view.
  • The trail has improved visibility with it being nearer to the top, rather than at the bottom where it is easy to forget about.
  • Overall, the DevTools UI feels more consistent.

Don’t forget, you can click each “crumb” within the breadcrumb trail. Doing this highlights the relevant DOM node in the DOM tree view.

Web Animations Resources

$
0
0

The Web Animations API provides powerful primitives to describe imperative animations from JavaScript - but what does that mean? Find out about the resources available to you, including Google’s demos and codelabs.

Background

At its core, the API provides the Element.animate() method. Let’s see an example, which animates the background color from red to green-

var player = document.body.animate(
    [{'background': 'red'}, {'background': 'green'}], 1000);

This method is supported in all modern browsers, with a great polyfill fallback (more on that later). Native support for this method - and its player object - became widely available as part of Chrome 39. It’s also natively available in Opera, and is under active development for Firefox. This is a powerful primitive that deserves a place in your toolbox.

Note! For a primer on the different approaches to animation on the web, including Web Animations, check out Modern Animation Fundamentals on YouTube and Animations on Web Fundamentals.

Codelabs

A growing number of codelabs are available for the Web Animations API. These are self-paced guides that demonstrate different concepts in the API. In most of these codelabs, you’ll take static content and enhance it with animation effects.

These codelabs, and related links or resources, are the absolute best place to start if you’re looking to understand the new primitives available to you in Web Animations. For an idea of what you might build, check out this Android-inspired reveal effect-

Preview of codelab result

So if you’re just getting started, then look no further!

Demos

If you’re looking for inspiration, be sure to check out the Material-inspired Web Animations Demos, with source hosted on GitHub. These demonstrate a variety of amazing effects and you can view each demo’s source code inline.

The demos include a colorful spinning galaxy, rotating Earth, or even just a variety of effects on a plain old element.

Polyfill

To ensure great support across all modern browsers, you can use a polyfill library. The Web Animations API has a polyfill available right now that brings it to all modern browsers, including Internet Explorer, Firefox, and Safari.

If you’re feeling adventurous, you can use the web-animations-next polyfill, which also includes features that are yet to be finalized - such as the composable GroupEffect and SequenceEffect constructors. For a comparison between the two polyfills, please see the homepage.

To use either polyfill in your code, you have a few options.

  1. Use a CDN, such as cdnjs, jsDelivr, or target a specific release via rawgit.com

  2. Install via NPM or Bower

    $ npm install web-animations-js $ bower install web-animations-js

In all cases, you can simply include the polyfill in a script tag before any other code-

<script src="https://cdn.jsdelivr.net/web-animations/latest/web-animations.min.js"></script>
<script>
  document.body.animate([
    {'background': 'red'},
    {'background': 'green'}
  ], 1000);
</script>

Other resources

If you’d like to read a more technical introduction, please check out the W3C spec.

Dan Wilson has also written a great set of posts on Web Animations, including on how to use it alongside the new CSS motion-path property. For some samples using motion-path, check out Eric Willigers’ doc.

DevTools Digest: Efficient element edits, Service Worker debugging, and Material Design shades

$
0
0

Use the DOM panel’s new context menu to efficiently edit nodes. Debug services workers directly via the Resources panel. Choose from all of the Material Design shades in the colorpicker. Blackbox JS libraries more easily.

The DOM panel’s new, improved context menu

The new DOM context menuWe’ve analyzed the most-used actions in the DOM panel and concluded that the right-click context menu should be uncluttered and re-organized.

It’s now much easier to quickly hide or delete an element, trigger a certain state like :active or :hover or edit its HTML. And if you’re on a trackpad and don’t want to bother right-clicking, click on the three little dots next to the selected element instead.

Debug Service Workers via the Resources panel

Service Workers are fantastic once you’ve got them set up but they can be tricky to wrap your head around early on. This was made worse by the fact that debugging them required leaving the DevTools and opening chrome://serviceworker-internals/ in a new browser window.

Service Workers in Resources

Not anymore! Now you can debug Service Workers for the current domain directly from the Resources panel. It’s still a work-in-progress, but already a heavy improvement from the previous status quo.

All the colors: Material Design shades in the colorpicker

A few weeks ago, we added the Material Design palette to the colorpicker to give you primary, bold colors out-of-the-box. To actually design a full page, you inevitably need full access to all of the Material Design shades, so we’ve baked them in.

To bring up the shades, long press on one of the primary colors and click on a shade instead.

Blackbox JavaScript libraries more easily in Settings

JavaScript Blackboxing has been around for a while but wasn’t terribly easy to discover. It’s a feature that allows you to blackbox a script on a page to focus on your authored code only (and hide all the wrapping code).

We’ve now moved it to Settings. Give it a try:

Blackboxing

The Best of the Rest

  • Missing access to Rendering toggles? Rendering Settings have been moved to the DevTools main menu (under “More Tools”). In addition to the usual suspects (i.e. FPS meter), we’ve moved “Emulate print media” there as well.
  • Tired of typing chrome://inspect into the Omnibox? Inspect Devices can now also be found in the new main menu under “More Tools”.
  • Accidentally closed one of these closable Drawer tabs like Rendering or Search? You can now reopen them with the new menu on the left.

As always, let us know what you think via Twitter or the comments below, and submit bugs to crbug.com/new.

Until next month!
Paul Bakaus & the DevTools team

Instant Loading Web Apps With An Application Shell Architecture

$
0
0

Progressive Web Apps (PWAs) describe how a web app can progressively change with use and user consent to give the user a more native-app-like experience with offline support, push notifications and being installable to the home-screen. They can gain substantial performance benefits thanks to intelligent service worker caching of your UI shell for repeat visits.

This allows you to focus on speed, giving your webapps the same instant loading and regular updates you’re used to seeing in native applications. It’s all possible using an Application shell architecture - a companion to this new way of thinking. Any site can take advantage of service workers, but PWAs must have them so it’s a natural fit.

App Shell Separation of HTML, JS and CSS shell and the HTML Content

When we talk about an app’s shell, we mean the minimal HTML, CSS and JavaScript powering the user interface. This should load fast, be cached and once loaded, dynamic content can populate your view. It’s the secret to reliably good performance. Think of your app’s shell like the bundle of code you’d publish to an app store if building a native app - it’s the load needed to get off the ground, but might not be the whole story. Keep your UI local and pull in content dynamically through an API.

Let’s dive into how to structure your app using a service worker augmented application shell architecture. We’ll look at both the client and server-side rendering involved and share an end-to-end sample you can try out today.

Image of Service Worker running in DevTools for the Application Shell

Our application has loaded for the first time and displays an ‘App is ready for offline use’ toast. If an update to the shell becomes available later, we can inform the user to refresh for the new version.

What are Service Workers, again?

A service worker is a script that runs in the background, separate from your web page. It responds to events, including network requests made from pages it serves. A service worker has an intentionally short lifetime. It wakes up when it gets an event and runs only as long as it needs to process it.

Service workers also have a limited set of APIs when compared to JavaScript run from the context of a normal page. This is standard for workers on the web. A Service worker can’t access the DOM but can access things like the Cache Storage API, and they can make network requests using the Fetch API. The IndexedDB API and postMessage() are also available to use for data persistence and messaging between the service worker and pages it controls.

A service worker can intercept network requests made from a page (which triggers a fetch event on the service worker) and returns a response retrieved from the network, or retrieved from a local cache, or even constructed programmatically. Effectively, it’s a programmable proxy in the browser. The neat part is that, regardless of where the response comes from, it looks to the web page as though there were no service worker involvement.

To learn more about service workers in depth, read an Introduction to Service Workers.

Application Shell Architecture

Service workers are powerful for offline caching but they also offer significant performance wins in the form of instant loading for repeat visits to your site or web app. You can cache your application shell so it works offline and populate its content using JavaScript.

On repeat visits, this allows you to get meaningful pixels on the screen without the network, even if your content eventually comes from there. Think of it as displaying regions of the screen where toolbars and cards will eventually be populated very quickly and then loading in the rest of the content progressively.

What is the performance impact of this architecture?

To test this architecture on real devices, we’ve run our application shell sample on WebPageTest.org and shown the results below.

Testing on Cable with a Nexus 5 using Chrome Dev

The first view of the app has to fetch all the resources from the network and doesn’t achieve a meaningful paint until 1.2 seconds in. Thanks to service worker caching, our repeat visit achieves meaningful paint and fully finishes loading in 0.5 seconds.

Web Page Test Paint Diagram for Cable Connection

Testing on 3G with a Nexus 5 using Chrome Dev

We can also test our sample with a slightly slower 3G connection. This time it takes 2.5 seconds on first visit for our first meaningful paint. It takes 7.1 seconds to fully load the page. With service worker caching, our repeat visit achieves meaningful paint and fully finishes loading in 0.8 seconds.

Web Page Test Paint Diagram for 3G Connection

Other views tell a similar story. Compare the 3 seconds it takes to achieve first meaningful paint for our first view of another URL in the application-shell:

Paint timeline for first view from Web Page Test

to the 0.9 seconds it takes when loaded from our service worker cache. Over 2 seconds of time is saved for our end users.

Paint timeline for repeat view from Web Page Test

Similar and reliable performance wins are possible for your own applications using the application shell architecture.

Does service worker require us to rethink how we structure apps?

Service workers imply some subtle changes in application architecture. Rather than squashing all of your application into an HTML string, it can be beneficial to do things XHR-style. This is where you have a shell (always cached and can always boot up without the network) and content which is refreshed regularly and managed separately.

The implications of this split are large. On the first visit you can render content on the server and install the service worker on the client. On subsequent visits you need only request data.

What about Progressive Enhancement?

While service worker isn’t currently supported by all browsers, the application content shell architecture uses progressive enhancement to ensure everyone can access the content. For example, take our sample project.

Below you can see the full version rendered in Chrome, Firefox Nightly and Safari. On the very left you can see the Safari version where the content is rendered on the server without a service worker. On the right we see the Chrome and Firefox Nightly versions powered by service worker.

Image of Application Shell loaded in Safari, Chrome and Firefox

When does it make sense to use this architecture?

The Application Shell architecture makes the most sense for apps and sites that are dynamic. If you’re a very small static site, you probably don’t need an application shell and can simply cache the whole site in a service worker oninstall step. Use the approach that makes the most sense for your project. A number of JavaScript frameworks already encourage splitting your application logic from the content, making this pattern more straight-forward to apply.

Production apps using this pattern already?

The application shell architecture is possible with just a few changes to your overall application’s UI and has worked well for large-scale sites such as Google’s I/O 2015 Progressive Web App and Google’s Inbox.

Image of Google Inbox loading. Illustrates Inbox using service worker.

Offline application shells are a major performance win and are also demonstrated well in Jake Archibald’s offline Wikipedia app and Flipkart Lite’s Progressive webapp.

Screenshots of Jake Archibald's Wikipedia Demo.

Explaining the architecture

During the first load experience, your goal is to get meaningful content to the user’s screen as quickly as possible.

First Load and Loading Other Pages

Diagram of the First Load with the App Shell

In general the application shell architecture will:

  • Prioritize the initial load, but let service worker cache the application shell so repeat visits do not require the shell to be re-fetched from the network.

  • Lazy-load or background load everything else. One good option is to use read-through caching for dynamic content.

  • Use service worker tools (sw-precache) for reliable caching and updating of service worker to automatically manage the caching of static content.

To achieve this:

  • Server will send down HTML content the client can render and will use far-future HTTP cache expiration headers to account for browsers without service worker support. It will serve filenames using hashes to enable ‘versioning’ and easy updates for later in the application lifecycle.

  • Page(s) will include inline CSS styles in a <style> tag within the document <head> to provide a fast first paint of the application shell. Each page will asynchronously load the JavaScript necessary for the current view. As we all know, CSS cannot yet be asynchronously loaded.. Instead, we can request styles using JavaScript as it IS asynchronous rather than parser-driven and synchronous. We can also take advantage of requestAnimationFrame to avoid cases where we might get a fast cache hit and end up with styles accidentally becoming part of the critical rendering path. requestAnimationFrame forces the first frame to be painted and then the styles to get loaded. Another option is to use projects such as Filament Group’s loadCSS to request CSS async using JavaScript.

  • Service worker will store a cached entry of the application shell so that on repeat visits, the shell can be loaded entirely from the service worker cache unless an update is available on the network.

App Shell for Content

A practical implementation

We’ve written a fully working sample using the Application Shell architecture using vanilla ES2015 JavaScript for the client and Express.js for the server. There is course nothing stopping you from using your own stack for either the client or the server portions (e.g PHP, Ruby, Python). We found using JS all the way through relatively painless for this example.

Service Worker Lifecycle

For our application-shell project, we use sw-precache which generates our service worker script and sw-toolbox which handles runtime caching. Together they offer the following service worker lifecycle:

Event Action
Install Cache application shell and other single page app resources
Activate Clear out old caches
Fetch Serve up single page web app for URL's and use cache for assets and predefined partials, use network for other requests..

Server bits

In the architecture, a server side component (in our case, written in Express) should be able to treat the content separate from how it’s presented. Content could be added to a HTML layout that results in a static render of the page, or it could be served up on it’s own to dynamically pulled in.

Understandably, your server-side setup may drastically differ from the one we use for our demo app, but this pattern of web apps is achievable by most server setups, it does require some rearchitecting. We’ve found that the following model works quite well:

Diagram of the App Shell Architecture

  • Routes are defined for three parts of your application: the user facing URL’s (index/wildcard), your HTML partials of just content and the application shell itself.

  • Each route has a controller which pulls in a handlebars layout which in turn can pull in handlebar partials and views. Simply put, partials are views are chunks of HTML that are copied into the final page. Note: JavaScript frameworks that do more advanced data synchronization are often way easier to port to an Application Shell architecture. They tend to use data-binding and sync rather than partials.

  • The user is initially served a static page with content. This page registers a service worker if it’s supported which caches the application shell and everything it depends on (CSS, JS etc).

  • The app-shell will then act as a single page web app, using javascript to XHR in the content for a specific URL. The XHR calls are made to a /partials/ endpoint which returns the small chunk of HTML, CSS and JS needed to display that content. Note: there’s a many variants on how this can be approached and the above XHR one is just one of them. Some applications will inline their data (maybe using JSON) for initial render and therefore aren’t “static” in the flattened HTML sense.

  • Browsers without service worker support should always be served a fall-back experience. In our demo, we fall back to basic static server-side rendering, but this is only one of many options. The service worker aspect provides you with new opportunities for enhancing the performance of your Single-page Application style app using the cached application shell.

File versioning

One question that arises is how exactly should file versioning/updates be handled. This is application specific and the options are:

  • Network first and use the cached version otherwise

  • Network only and fail if offline

  • Cache the old version and update later

For the application shell itself, a cache-first approach should be taken for your service worker setup. If you aren’t caching the application shell, you haven’t properly adopted the architecture.

Note: The application-shell sample does not (at the time of writing) use file versioning for the assets referenced in the static render, often used for cache busting. We hope to add this in the near future. The service worker is otherwise versioned by sw-precache (covered in the ‘Tooling’ section).

Tooling

We maintain a number of different service worker helper libraries that make the process of precaching your application’s shell or handling common caching patterns more straight-forward to setup.

Screenshot of the Service Worker Library Site on Web Fundamentals

Use sw-precache for your application shell

Using sw-precache to cache the application shell should handle the concerns around file revisions, the install/activate questions, and the fetch scenario for the app shell. You can drop sw-precache into your application’s build process and can use configurable wildcards to pick up your static resources. Rather than manually hand-crafting your service worker script, it generates one for you to take care of cache management in a way that is safe and has an efficient, cache-first fetch handler.

Initial visits to your app trigger precaching of the complete set of needed resources. This is very similar to the experience of installing a native app from an app store. When users return to your app, only updated resources are downloaded. In our demo app, we display an “App updated. Refresh for the new version” message to inform users that a new version of the application shell is available. This pattern is a low-friction way of letting users know they can refresh for the latest version.

Use sw-toolbox for runtime caching

Use sw-toolbox for runtime caching with varying strategies depending on the resource:

  • cacheFirst for images, along with a dedicated named cache that has a custom expiration policy of N maxEntries.

  • networkFirst or fastest for API requests, depending on the desired content freshness. Fastest might be fine, but if there’s a specific API feed that’s updated frequently, use networkFirst.

Conclusions

Application shell architectures comes with several benefits but only makes sense for some classes of applications.The model is still young and it will be worth evaluating how much effort and overall performance benefits you might gain from using this architecture.

In our experiments, we took advantage of template sharing between the client and server to minimise the work of building two application layers. This ensures progressive enhancement is still a first-class citizen.

If you’re already considering using service workers in your app, take a look at the architecture and evaluate if it makes sense for your own projects.

With thanks to our reviewers: Jeff Posnick, Paul Lewis, Alex Russell, Seth Thompson, Rob Dodson, Taylor Savage and Joe Medley.

DevTools Digest (CDS Edition): A glimpse into the future + RAIL Profiling

$
0
0

Learn how DevTools is going mobile first with a new, streamlined Device Mode that’s always on. Use the color buttons to quickly add colors to your selectors and find out what’s coming to DevTools soon.

A glimpse into the future of authoring

We’re just coming back from the Chrome Dev Summit where I showed you what working with DevTools looks like today and in the future. I usually don’t mention any features that are still experiments or heavy works of progress in this digest but I’m making an exception this time. If you don’t have time to watch the whole talk, here’s the gist:

Device Mode v2

We’re still heavily working on this new, bold iteration of the Device Mode but wanted to give everyone an opportunity to try it out, so we’ve enabled it in your Canary today. With the changes, we are pushing DevTools into a mobile-first future where mobile development is the default, and Desktop development is the “add-on”. Expect more iteration over the next few weeks with an extended blog post when we’re done.

Powerful Animation Inspection

The work-in-progress Animation Inspection gives you a full, detailed picture over what’s happening on anything moving. Instead of showing you a transition on one element at a time, we added heuristics that group complex animations so you can focus on all you’re seeing. Have a look at the video. We’ll offer a bigger, standalone blog post when we’re fully launched.

Layout Mode (Sneak Peek)

Not quite ready for prime time but very promising is the new Layout Mode, a feature I can’t wait to see fully built out. The Layout Mode adds WYSIWYG editing capabilities to DevTools for any element on the page. So far, the height, width, paddings and margins can be edited in context. It’s going to take a little longer until we’re ready to let you try but we’ll keep you updated.

Performance profiling with the updated Timeline panel

As part of a bigger push of introducing the new RAIL performance model, there have been hundreds of smaller and bigger changes to the Timeline panel, and together they transform and improve the performance profiling story quite a bit. So instead of showing every individual change in isolation, our own Paul Irish showed us how to properly debug the performance of a site, in this case the mobile site of Hotel Tonight, live on stage. Among the newly announced features are the load and performance film strips, the included network waterfall, the treeview summary and the ability to view perf costs by domain & file.

Easily add foreground and background colors to any element

Whenever you wanted to add a background-color or color property to your element, you couldn’t just open the color picker. Instead, most of you type in something like “background: red;” each time so the color picker icon appears, then choose the actual color you wanted.

We thought we could simplify this. We added two nifty buttons that appear when hovering over the bottom right corner of a selector, allowing you to add a color and bring up the picker with a single click:

The Best of the Rest

  • We’ve wasted a lot of previous real estate in the Style panel by showing generic media types. We now hide that stuff before your selectors if it’s not unusual!
  • You can now long hover over a CSS selector in the Style panel to see how many elements on the page it applies to.
  • Didn’t give up on printing yet? Print media emulation is still around to see how your page would look like when printed – we just moved it to the Rendering Settings.
  • When choosing an element to inspect, we now auto-expand and close the relevant DOM sub tree. Hard to explain, seeing is believing.

As always, let us know what you think via Twitter or the comments below, and submit bugs to crbug.com/new.

Until next month!
Paul Bakaus & the DevTools team


Chrome 47 WebRTC: media recording, secure origins & proxy handling

$
0
0

Chrome 47 includes several significant WebRTC enhancements and updates.

Record video from your web apps

The MediaStreamRecorder API has long been the top chromium.org request, with over 2500 stars. Media recording has now been added to Chrome behind the experimental Web Platform features flag — though it’s desktop only for the moment. This allows you to record and play back or download video. There is a simple demo on the WebRTC samples repo and you can find out more from the discuss-webrtc announcement. A sample Chrome App for recording video from screen capture is available at github.com/niklasenbom/RecordingApp. These are brand-new implementations and there may still be bugs to iron out: please file issues on the repos if you encounter problems.

Screenshot of MediaRecorder demo on the WebRTC GitHub samples repo

Audio output device selection

MediaDevices.enumerateDevices() has been released. More details are available from Chromium issue 504280. You can now enumerate audio output devices in addition to the audio input and video input devices that MediaStreamTrack.getSources() already provides. You can find out more about how to use it in this update.

Device support on Windows

Default communications device support on Windows has now been added. This means that when enumerating audio devices on Windows, there will be an additional entry for the communications device whose ID will be ‘communications’.

Device IDs for the default audio device (and communications on Windows) will no longer be hashed (Issue 535980). Instead, two reserved IDs, ‘default’ and ‘communications’ are supported and are the same across all security origins. Device labels will be translated to the browser locale so developers should not expect labels to have a predetermined value. Video rendering accuracy has been improved by propagating the capture timestamp all the way to the rendering algorithm, where the right vsync can be chosen based on that. For Windows platform the capture timestamp is also more accurate in Chrome 47.

Proxy handling

Chrome 47 adds a new preference to force WebRTC traffic to be sent through a local proxy server, if one is configured, which is important for some users browsing via a VPN. This means that the WebRTC application will only see the proxy IP address. Be aware that this will hurt application performance, and won’t work at all unless the application supports TURN/TCP or ICE-TCP. Look for a new version of the WebRTC Network Limiter Extension soon to provide a UI for this preference. There’s more information about IP address ‘leakage’ in What’s Next for WebRTC.

The WebRTC Network Limiter Chrome extension

…and more

Data channel throughput has been greatly improved for high latency connections.

We will gradually roll out support for DTLS 1.2 in the Chrome 47 timeframe.

Though neither VP9 nor H.264 are supported in this release, work on these continues, and we hope to implement support for VP9 and an initial version of H.264 (behind a flag) in Chrome 48.

Public Service Announcements

  • Starting with Chrome 47, getUserMedia() requests are only allowed from secure origins: HTTPS or localhost.
  • RTP data channel support has been removed. Any remaining applications still using RTP data channels should use the standard data channels instead.

As with all releases, we encourage developers to try Chrome on the Canary, Dev, and Beta channels and report any issues found. The help we receive is invaluable. For pointers on how to file a good bug report, please take a look at the WebRTC bug page.

Demos

Find out more

Introducing Background Sync

$
0
0

Background sync is a new web API that lets you defer actions until the user has stable connectivity. This is useful for ensuring that whatever the user wants to send, is actually sent.

The problem

The internet is a great place to waste time. Without wasting time on the internet, we wouldn’t know cats dislike flowers, chameleons love bubbles, and “You do What They Told Ya” as sung by “Rage Against the Machine” sounds like the Japanese for, “Break the chicken nugget, daddy”.

But sometimes, just sometimes, we’re not looking to waste time. The desired user experience is more like:

  1. Phone out of pocket.
  2. Achieve minor goal.
  3. Phone back in pocket.
  4. Resume life.

Unfortunately this experience is frequently broken by poor connectivity. We’ve all been there. You’re staring at a white screen or a spinner, and you know you should just give up and get on with your life, but you give it another 10 seconds just in case. After that 10 seconds? Nothing. But why give up now? You’ve invested time already, so walking away with nothing would be a waste, so you carry on waiting. By this point you want to give up, but you know the second you do so, is the second before everything would have loaded if only you’d waited.

Service workers solve the page loading part by letting you serve content from a cache. But what about when the page needs to send something to the server?

At the moment, if the user hits “send” on a message they have to stare at a spinner until it completes. If they try to navigate away or close the tab, we use onbeforeunload to display a message like, “Nope, I need you to stare at this spinner some more. Sorry”. If the user has no connection we tell the user “Sorry, you must come back later and try again”.

This is rubbish. Background sync lets you do better.

The solution

The following video shows Emojoy, a simple emoji-only chat demo… thing. It’s a progressive app. It works offline-first. It uses push messages and notifications, and it uses background sync.

If the user tries to send a message when they have zero connectivity, then, thankfully, the message is sent in the background once they get connectivity.

Background sync hasn’t hit the main release of Chrome yet, so if you want to try this you’ll need either Chrome Dev for Android, or Chrome Canary for desktop. You’ll also need to enable chrome://flags/#enable-experimental-web-platform-features and restart the browser. Then:

  1. Open Emojoy.
  2. Go offline (either using airplane-mode or visit your local Faraday cage).
  3. Type a message.
  4. Go back to your homescreen (optionally close the tab/browser).
  5. Go online.
  6. Message sends in the background!

Being able to send in the background like this also yields a perceived performance improvement. The app doesn’t need to make such a big deal about the message sending, so it can add the message to the output straight away.

How to request a background sync

In true extensible web style, this is a low level feature that gives you the freedom to do what you need. You ask for an event to be fired when the user has connectivity, which is immediate if the user already has connectivity. Then, you listen for that event and do whatever you need to do.

Like push messaging, it uses a service worker as the event target, which enables it to work when the page isn’t open. To begin, register for a sync from a page:

// Register your service worker:
navigator.serviceWorker.register('/sw.js');

// Then later, request a one-off sync:
navigator.serviceWorker.ready.then(function(swRegistration) {
  return swRegistration.sync.register('myFirstSync');
});

Then listen for the event in /sw.js:

self.addEventListener('sync', function(event) {
  if (event.tag == 'myFirstSync') {
    event.waitUntil(doSomeStuff());
  }
});

And that’s it! In the above, doSomeStuff() should return a promise indicating the success/failure of whatever it’s trying to do. If it fulfills, the sync is complete. If it fails, another sync will be scheduled to retry. Retry syncs also wait for connectivity, and employ an exponential back-off.

The tag name of the sync (‘myFirstSync’ in the above example) should be unique for a given sync. If you register for a sync using the same tag as a pending sync, it coalesces with the existing sync. That means you can register for an “clear-outbox” sync every time the user sends a message, but if they send 5 messages while offline, you’ll only get one sync when they become online. If you want 5 separate sync events, just use unique tags!

Here’s a simple demo that does the bare minimum; it uses the sync event to show a notification.

What could I use background sync for?

Ideally, you’d use it to schedule any data sending that you care about beyond the life of the page. Chat messages, emails, document updates, settings changes, photo uploads… anything that you want to reach the server even if user navigates away or closes the tab. The page could store these in an “outbox” store in indexedDB, and the service worker would retrieve them, and send them.

Although, you could also use it to fetch small bits of data…

Another demo!

This is the offline wikipedia demo I created for Supercharging Page Load. I’ve since added some background sync magic to it.

Try this out yourself. As before make sure you’re in Chrome Dev for Android, or Chrome Canary for desktop with chrome://flags/#enable-experimental-web-platform-features.

  1. Go to any article, perhaps Chrome.
  2. Go offline (either using airplane-mode or join a terrible mobile provider like I have).
  3. Click a link to another article.
  4. You should be told the page failed to load (this will also appear if the page just takes a while to load).
  5. Agree to notifications.
  6. Close the browser.
  7. Go online
  8. You get notified when the article is downloaded, cached, and ready to view!

Using this pattern, the user can put their phone in their pocket and get on with their life, knowing the phone will alert them when it’s fetched want they wanted.

Permissions

The demos I’ve shown use web notifications, which require permission, but background sync itself does not.

Sync events will often complete while the user has a page open to the site, so requiring user permission would be a poor experience. Instead, we’re limiting when syncs can be registered and triggered to prevent abuse. E.g.:

  • You can only register for a sync event when the user has a window open to the site.
  • The event execution time is capped, so you can’t use them to ping a server every x seconds, mine bitcoins or whatever.

Of course, these restrictions may loosen/tighten based on real-world usage.

Progressive Enhancement

It’ll be a while before all browsers support background sync, especially as Safari and Edge don’t yet support service workers. But progressive enhancement helps here:

if ('serviceWorker' in navigator && 'SyncManager' in window) {
  navgiator.serviceWorker.ready.then(function(reg) {
    return reg.sync.register('tag-name');
  }).catch(function() {
    // system was unable to register for a sync,
    // this could be an OS-level restriction
    postDataFromThePage();
  });
} else {
  // serviceworker/sync not supported
  postDataFromThePage();
}

If service workers or background sync aren’t available, just post the content from the page as you’d do today.

Note that it’s worth using background sync even if the user appears to have good connectivity, as it protects you against navigations and tab closures during data send.

The future

We’re aiming to ship background sync to a stable version of Chrome in the first half of 2016. But we’re also working on a variant, “periodic background sync”. This will allow you to request a “periodicsync” event restricted by time interval, battery state and network state. This would require user permission, of course, but it will also be down to the will of the browser for when and how often these events fire. E.g., a news site could request to sync every hour, but the browser may know you only read that site at 07:00, so the sync would fire daily at 06:50. This idea is a little further off than one-off syncing, but it’s coming.

Bit by bit we’re bringing successful patterns from Android/iOS onto the web, while still retaining what makes the web great!

Security Panel debuts in Chrome DevTools

$
0
0

The new Security Panel

The Chrome Security team has been hard at work to realize a future without HTTP, a future where you and your users can be reasonably sure that whatever data you’re sending to the web stays between you and the site you’re looking at. And to to make it even easier to jump ship and join the glorious HTTPS future, we’ve made Security a first-class citizen in DevTools.

The new Security panel introduced in Chrome 48 makes it a lot easier to see any issues you have with certificates and mixed content. You can head to it directly in DevTools or by clicking on the URL bar’s lock icon, then the “Details” link.

Addressing the problems with “Connection Info”

Our current solution for those of you who want data about page security is a click onto the little lock icon next to the URL, then parsing the info available on the “Connection” tab.

Unfortunately, this tab had several problems:

  • It’s too complicated for most users
  • …but too basic for most developers
  • and makes it unclear what causes a lock icon “downgrade”

Overview: Explain lock icon and surface mixed content

Overview tab

The lock icon represents the security state of the page, so knowing when and why it appears is extremely important. The overview screen in the new security panel explains the important parts that contribute to a secure page:

  • Identity (certificate)
  • Connection (protocol, cipher suite)
  • Subresources

You’ll now know at a glance why your site does or does not get the little green badge of awesomeness.

Have mixed content appear out of nowhere? No worries. We show it directly on the overview, and a click brings you to a filtered view of the Network Panel, so you can quickly look at the offending requests:

(image)

Origin View: Connection Type and Certificate Details

Connection tab

If you need information about a specific TLS connection, the Origin view will help. Reload the page and you’ll see every individual origin for all resources appear in the left hand navigation.

From here, you can find out everything about the certificate used and the connection type. In addition, it gives you the handy ability to drill down further to inspect all resources coming from that origin via the Network Panel.


Give the new Security panel a try and and let us know what you think on Twitter or via bug/feature ticket!

Google Cast for Chrome on Android

$
0
0

Imagine being able to use a web app from your phone to present a slide deck to a conference projector — or share images, play games or watch videos on a TV screen — using the mobile web app as a controller.

The latest release of Chrome on Android allows sites to present to Google Cast devices using the Cast Web SDK. This means you can now create Cast sender apps using the Web SDK with Chrome on Android or iOS (or on desktop with the extension) as well as creating apps that use the native Cast SDK for Android and iOS. (Previously, a Google Cast sender application needed the Google Cast Chrome extension, so on Android it was only possible to interact with Cast devices from native apps.)

Below is a brief introduction to building a Cast sender app using the Web SDK. More comprehensive information is available from the Chrome Sender App Development Guide.

All pages using Cast must include the Cast library:

<script type="text/javascript"
  src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js"></script>

Add a callback to handle API availability and initialize the Cast session (make sure to add the handler before the API is loaded!):

window['__onGCastApiAvailable'] = function(isLoaded, error) {
  if (isLoaded) {
    initializeCastApi();
  } else {
    console.log(error);
  }
}

function initializeCastApi() {
  var sessionRequest = new chrome.cast.SessionRequest(applicationID);
  var apiConfig = new chrome.cast.ApiConfig(sessionRequest,
      sessionListener, receiverListener);
  chrome.cast.initialize(apiConfig, onInitSuccess, onError);
};

If you’re using the default Styled Media Receiver application and not a roll-your-own, registered Custom Receiver application, you can create a SessionRequest like this:

var sessionRequest = new chrome.cast.SessionRequest(chrome.cast.media.
  DEFAULT_MEDIA_RECEIVER_APP_ID);

The receiverListener callback above is executed when one or more devices becomes available:

function receiverListener(e) {
  if (e === chrome.cast.ReceiverAvailability.AVAILABLE) {
    // update UI
  }
}

Launch a Cast session when your user clicks the Cast icon, as mandated by the User Experience Guidelines:

chrome.cast.requestSession(onRequestSessionSuccess,
    onRequestSessionError);

function onRequestSessionSuccess(e) {
  session = e;
}

The user will be presented with a device picker:

Cast device selection dialog

The route details dialog is shown when the page is already connected and calls requestSession():

Cast route details dialog

Once you have a Cast session, you can load media for the selected Cast device, and add a listener for media playback events:

var mediaInfo = new chrome.cast.media.MediaInfo(mediaURL);
var request = new chrome.cast.media.LoadRequest(mediaInfo);
session.loadMedia(request,
    onMediaDiscovered.bind(this, 'loadMedia'),
    onMediaError);

function onMediaDiscovered(how, media) {
  currentMedia = media;
  media.addUpdateListener(onMediaStatusUpdate);
}

The currentMedia variable here is a chrome.cast.media.Media object, which can be used for controlling playback:

function playMedia() {
  currentMedia.play(null, success, error)
}

// ...

A play/pause notification is shown when media is playing:

Cast play/pause notification

If no media is playing, the notification only has a stop button, to stop casting:

Cast stop notification

The sessionListener callback for chrome.cast.ApiConfig() (see above) enables your app to join or manage an existing Cast session:

function sessionListener(e) {
  session = e;
  if (session.media.length !== 0) {
    onMediaDiscovered('onRequestSessionSuccess', session.media[0]);
  }
}

If Chrome on Android allows casting media from your website but you want to disable this feature, use the disableRemotePlayback attribute, available in Chrome 49 and above:

<video disableRemotePlayback src="...">

Alt Sender and receiver devices

The Cast Web SDK guide has links to sample apps, and information about Cast features such as session management, text tracks (for subtitles and captions) and status updates.

At present, you can only present to a Cast Receiver Application using the Cast Web SDK, but there is work underway to enable the Presentation API to be used without the Cast SDK (on desktop and Android) to present any web page to a Cast device without registration with Google. Unlike the Chrome-only Cast SDK, using the standard API will allow the page work with other user agents and devices that support the API.

The Presentation API, along with the Remote Playback API, is part of the Second Screen Working Group effort to enable web pages to use second screens to display web content.

These APIs take advantage of the range of devices coming online — including connected displays that run a user agent — to enable a rich variety of applications with a ‘control’ device and a ‘display’ device.

We’ll keep you posted on progress with implementation.

In the meantime, please let us know if you find bugs or have feature requests: crbug.com/new.

Find out more

Input Device Capabilities

$
0
0

Chrome 47 has a new feature that makes it easier to understand the how users interact with your site: InputDeviceCapabilities! Let’s step back a bit and learn why this is important.

DOM input events are an abstraction above low-level input events, loosely tied to physical device input (e.g., click events can be fired by a mouse, touchscreen, or keyboard). However, there is a problem: there is no simple method to obtain the details of the physical device responsible for an event.

In addition, certain types of input can generate further “fake” DOM input events for compatibility reasons. One such fake DOM event happens when a user taps a touch screen (such as on a mobile phone); it not only fires touch events but, for compatibility reasons, mouse events as well.

This causes problems for developers when supporting both mouse and touch input. It’s difficult to know if a mousedown event actually represents new input from a mouse, or is just a compatibility event for a previously-processed touchstart event.

The new InputDeviceCapabilities API provides details about the underlying sources of input events via a sourceCapabilities object on the UIEvent.
The object has a firesTouchEvents property that is set to true or false based on how the event was generated by the user action.

The question is: Where should this be used?

Outside of Pointer Events, many developers today handle the logic for interaction in the touch-layer, preventing Default to avoid creating “fake” mouse events in the first place.This design works well in many scenarios and doesn’t need to change to take advantage of InputDeviceCapabilities.

But in some scenarios you really don’t want to preventDefault the touch event; for example, you still want taps to send ‘click’ events and change focus. For these cases, the information held in the MouseEvent.sourceCapabilities.firesTouchEvents property allows you to start consolidating the logic for touch- and mouse-based events into a model that is similar to how you would manage the logic with Pointer Events. That is, you can have just one set of code that manages the interaction logic and provides developers a simpler way to share logic among browsers that do and don’t support Pointer Events.

function addMouseEventListener(target, type, handler, capture) {
  target.addEventListener(type, function(e) {
    if (e.sourceCapabilities.firesTouchEvents)
      return false;
    return handler(e);
  }, capture);
}

The good news is that this has been Polyfilled by Rick Byers so that you can use it across most platforms.

Today this API is minimal, focused on solving a specific problem with identifying mouse events derived from touch events. It is even possible to instantiate an instance of InputDeviceCapabilities; however, it only contains firesTouchEvents. In the future it’s expected to expand to enable you to understand more about all of the input devices on a user’s system. We would love to get your feedback on use cases.

DevTools Digest: Tab reordering, Console is #2 and framework event listeners

$
0
0

Re-order DevTools tabs which ever way suits you best; see exactly where framework events were bound and block network requests to see which third party scripts slow you down.

Better Panel Navigation: Console on #2, Tab Reordering and Nifty Underlines

After investigating which areas of DevTools are used the most, it became clear that the full-screen Console panel didn’t deserve the last position in the main tab bar. As second-most used panel, it’s now the second tab. This especially matters on lower resolutions when we can’t show all tabs at once.

But look, we get it. The classic order is part of your muscle memory and you’ll feel dizzy for a while. Or maybe, gasp, you just hate the full screen console! Fear not, we’ve got you covered. The tabs can now be reordered by dragging them around, like so:

The changes you make to the tab bar persist, and it works with both native tabs and extension-provided tabs. And as a bonus, we’ve thrown in smooth, animated underlines. Because we’re nice like that.

Support for Framework Event Listeners

Events created by JS Frameworks such as jQuery have sometimes been a pain when working with DevTools. That’s because most frameworks wrap the native DOM events into their custom event API, so looking at the event listener doesn’t really reveal much about what’s happening:

Framework Listeners Off

But with the new “Framework Listeners” option in the Event Listener tab, DevTools becomes aware of the framework wrapping portion and automatically resolves it. Now, events bound by frameworks look and behave exactly like their native counterparts, telling you where it was actually bound:

Framework Listeners On

The Best of the Rest

  • Custom Object Formatters allow transpiled languages such as CoffeeScript to better format their objects in the DevTools Console.
  • The Timeline has a new better looking dialog during recording that shows you status, time and buffer usage at a glance.
    Timeline Hint
  • Along the same lines, the Network Panel shows a helpful hint when empty now: Network Hint
  • You can now filter for mixed content in the Network Panel by using the filter input and set it to mixed-content:displayed

As always, let us know what you think via Twitter or the comments below, and submit bugs to crbug.com/new.

Until next month!
Paul Bakaus & the DevTools team

Adding a Splash screen for installed web apps in Chrome 47

$
0
0

Over the past year we have focused on letting developers build sites and apps that feel like they are installed on the user’s system: service worker for letting you easily build offline first experiences and Add to Homescreen to give your site the presence on the user’s device.

The home screen launch process on Android is a great first step, however there was always a tell that this wasn’t a native-like experience: When you click on the home screen icon the screen would go white until the document was ready to render its first frame of the document. This could take anywhere from 200ms of white up to, well, it depends on how quickly you can draw something. Some poorly designed sites can take many seconds to get their first paint and we believe that the splash screen increases the perceived performance of loading of your site.

In Chrome 46 on Android we quietly introduced background_color that removes this delay and paints the screen with a solid colour until the browser is ready to paint something from the web page. This was a good addition, yet it still didn’t look fully like an app.

Now in Chrome 47 on Android (Beta in October 2015) we are introducing the concept of a “splash screen”.

Try it out on Voice Memos, Air Horner or SVG OMG.

The splash screen is generated dynamically from information held in the Web App Manifest and is a combination of the name and background_color properties, and the icon in the icons array that is closest to “128dp” for the device.

128dp is the ideal size for the image on the splash screen as it means no scaling will be applied to the image. Now we web developers don’t deal with dp’s. We use physical pixels or CSS pixels. In the case of splash screen and configuration in the manifest only physical pixels are considered. 1dp is 1 physical pixel at a screen density of 160dpi.

1dp = 1px at 160 dpi.

128dp at 1x (160dpi) = 128px
128dp at 1.5x (240dpi) = 192px ( 128 * ( 240 / 160 ) ) 128dp at 2x (320dpi) = 256px
128dp at 3x (480dpi) = 384px (Equivalent to Nexus 5)
128dp at 4x (640dpi) = 512px (Nexus 6 is in between 3 and 4)

If you want to ensure that an icon will always be displayed consider that 48dp is the minimum image size we will display, which if you take the maximum density display currently supported (4x) then 48 * 4 = 192px. This is lucky because we need to 192px image for Add to Homescreen to work! Yay. Therefore, I would recommend always having 192px as the minimum sized icon and create 3 other versions at 256px, 384px and 512px. However, if you want to ensure that the user is not downloading too much data for the splash screen, especially on a low density device then you can go lower and Chrome will try to fetch the most appropriate image.

The following is a sample manifest (note: do not set the density field in the icons array, it will cause you a whole heap of pain, well, unless you know what you are doing):

{
  "short_name": "Voice Memos",
  "name": "Voice Memos",
  "start_url": "./?utm_source=web_app_manifest",
  "icons": [
    {
      "src": "/images/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/images/icon-256x256.png",
      "sizes": "256x256",
      "type": "image/png"
    },
    {
      "src": "/images/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "/images/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "background_color": "#FAFAFA",
  "theme_color": "#512DA8",
  "display": "standalone",
  "orientation": "portrait"
}

Ensure that in your manifest you have:

  • A name - it will be displayed at the bottom of the screen
  • A background_color, and for the best effect have it match the background color of your page so the transition on first paint is near seamless.
  • An optional theme_color if you have them inside the your app already, this will ensure a smooth transition when the splash screen is replaced by your app content.
  • High quality icons that will displayed in the center of the splash screen - ensure your icon is at least 192px.

I think this is a great step in making sites and apps feel even more like they are meant to be part of the user’s mobile device.

FAQ

  • Will this work on Chrome for iOS or on Desktop?
    • No. It is only Android.
  • Will this splash screen appear when a user visits my site from a link?
    • No, this only shows when a user clicks the icon for your site on their home screen.
  • Is there an API to control this or make it look like the shell of my app?
    • No, we are following guidelines similar to Android’s and how iOS works.
      Added to that, we don’t know that the screen size will always be the same and trying to predict that for an app shell is outside that remit of this.

Detecting if a web app is launched from the home screen

$
0
0

During the past year we have focused on enabling users to build app like experiences on the web by making it possible for apps to work offline using service worker and to get a presence on the home screen using the Web App Manifest.

Now apps tend to offer different experiences as sites, and developers might want to offer different experiences depending on whether the site is viewed in the browser or launched as a standalone web app, from the homescreen.

One example could be to show a navigation drawer only when launched as an app (ie. without any browser chrome).

A way to accomplish this has been to encode a custom parameter on the URL defined in start_url in the manifest, which when launched will be accessible to the page via window.location:

{
  "name": "Air Horner",
  "short_name": "Air Horner",
  ...
  "start_url": "/?homescreen=1",
  "display": "standalone",
  "background_color": "#2196F3",
  "theme_color": "#2196F3"
}

While this works, it means that the developer needs to handle everything from directly JavaScript, including modifying CSS, or applying different CSS rules.

The web already has a very nice way of working with conditional CSS, called media queries. Since M46, Chrome in Android supports the display-mode media query feature, which can be used to find out what the current display-mode is being used for displaying the app, ie. is it being displayed by a browser, standalone or fullscreen. display-mode is also supported for standalone Chrome apps, which will mean that (display-mode: standalone) is true.

To apply a different background color for the app above when being launched from the home screen, all we need to do it use the following conditional CSS:

@media all and (display-mode: standalone) {
  body {
    background-color: yellow;
  }
}

It is also possible to detect is the display-mode is standalone from JavaScript:

if (window.matchMedia('(display-mode: standalone)').matches) {
  console.log("Thank you for installing our app!");
}

Unfortunately, you cannot check whether the display-mode media query feature is available, as (display-mode) returns false in M46. This issue has since been fixed and should ship in M48.

Best practices

As a general note, it is recommended to not use the media query to hide or show so-called manual “install banners”, telling people to add the app to the home screen manually. This is better done by using the rules set out in “Increasing engagement with Web App install banners”.

It is also recommended to not add back-buttons which are visible in the standard Chrome UI. If a back-button is needed, the "display": "browser" mode can be used in the web app manifest instead.

FAQ

  • Will this work on Chrome for iOS or on Desktop?
    • This feature works on any platform where web apps can be added to the homescreen, meaning it works for Android as well as for desktop “Add to desktop” apps. It additional works for Chrome Apps distributed through the Chrome store. It currently does not work on iOS.
  • Can’t I use “display”: “minimal-ui” instead of “display”: “browser” if I want a simple back-button?
    • Chrome currently doesn’t support “minimal-ui”, nor is such support planned for the foreseeable future.

Notification requireInteraction — A smoother notification UX on desktop

$
0
0

We’ve learnt a lot since Notifications and Push Messaging landed in Chrome. One specific piece of feedback about Desktop-class devices was that notifications would stay around and visible on the user’s screen until actively dismissed by the user.

When the page is open it is possible to create a simple JavaScript timer that will automatically close the notification. But we now live in a world with service worker: where web apps can live past the lifetime of a window and the service workers are put to sleep as quickly as possible to save resources. This means we need another way to create a good experience for users.

The Nofitification spec was recently updated to give the developer the ability to indicate that the notfication should not be automaticaly dismissed by the system.

A notification has an associated require interaction preference flag which is initially unset. When set, indicates that on devices with a sufficiently large screen, the notification should remain readily available until the user activates or dismisses the notification.

This might seem odd, but what it implies that unless told otherwise the notification should be removed from view after a short period of time.

Chrome 47 (beta in October 2015) now supports the requireInteraction option. Unless it is explicitly provided and set to true, all notifications on desktop will be dismissed after approximately 20 seconds. The interesting part though is that Chrome has recently just removed the Notification Center from all desktop platforms (but Chrome OS), this means that minimized notifications are considered to be dismissed and are not accessible in a call to getNotifications in a service worker.

On Chrome for Android, because the notifications are minimized in the notifications tray area, the requireInteraction option is ignored.

navigator.serviceWorker.register('sw.js');

function showNotifications() {
  Notification.requestPermission(function(result) {
    if (result === 'granted') {
      navigator.serviceWorker.ready.then(function(registration) {
        registration.showNotification('requireInteraction: true', {
          body: 'Requires interaction',
          icon: '../images/touch/chrome-touch-icon-192x192.png',
          requireInteraction: true,
          tag: 'require-interaction'
        });

        registration.showNotification('requireInteraction: false', {
          body: 'Does not require interaction',
          icon: '../images/touch/chrome-touch-icon-192x192.png',
          requireInteraction: false,
          tag: 'no-require-interaction'
        });
      });
    }
  });
}

Try the demo.

Manage the triggering of Touch to Search

$
0
0

Touch to Search launched in June of 2015 on Chrome 43 for most Android phones. When the user taps text on any page in Chrome, the word is selected along with relevant surrounding text. The search term appears in a bar at the bottom of the screen, which users can open in an overlay panel to show full search results.

Tap triggering is enabled for any plain text that is selectable and non interactive or not focusable. When the page has a click handler that responds to a tap on text, Touch to Search automatically detects the response and ignores it since we know the developer intended to handle the event. Using a touch-and-hold gesture to manually select text also triggers the Touch to Search bar. Users can enable or disable the feature using a preference under Chrome’s Privacy settings.

As the author of a site there are often times when you don’t want a tap gesture on certain element to trigger a search. To ensure that Chrome does what you intend, make those elements:

  1. Focusable: add a tabindex=-1 property on the element.
  2. Interactive: Use any of several standard ways to indicate that an element is interactive:
    • Use accessibility markup to indicate the element has a widget role, or widget attributes. For example, any element with role=button won’t trigger. Adding accessibility markup has the added benefit that your page will be more readable by visually impaired users.
    • Any JavaScript click handler that calls preventDefault(), or manipulates the DOM or CSS will not trigger Touch-to-Search.
  3. Non-selectable: using -webkit-user-select: none; Non-selectable text will not trigger Touch-to-Search even when using the touch-and-hold gesture.

If Touch to Search does not trigger when or where it should trigger, or triggers intermittently, then elements are probably marked focusable or interactive when they should not be. Use the following procedure to help determine what’s preventing Touch to Search from triggering:

  1. Check if the text is selectable using the touch-and-hold gesture. If the text selects, but the Touch-to-Search bar does not appear, check that the feature has not been disabled on your phone in the Touch to Search setting under Privacy in Chrome. Also note that some low-end devices do not support Touch-to-Search.
  2. If the Touch-to-Search bar shows when text is selected, but not when you tap, then there is some tap triggering issue. If the triggering is intermittent, then the problem is likely due to animation being conditionally activated by a JavaScript handler for the element.
  3. If the triggering never happens, consult the trigger reasons listed above (check if the element is focusable or interactive).

If your page still doesn’t behave the way you’d like, file a bug at crbug.com and add the label Cr-UI-Browser-Mobile-TouchToSearch.

Web Animations Resources

$
0
0

The Web Animations API provides powerful primitives to describe imperative animations from JavaScript - but what does that mean? Find out about the resources available to you, including Google’s demos and codelabs.

Background

At its core, the API provides the Element.animate() method. Let’s see an example, which animates the background color from red to green-

var player = document.body.animate(
    [{'background': 'red'}, {'background': 'green'}], 1000);

This method is supported in all modern browsers, with a great polyfill fallback (more on that later). Native support for this method - and its player object - became widely available as part of Chrome 39. It’s also natively available in Opera, and is under active development for Firefox. This is a powerful primitive that deserves a place in your toolbox.

Note! For a primer on the different approaches to animation on the web, including Web Animations, check out Modern Animation Fundamentals on YouTube and Animations on Web Fundamentals.

Codelabs

A growing number of codelabs are available for the Web Animations API. These are self-paced guides that demonstrate different concepts in the API. In most of these codelabs, you’ll take static content and enhance it with animation effects.

These codelabs, and related links or resources, are the absolute best place to start if you’re looking to understand the new primitives available to you in Web Animations. For an idea of what you might build, check out this Android-inspired reveal effect-

Preview of codelab result

So if you’re just getting started, then look no further!

Demos

If you’re looking for inspiration, be sure to check out the Material-inspired Web Animations Demos, with source hosted on GitHub. These demonstrate a variety of amazing effects and you can view each demo’s source code inline.

The demos include a colorful spinning galaxy, rotating Earth, or even just a variety of effects on a plain old element.

Polyfill

To ensure great support across all modern browsers, you can use a polyfill library. The Web Animations API has a polyfill available right now that brings it to all modern browsers, including Internet Explorer, Firefox, and Safari.

If you’re feeling adventurous, you can use the web-animations-next polyfill, which also includes features that are yet to be finalized - such as the composable GroupEffect and SequenceEffect constructors. For a comparison between the two polyfills, please see the homepage.

To use either polyfill in your code, you have a few options.

  1. Use a CDN, such as cdnjs, jsDelivr, or target a specific release via rawgit.com

  2. Install via NPM or Bower

$ npm install web-animations-js
      $ bower install web-animations-js

In all cases, you can simply include the polyfill in a script tag before any other code-

<script src="https://cdn.jsdelivr.net/web-animations/latest/web-animations.min.js"></script>
<script>
  document.body.animate([
    {'background': 'red'},
    {'background': 'green'}
  ], 1000);
</script>

Other resources

If you’d like to read a more technical introduction, please check out the W3C spec.

Dan Wilson has also written a great set of posts on Web Animations, including on how to use it alongside the new CSS motion-path property. For some samples using motion-path, check out Eric Willigers’ doc.

DevTools Digest: Efficient element edits, service worker debugging, and Material Design shades

$
0
0

Use the DOM panel’s new context menu to efficiently edit nodes. Debug services workers directly via the Resources panel. Choose from all of the Material Design shades in the colorpicker. Blackbox JS libraries more easily.

The DOM panel’s new, improved context menu

The new DOM context menuWe’ve analyzed the most-used actions in the DOM panel and concluded that the right-click context menu should be uncluttered and re-organized.

It’s now much easier to quickly hide or delete an element, trigger a certain state like :active or :hover or edit its HTML. And if you’re on a trackpad and don’t want to bother right-clicking, click on the three little dots next to the selected element instead.

Debug Service Workers via the Resources panel

Service workers are fantastic once you’ve got them set up but they can be tricky to wrap your head around early on. This was made worse by the fact that debugging them required leaving the DevTools and opening chrome://serviceworker-internals/ in a new browser window.

Service Workers in Resources

Not anymore! Now you can debug service workers for the current domain directly from the Resources panel. It’s still a work-in-progress, but already a heavy improvement from the previous status quo.

All the colors: Material Design shades in the colorpicker

A few weeks ago, we added the Material Design palette to the colorpicker to give you primary, bold colors out-of-the-box. To actually design a full page, you inevitably need full access to all of the Material Design shades, so we’ve baked them in.

To bring up the shades, long press on one of the primary colors and click on a shade instead.

Blackbox JavaScript libraries more easily in Settings

JavaScript Blackboxing has been around for a while but wasn’t terribly easy to discover. It’s a feature that allows you to blackbox a script on a page to focus on your authored code only (and hide all the wrapping code).

We’ve now moved it to Settings. Give it a try:

Blackboxing

The Best of the Rest

  • Missing access to Rendering toggles? Rendering Settings have been moved to the DevTools main menu (under “More Tools”). In addition to the usual suspects (i.e. FPS meter), we’ve moved “Emulate print media” there as well.
  • Tired of typing chrome://inspect into the Omnibox? Inspect Devices can now also be found in the new main menu under “More Tools”.
  • Accidentally closed one of these closable Drawer tabs like Rendering or Search? You can now reopen them with the new menu on the left.

As always, let us know what you think via Twitter or the comments below, and submit bugs to crbug.com/new.

Until next month!
Paul Bakaus & the DevTools team

Viewing all 599 articles
Browse latest View live