Frameworks • iOS, macOS, watchOS • 36:04
Explore the latest features and improvements for Safari and WebKit. We’ll walk you through updated web APIs, CSS and media features, JavaScript syntax, and more to help you build great experiences for people when they use your website, home screen web apps, or embedded WebKit views.
Speaker: Jon Davis
Downloads from Apple
Transcript
Hello and welcome to WWDC. Hello, I'm Jon Davis, Web Technologies Evangelist for the Safari and WebKit teams. I'm so excited to get to tell you about all of the new features and improvements for web developers this year. If you develop websites, web apps saved to the Home Screen or web content used in apps, and want to learn about all of the latest technologies available in Safari and WebKit, this session is for you. In this session, I'll give you a tour of the new features and enhancements in WebKit and shipping in Safari 13.1 for macOS, Safari on iOS and iPadOS 13.4 and coming to Safari 14 on macOS, iOS and iPadOS.
But first, there's some really great news I wanna share up front. We made a really big effort this year to improve Safari's interoperability with other browsers. One way to measure that is web platform tests. It's a set of tests used by browser makers to ensure interoperability so your web content operates the way you expect across browsers.
So I'm pleased to announce improved interoperability for service workers, XHR and Fetch, pointer events, CSS, SVG, WebAssembly and many more areas. Safari passes 140,000 new interoperability test cases this year, and you can look forward to continued progress in this area. But there's so much more to talk about this year. In this session, I'm going to go over performance improvements, lots of new web API, CSS updates, media enhancements, including some great image updates, new JavaScript features and finally, new platform integration capabilities. So let's get started with performance, and specifically browsing performance.
Page load performance is foundational to our browsing experience feeling fast, and I'm pleased to report Safari 14 is 13% faster clicking a link to an unvisited site, and up to 42% faster clicking a link for a recently visited web page. Typing a URL into the Search and Address bar for a recently visited web page is 52% faster.
We improved instant back by caching up to 34% more pages. PDFs show the first page 60 times faster while downloading. And outside of page load performance, closing unresponsive tabs is down from three-and-a-half seconds to just 50 milliseconds. All of these improvements help users and developers have a faster browsing experience in Safari.
And there's performance improvements for developers too. CPU usage while scrolling is three times less. It's buttery smooth with zero dropped frames. IndexedDB operations are up to ten times faster. Reduced overhead makes for-of loops up to five times faster, based on microbenchmarks. Promises are twice as fast in the JetStream 2 benchmark's async-fs test, and optimized JavaScript delete operations are up to 12 times faster. Safari and WebKit are faster than ever. But now, I'm going to show you the new web API added in WebKit and available in Safari.
First up is the Web Animations API. It's long-awaited and new in Safari 13.1. It's an API available in JavaScript to directly create and control the playback of CSS animations and transitions. You no longer need to manipulate element properties. And you can query the animations on the page, seek directly to a specific time in the animation playback cycle or even change the speed and direction of playback.
So I've been experimenting with a loading animation of the WebKit logo for an internal website where my colleagues enjoy discussing their pets. And after it's animated in, the compass needle spins and it's a really fun element. So I'd like to let folks interact with it a bit by clicking on the logo to give the needle another spin. And with the Web Animations API it's really easy.
So in the logo's click handler, we use the element.animate method. It takes a KeyframeEffect parameter that allows us to set up the keyframes for the animation, a nice easing function so the needle starts spinning quickly with a softer ending, and then a reasonable duration in milliseconds. And here it is. And clicking the logo keeps the needle spinning.
That's more fun than I thought it'd be. And Web Inspector's Graphics tab now shows you the animation instances... including the animations created each time I click the logo. It also visualizes the easing curves. And to help with timing, it gives you a perspective of the animation delay compared to its duration. There are lots of updates to Web Inspector you can learn about in the "What's New in Web Inspector" session available in your Developer app.
So that's the Web Animations API. JavaScript control of animations with all of the power and efficiency of CSS animations and transitions. Next in our tour is ResizeObserver. It's newly available with the release of Safari 13.1 earlier this year. It's a JavaScript API that reports element size changes. It allows elements to respond to the size changes of other elements, not just the viewport. With ResizeObserver, your content can react to elements that change their size both when the viewport changes, like when the window gets resized, but more importantly, when other changes to size occur, like changing the display property or when new child elements are appended.
My colleagues on the WebKit team love discussing their pets, so I've been maintaining an internal website where they can share pictures and comment on them. And, of course, it uses responsive design so that when you resize the window and things start to get a little cramped, the controls shrink to just show the icon and save space.
But some folks said they wanted a flexible editor because they like having the extra space while commenting, and you can see it resizes well for the window, but it doesn't work when resizing the editor. This hasn't been easily achieved before, but ResizeObserver is a great tool for this because it can detect when the size of the container changes and react. Let me show you what I've been working on.
So to address this, I'll create a new ResizeObserver in the site's JavaScript that detects when the container's width goes below a certain size, then toggle a CSS class on the container. The style rules for our formatting buttons can pick that up and hide the label to use less space and collapse the size of the buttons so they always fit. To get it working, I just pass the container element to the Observer method of my newly constructed ResizeObserver. Let's check it out.
With the code in place, resizing the editor causes the buttons to hide the labels and resize the way you'd expect. That's ResizeObserver. If you wanna learn more, there's a blog post on the WebKit blog with more details. Now, another feature I need to get working on the WebKittens website is the Paste button, and I've got just the thing, the Async Clipboard API. It's also new this year and available in Safari 13.1. You can read data from the system clipboard for paste operations or write data to the clipboard for copying. It's asynchronous, to avoid blocking the page while you're accessing the clipboard.
And there's no need to fake a selection or have element focus to copy data into it. It supports multiple items and item types like images and rich formatted text, but needs a secure context over HTTPS and calls must be invoked in response to user interaction. Now, if you're working with just plain text, it has shortcut methods to make it even easier. Copying plain text is as easy as using the clipboard.writeText method to write a string of text. And pasting plain text uses the clipboard.readText method. But for the WebKittens website, the team wants rich HTML-formatted text when pasting.
Inside the click handler, the clipboard.read method is called asynchronously to get an array of clipboardItems back. The clipboardItems are iterated to find the HTML data. The data gets returned as a blob object. Then, FileReader is used to get the HTML data back, which is collected and appended to the editor.
I copied a comment from another post earlier to test with, so I'll click the Paste button and post it. And there you have it, a functional Paste button that handles rich text. The Async Clipboard API is powerful and this just scratched the surface. You can learn more about it on the WebKit blog.
Now, if you're a developer of a library or framework, this next news is for you. Safari 13.1 now supports the EventTarget constructor. EventTarget is used by objects that can receive events. For example, DOM elements extend EventTarget, but now your own objects can too, without all the extra element behaviors.
Library authors can use native event functionality to create their own object interface for dispatching custom events for non-DOM objects. While we're talking about library developers, a lot of libraries are simply providing a custom component for web authors to implement, so that leads us to an update on web components.
We've had support for web components in Safari for a long while now and they keep becoming more and more powerful. It's actually another feature I took advantage of on the WebKittens website. Everything from the posts to the comments and even the formatting buttons are implemented as web components. But for a simple example, let's look specifically at the formatting buttons.
Some simple template markup is used to set up the component as a custom element. The id attribute is used to reference this template in JavaScript. Then, in JavaScript, it's registered as a custom element. The id attribute value is repurposed to serve as the custom element hook. Our custom element class extends a generic HTMLElement and in the constructor, clones the template content to modify the template fragment with our text label and icon. It then appends our modified DOM fragment to the shadowRoot of the custom element. Then, the page markup can create those elements using the custom element's registered name as the tag name.
Each of the format buttons can be customized for bold, italic, underline and so on. Now, as a component author, you provide a generic component that can get used in many ways, so you wanna give the page author some control over how these elements are styled. In this case, as a component author, we don't know what kind of button each one will end up being.
In the example, component styling handles the layout of a larger text icon to the left of the button label, but in order to give the bold button's "B" icon a bold style, and an italic style for the "I" icon, the page author, who knows what kind of button they're implementing, needs to be able to customize that part of the component.
With Safari 13.1 released this spring they can, using CSS Shadow Parts. It allows web component authors to specifically expose parts of their components to content authors to style with their own CSS. You don't need to know all of the underlying markup structure of the component to style it. Just the parts of the component the author exposed through the part attribute.
Component layout is protected and content authors can customize the components to fit the use case or better match the style of their website. Looking back at our example, this was the original template markup. By adding the part attribute to the elements inside the component, they're now exposed to the page's CSS.
Now, the page author that's implementing the buttons can use the part pseudo-element selector and easily decorate the buttons to provide an extra visual hint about their function. So this turns into this. And that's CSS Shadow Parts for web components. Speaking of visual hints, WebKit added support for another visual hint. The HTML enterkeyhint attribute. It's supported on Safari, on iOS 13.4 and iPadOS. It allows you to declare an action label for the Enter key on virtual keyboards of a touchscreen device.
You can set the label to give your users a hint about what action the Enter key will take. Instead of just Enter, it could be Done, or Go, or Send, for example. Before I wrap up the new web API, there's one more API to mention... the Web Authentication API. It supports logging into websites beyond usernames and passwords and it was introduced in Safari 13 and Safari on iOS 13.3 with support for hardware security keys.
And with the latest Safari, WebKit has added support for Touch ID and Face ID in Safari on macOS, iOS and iPadOS. You can learn all about the security and convenience of implementing it for your users by watching the "Face ID and Touch ID on the Web" session in the Developer app.
And that's a look at the new Web API in Safari this year. Web Animations, ResizeObserver, the Async Clipboard API, the EventTarget constructor, CSS Shadow Parts, HTML enterkeyhint and Web Authentication. I can't wait to see what you do with these new capabilities. But we're not done yet. Let's take a look at several CSS improvements that give content authors more fine-grained control over styles and layout.
This year, WebKit added support for system font families. They work in WebKit across all of Apple's platforms. They each map to a system-appropriate font. The system-ui font family is a generic alias for ui-sans-serif and on the system it maps to San Francisco... ui-serif uses the New York font family... ui-monospace uses SF Mono... and ui-rounded uses SF Rounded.
They're useful when developing a web app that you wanna make feel more familiar to the system. And the different font families allow you to create an easily identifiable difference between content and user interface, such as on the WebKittens website. It uses ui-serif for the content areas... and ui-sans-serif for the user interface when adding a comment. So beautiful new font families for your web apps.
Another CSS feature that can help your content layout is support for "line-break: anywhere." It breaks to a new line at any opportunity before the content overflows. This can be particularly helpful with long words that can overflow narrow containers, especially technical jargon, like code, where hyphenation might change the intended meaning of the word.
And it can protect your content from unexpected layout issues. The simplest way to understand it is to see the behavior of the default line-break rule. WebKit uses a default line-break heuristic that's based on language-specific rules, while taking into account other CSS that might apply. With roman-based written languages, the line-break heuristic hyphenates the text when it can, but take a look at the first word on this page from the Web Inspector Command Line API Reference.
The long queryInstances syntax doesn't break at all. It's breaking right before the long word, making a blank line after the bullet. Then, it still overflows the container and the viewport. "Line-break: anywhere" makes it possible to fix this. With "line-break: anywhere," it breaks up the character just before the overflow, making it possible to see all of the content without breaking the layout. Now it's possible to see the entire line.
Next up is another powerful CSS tool. The "is" pseudo-selector. It's newly supported in Safari 14. It matches a list of selectors just like the "matches" pseudo-selector. In fact, "is" aliases our "matches" pseudo-selector behavior that's been part of Safari for years. The matching element gets the specificity of the most specific selector. It's really useful for avoiding repetitive selectors. Here's an example.
Here, a 3em top margin is added to all of the headings. Then, this rule removes the top margin when a heading is immediately followed by a heading of the next level down. But, of course, if this is used in a content management system, page authors may not adhere to strict rules of an h1 followed by an h2.
They're not technically prevented from using an h1 followed by an h3, so this isn't enough to cover all of those cases. To do that, you'd need a really repetitive selector. Like this. That's pretty awful-looking. But with "is," we can simplify writing all of that out. And it becomes this. That's so much nicer. To go along with "is," WebKit also supports the "where" pseudo-selector.
It works the same way as "is" in that it matches a list of selectors, but the big difference is that the CSS specificity of any matching element is always zero. So it can act as a kind of specificity reset. Here's another example, and I'll start by comparing "is" first.
Looking at this example, the "is" selects an intro class, pullquote or element with a hero id and styles the paragraph tag that immediately follows it to use uppercase text and give it an eye-grabbing look. Later in the styles, the page author is trying to specifically override the heading levels two through six followed by a paragraph to use normal text. Seems like they only want this to work for paragraphs following level one headings. But using "is" means that it won't work as expected. This is where the "where" pseudo-selector comes in.
Using "where" instead makes this possible. Now, the elements matched by "where" are reset to a specificity level of zero, making the follow-up rules able to override as expected. From CSS, we move on to media. But included in media is a fair number of image updates as well. And I'm pleased to announce support for an entirely new image format... WebP images. WebP is an open-source image format that provides smaller file sizes and lots of advanced bells and whistles. It supports a lossy format comparable to JPEG and a lossless format like PNG. It even supports transparency and animation across both.
In your markup, you can use the picture element to add WebP images with a fallback. And on the server side, you can look at the Accept header. But a big reason web developers are excited for this format is the file size savings. This sample JPEG encoded at 80% quality is 5.1 megabytes, but the WebP lossy encoding at the same quality settings gives us a 41% file savings with visual quality that's nearly the same as a JPEG.
This high resolution PNG weighs in at 817 kilobytes, but the lossless WebP encoding preserves the transparency and saves us 33%. WebP image support is available in Safari 14 and Safari for iOS 14. While we're talking about images, there are a couple of new default image behaviors in WebKit. The first is a change that will improve the way your web pages load.
We've all seen what happens when we load a web page where the images load in and cause the layout to jump around. I'm going to show you how easy it is to fix this with WebKit's new behavior for calculating the default image aspect ratio. In Safari 13.1 and in Safari on iOS 13.4, WebKit now calculates the image aspect ratio from an image tag's width and height attributes. All you have to do is make sure to add the width and height attributes to your image tags. Let's see what happens when the attributes are added.
There's no jumping around at all. The space is reserved for the image and it just loads right in. Beautiful. The other new default behavior is for image orientation. We've supported respecting EXIF image orientation on iOS for a long time. This update aligns our support on iOS and macOS through the standard image-orientation: from-image value. The from-image value tells Safari to respect the image-orientation flag encoded into images that support EXIF data.
This JPEG image is encoded with an EXIF orientation flag of six, meaning the camera was rotated 90 degrees counterclockwise. And now you can override this default by setting image-orientation value to "none," to display the image directly as encoded, without rotation correction. From images, we move on to video.
With system support for High Dynamic Range videos and web content with Safari 14 on macOS. You can use media queries to detect High Dynamic Range display support. In CSS, you can query support with "dynamic-range: high" like this. Or you can use the window's matchMedia method in JavaScript so you can deliver progressively enhanced content to users with HDR displays.
Continuing with video updates, WebKit has added support for the Remote Playback API. We've always had an API for doing AirPlay before, but the Remote Playback API is a standards-based way of adding remote playback of audio or video to your custom web-based media player and sending it to a variety of other remote playback devices, like connected TVs, audio-only speakers and any AirPlay-capable devices. To use it, you'll set up a custom button on your video player controls and in response to user interaction, call the videoElement's remote.prompt method. Then, you can handle updating remote playback state in your callback handler. It's really that easy.
Then, on your device, users can tap on the control to get a menu of available remote playback devices. When selected, the video is sent to that device. Supporting the Remote Playback API gives your users the flexibility to enjoy media on all of their devices. And another way to help users enjoy your media is the picture-in-picture API.
Adding a picture-in-picture control to your web player allows users to play videos in a pop-out window while they continue doing other tasks. Like remote playback, WebKit has supported picture-in-picture for a while, but the standards-based picture-in-picture API is now available and it works across iOS, iPadOS and macOS. Similar to using the Remote Playback API, you setup a custom control element and call the videoElement's requestPictureInPicture method in response to user interaction. That's it.
Then your users can enjoy videos in picture-in-picture mode on their device while doing other tasks. In other news related to video, Safari 14 includes support for timed metadata in HLS. It's new in Safari 14. And this is metadata synchronized to the media time stamps in the video stream. It can be used to provide program information like episode details or live sports data like inning boundaries or scores. There are two approaches supported.
The HLS #EXT-X-DATERANGE tag is available in the DataCue and carries the metadata to the HLS Media Playlists themselves. The advantages of using these tags is their immediacy and scope. All metadata in Media Playlists is available to the video player as soon as it's loaded. It doesn't require waiting for the specific segment to load or for the playhead to pass over it.
And event message boxes are now available in fragmented MP4s. These are compatible with ID3 storage and other formats, like MPEG-2 transport streams, to carry the same metadata in fragmented MP4 containers. This is especially important for codecs like HEVC and Dolby Atmos, which Apple platforms only recognize inside fragmented MP4s.
The last update is an enhancement for developers of video sites that provide subtitles and captioning. This is a short, but sweet update. It's an enhancement to TextTrackCue that allows you to use your own captions format, but use native caption rendering. Developers can use existing caption formats without needing to convert them all.
And because the user agent is responsible for displaying the captions, they get first-class accessibility treatment. Plus, they render in both full-screen and picture-in-picture without any extra work. Those are our media updates, with support for WebP images, new defaults for image aspect ratio and orientation, Mac HDR video, timed metadata in HLS, Remote Playback and picture-in-picture APIs with natively rendered subtitles and captions.
Now it's time for new JavaScript features. Starting with BigInt. BigInts are a new data type in JavaScript. They're integers that are arbitrarily large and most commonly used in cryptography, but are useful wherever you need numbers larger than the MAX_SAFE_INTEGER in JavaScript. But there are a few things to keep in mind.
You can't use number operations or mix operations with the regular number data type. You also can't use JSON.stringify to serialize a BigInt for backwards compatibility reasons. You'll need to build your own serialization functionality to ensure the decoding process matches your serialization format. And be aware that when using the division operator, BigInts will drop any decimal values. That's BigInt available in Safari 14. But WebKit also supports some powerful new operators to help with null or undefined values.
The nullish coalescing operator works like other logical operators, but it checks for existence. Let's look at a quick example. So I have a Person class where the constructor takes a firstName, lastName and age argument. The nullish coalescing operator is used to check if an argument's value is provided. If it's null or undefined, the result of the right-hand side of the operator is used instead.
Here, without any arguments, the right-hand side defaults, as I like to think of them, are used. But passing Boolean values, regardless of what they are, pass the existence check and are set as the properties on the Person object. Passing a filled in string or empty string, or even zero for the age still evaluates to set the fields to the passed-in arguments.
And finally, passing the full data sets the properties. And that's nullish coalescing. Building on nullish coalescing, and also new this year, is optional chaining. It's a new JavaScript syntax that gives you a shortcut for property access. And it even works for indexes and methods too. Take a look at this example.
Here, we add a name property to include both the first and last name. And when a Person is registered, we want to see the first name. This is how you might typically add some guards to make sure you can access the firstName property. Passing no arguments to the Person when calling "register" gives us an undefined result.
And passing strings for the firstName and lastName gives us the expected firstName. But with optional chaining, we can replace this approach with new syntax that uses the optional chaining operator. And it works in the exact same way. It also works with indexes, like checking for the first entry in an array of a person's children.
Using optional chaining here avoids the TypeError and it even works for methods. Trying to call an undeclared method triggers an error, but with optional chaining you can avoid the error. So that's optional chaining. Sticking with the operators theme, there are even more newly available operators in Safari 14.
Logical assignment operators. And they come in three flavors. Logical and assignment, logical or assignment... plus a nullish assignment operator. Logical assignment operators are nice in that they only evaluate the left-hand side expression once. And it isn't as destructive in that it doesn't always reassign. Take this example using the nullish coalescing operator where it always reassigns innerHTML.
With a nullish assignment operator, it only destructively assigns innerHTML if it is null or undefined. Switching gears back to objects for a moment, WebKit in Safari 14 includes support for public class fields. Public class fields are a new syntax to declare member properties that are part of the object, regardless of them being set up in the constructor. Looking at the Person example earlier, they could be set up like this.
Now, children, for example, will still be available when a new Person object is created, even though it isn't set in the constructor. By not having it in the constructor, you can focus on the logic instead of worrying if variables are set as public class fields are guaranteed to always be added. And a final utility in JavaScript to look at is String replaceAll.
Finally, String replaceAll is new in Safari 13.1 and it does what it promises, replacing all instances of a string. Previously, the String replace method would only replace the first occurrence of the string. You'd have to iterate over the words in the string or use a global regular expression. With replaceAll, you can replace all the instances of the string. And those are the powerful new JavaScript features available in Safari this year. BigInt, nullish coalescing, optional chaining, logical assignment operators, public class fields and String replaceAll.
That's our JavaScript updates. And finally, I'm going to share a few exciting platform integration capabilities new this year. First up is AR Quick Look on iOS. These are experiences launched from Safari that can be customized with web technologies. And new with iOS 13.3, these experiences can include a banner for users to buy products.
You can customize individual elements of the banner or provide a completely custom banner with a simple HTML page. To learn more, I encourage you to check out the "Shop Online with AR Quick Look" session in the Developer app. Another platform technology in Safari updated this year is Apple Pay.
Apple Pay on the web has been updated to add new button types with custom rounded corners and the ability to request redacted billing details. This is great for merchants that calculate tax based on a customer's location, but have no use for the shipping address. To learn more, see the "What's New in Wallet and Apple Pay" session in the Developer app.
Finally, another experience new this year is App Clips. It gives users a focused, fast and frictionless experience without waiting for downloading and installing an entire app. On your website, you can let users know that an App Clip interaction is available by adding the apple-itunes meta tag to your website's HTML and include your AppStoreID and the new app-clip-bundle-id parameter to add a banner to your website.
You can learn more about App Clips by watching the "Explore App Clips" session in the Developer app. That wraps up our platform integration with customizable AR Quick Look, Apple Pay updates and the all-new App Clips experience. And it also wraps up our tour of the new features and improvements of Safari and WebKit.
There's a whole lot new in Safari this year powered by changes in WebKit and I encourage you to try these features out and share your feedback. Now is the perfect time to test it. And we'd love to hear how it goes, especially if you run into bugs. For Web API, CSS or JavaScript bugs, you can file issues on the WebKit bug tracker at bugs.webkit.org. For Safari bugs or issues specific to iOS, Home Screen web apps or Apple platform integration features, you can use Feedback Assistant.
If you wanna stay on the leading edge of what's coming, you should download and use Safari Technology Preview. It's a separate version of Safari that works right alongside of Safari and it's shipped every two weeks with a sneak peek of new and experimental features, as well as new Web Inspector tools.
So as a web developer, you can be using the latest developer tools every two weeks. You can also stay informed by keeping tabs on the WebKit website at webkit.org. It features blog posts, Safari Technology Preview release notes and a fantastic library of reference guides for using Web Inspector.
You can also follow WebKit on Twitter for new announcements about the WebKit project along with tips and tricks for Web Inspector. And check out the links related to this session, including "Safari Web Extensions," "What's New in Web Inspector" and more web technologies. Thanks for joining me, and enjoy WWDC.