Craig Buckler Freelance UK IT consultant specialising in HTML5 webby stuff.

What’s new in Chrome 78

5 min read 1570

The stable version of Chrome 78 will be released on October 22, 2019. Few users will notice changes but there are some exciting new features for web developers…

CSS opacity percentage

The opacity property currently accepts a value between 0 (fully transparent) and 1 (fully opaque). Chrome 78 also permits a percentage from 0% to 100%:

/* identical styles */
.style1 { opactity: 0.75; }
.style2 { opacity: 75%; }

This brings some much-needed consistency to CSS since the rgba() function already accepts a percentage, e.g. rgba(100, 150, 200, 75%).

Percentages can also be used on opacities set in the SVG properties stop-opacity, fill-opacity, stroke-opacity, and shape-image-threshold.

JavaScript optional chaining

Optional chaining is an ES2019 proposal that will save you hours of typing and debugging effort! Imagine you need to analyze a user object which has been returned following an Ajax request to a REST API call:

let user = {
  firstname: 'Imaginary',
  lastname: 'Person',
  address: {
    street1: '123 Madeup Street',
    street2: '',
    city: 'Nowhereville',
    country: 'Antarctica'
  }
};

// output "Antarctica"
console.log( user.address.country );

What if the country value had not been set? JavaScript would return undefined.

Unfortunately, the situation is worse if the address or user object has not been defined – the code will raise an error and stop further JavaScript code from running.

For this reason, your code must check the existence of every parent property:

let country = (user && user.address && user.address.country) || undefined;

Or the more hideous:

let country =
  (user ?
    (user.address ?
    (user.address.country ?
          user.address.country : undefined
    ) :
      undefined
    ) :
    undefined
  );

Optional chaining in Chrome 78 permits the considerably more concise ?. chaining operator:

let country = user?.address?.country;

Instead of throwing an error, JavaScript sets the country variable to undefined if any value is falsy (null, undefined, etc.) Further methods can be appended without risk of failure:

let countryLength = user?.address?.country?.length;

While optional chaining is incredibly useful, no other browser or Node.js currently permits the syntax. A Babel plugin will be necessary until support becomes more widespread.

Internationalization API updates

The Intl object provides locale-specific string comparison, number formatting, date and time formatting which is especially useful when operating in global markets. The API has reasonable support across browsers and is slowly appearing in Node.js. Check out this example:

// set date to 31 December 2020
let date = new Date(2020, 11, 31);

// outputs US date format - 12/31/2020
console.log( new Intl.DateTimeFormat('en-US').format(date) );

// outputs UK date format - 31/12/2020
console.log( new Intl.DateTimeFormat('en-GB').format(date) );

// set number
let num = 12345.67;

// output US number format - 12,345.67
console.log( new Intl.NumberFormat('en-US').format(number) );

// output German number format - 12.345,67
console.log( new Intl.NumberFormat('de-DE').format(number) );

DateTimeFormat and NumberFormat accept an optional options object as a second parameter. Chrome 78 adds calendar and numberingSystem options for locales that use two or more calendars or numbering systems.

Dark pattern restrictions

The window unload event triggers when a user navigates away from the page:

window.addEventListener('unload', () => {
  // do something when the user leaves the page
});

Similar events can be registered for:

  • beforeunload – the document is visible and about to be unloaded, but the event can still be canceled
  • pagehide – the browser is navigating to a different page in the session history, e.g. the back button has been clicked
  • visibilitychange – the user switches to or from the current tab

Typically, these events can be used to check data that has been saved or record usage analytics.

Unfortunately, some less-conscientious developers can add code to harm the user experience. From version 78, Chrome will not permit:

  1. Synchronous Ajax requests – this can be overridden in the AllowSyncXHRInPageDismissal policy flag, but the flag will also be removed in version 82
  2. Popup generation with window.open() – the popup blocker will normally prevent this, but it is now prohibited even when the blocker is inactive

Independent scroll offsets

Prior to Chrome 78, the window.scrollTo() method and scroll properties such as scrollTop and scrollLeft would calculate the nearest physical pixel. For example, on a double pixel density device (devicePixelRatio is 2), window.scrollTo(0, 123.678) and window.scrollTop would equate to 123.5.

From Chrome 78, the actual value passed will be returned (123.678) regardless of the physical pixels. This should help prevent scroll calculation issues especially when a page is zoomed.

User Timing Level 3

The User Timing API allows developers to measure application performance by creating custom timestamps. Named performance marks are created at critical points throughout your code, e.g.

performance.mark('markstart');
// ...processing...
performance.mark('markend');

Performance measures can then report the duration between two marks, e.g.

performance.measure('m1', 'markstart', 'markend');
performance.getEntriesByName('m1');

/*
Returns something like:
(1) [...]
  0: PerformanceMeasure
     duration: 5153
     entryType: "measure"
     name: "m1"
     startTime: 7314
*/

Level 3 permits developers to pass custom timestamps and arbitrary metadata to performance mark and measure methods.

Payment API updates

The Payment Request API aims to provide a consistent and secure online transaction experience for merchants and customers. It allows users to select their preferred payment option which is passed to the e-commerce website.

Chrome 78 introduces several new options:

  • The hasEnrolledInstrument() method of the PaymentRequest object checks auto-fill payment data to ensure it is valid and complete. For example, it will not allow an expired credit card to be chosen
  • The retry() method of the PaymentResponse object allows a customer to retry a payment when processing errors occur
  • The PaymentRequest shippingaddresschange event sends the shipping address to the merchant in order to calculate delivery costs, tax, etc. Since the buyer has not yet committed to a purchase, their address is redacted to remove recipient names, organizations, full addresses, and phone numbers which are not needed for shipping calculations

WebSocketStream

The WebSocket API creates a two-way communication channel between the browser and the server. Either device can send a message at any point, so the technology is often used for chat rooms, multiplayer games, and real-time data updates.

Unfortunately, messages can arrive faster than the browser can cope with. In those situations, the memory buffer can overflow or CPU usage will increase to the point that the browser becomes unresponsive.

WebSocketStream supersedes the WebSocket API. It is promise-based and integrates streams so a chunk of data can be parsed before the full message has been received.

The API is new, experimental, and may evolve or be dropped before becoming a W3C standard. For more information, refer to WebSocketStream Explained.

Media element seekto event

HTML audio and video media elements register a number of events such as:

  • play – triggers when the video is played when it is auto-started or resumed after pausing
  • timeupate – the playback time has changed
  • volumechange – the volume has been changed

Chrome 78 introduces a new seekto action handler which is called when playback is moved to a specific point on the timeline. This could be used to make DOM changes, record analytics, etc. At the time of writing, there is no documentation or support in other browsers.

Screen Enumeration API

The Screen Enumeration API provides information about all displays connected to the user’s device. It will typically be useful in situations where an application can use more than one monitor, e.g. presentations that provide public-facing slides and speaker note displays.

No documentation is currently available, but it will be used in conjunction with the new Window Placement API.

Native File System API

The Native File System API allows the browser to directly interact with the chosen files on the user’s local device. It could be used to edit photos, videos, or text documents from client-side JavaScript without requiring upload and download processes.

Chrome 78 provides an early version of the API for trial purposes and developers must register for a token from Google before it can be used.

SMS Receiver API

SMS text messages are often used to verify phone numbers or send one-time-passwords (OTP) codes. Native smartphone apps can intercept, read, and react to these messages but web app users are forced to manually copy/paste or retype information.

The new SMS Receiver API allows web apps to read SMS messages addressed to them using specific formatting conventions in order to avoid manual user interaction, e.g.

Your OTP is: 123ABC
For: https://example.com/verify?otp=123ABC&hash=9B3FF1C2

Retrieval JavaScript:

if (navigator.sms) {

  try {
    let { content } = await navigator.sms.receive();
    console.log('SMS text:', content);
  } catch (e) {
    console.log('error', e);
  }

}

Miscellaneous updates

If you’re hungry for more, a number of minor and experimental features are also available:

    1. The default color for input and text area ::placeholder text has changed from #757575 to rgba(0, 0, 0, 0.54)
    2. Service worker scripts imported with importScripts() are now checked for updates even when the main service worker script has not been modified
    3. A registerProperty() function can be called from JavaScript to register typed and animatable custom CSS properties (part of the new Houdini API)
    4. WebAssembly modules can hold references to JavaScript and DOM objects. They can be passed as arguments, stored in locals, globals, or WebAssembly.Table objects
    5. A new WebHID (Human Interface Device) API supports input and output devices other than keyboards, mice, touchscreens, and gamepads. In essence, it permits low-level device-specific logic to be implemented in JavaScript without relying on browser support
    6. The XSS Auditor has been removed

Here be dragons!

It’s encouraging to see continued innovation on the Chrome browser despite its monopolistic market share.

While it’s tempting to jump in head first, many of the new features are experimental and could change radically, disappear, or never be implemented in other browsers. Experimentation is healthy, but be wary about gambling your reputation on Google’s whims!

 

Plug: , a DVR for web apps

LogRocket is a frontend application monitoring solution that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.

In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.

.
Craig Buckler Freelance UK IT consultant specialising in HTML5 webby stuff.

One Reply to “What’s new in Chrome 78”

Leave a Reply