大多数浏览器和
Developer App 均支持流媒体播放。
-
进一步了解声明式网页推送
了解声明式网页推送如何帮助你更可靠地发送通知。了解如何借鉴现有标准实现更高效、更透明的设计,同时保证与原始网页推送的向后兼容性。
章节
- 0:00 - Introduction
- 3:50 - Declarative Web Push
- 7:49 - Push subscriptions
- 9:53 - Declarative JSON format
- 11:09 - Service Worker support
资源
相关视频
WWDC25
WWDC22
-
搜索此视频…
My name is Brady Eidson, and I'm an engineer on the WebKit Architecture Team. I'm really excited to talk to you about recent advancements in Web Push notifications. Push notifications are a crucial part of the modern web, just like they're crucial to any modern platform.
We started building push notifications into Apple’s platforms back in 2009 with iPhone OS 3. We were early pioneers here but push notifications obviously belonged on all modern platforms. They were added to macOS, other desktop platforms, and other mobile platforms soon after. Almost overnight, apps could assume push notifications were built-in to the platform.
Early on we were continuously adjusting exactly how push worked for native apps to find the sweet spot for both developers and users. We knew from the start that push notifications belonged on the web, and we wanted to be deliberate in the details. We added Safari Push Notifications to Safari 7. Developers adopted Safari Push eagerly, and users engaged, so we knew we were on to something. Safari Push required tight integration with Apple's systems, so we couldn't standardize it in a way other browsers could implement. Of course, all browsers needed push notifications. The web standards community got busy working on Web Push and the first browser shipped it a year or two later.
In web standards this was an era of intense focus on JavaScript features. Original Web Push was designed to be a supremely flexible system, 100% driven by JavaScript code that you write. We take pride in squeezing out every drop of performance we can while running JavaScript, but as all software engineers know any code you have to write and maintain is more bug prone than writing none.
And even when executed in a JavaScript engine on the bleeding edge of efficiency, running any code is less efficient than doing nothing.
Another downside to this approach is privacy. Website data is a vector for tracking users as they browse, which is why Intelligent Tracking Prevention limits the lifetime of the JavaScript required for original Web Push.
With iOS, macOS, and Safari Push notifications, the push message itself contains a standardized description of the user visible notification. No application specific code needs to be developed or executed to display it.
Native apps don’t even need their code on the device to display a push notification. Apps that iOS has offloaded display their notifications just fine.
While adding original Web Push to our browsers we observed something interesting. Even with the flexibility offered by the standards, many websites send push messages in simple to parse JSON, and their Service Worker JavaScript does nothing more than translate it to the API call to show the notification. Given our long history with iOS, macOS, and Safari Push notifications, this made sense to us. And it gave us a pretty straightforward idea. If declaring the notification up front in JSON is a common case, we could evolve Web Push to meet you where you are.
By removing the step that relies on you writing any code, you get all the same benefits native apps have enjoyed since the beginning.
Declarative Web Push has ease-of-use, efficiency, and transparency baked in. Using it is as simple as sending your push messages in a standardized format and setting it up requires almost no code.
We designed it with the open web in mind, engaging the standards community along the way. It’s also designed to be backward compatible with browsers that don’t yet support it. Declarative Web Push is truly a progressive enhancement for the web. If you are already familiar with original Web Push, then the concepts you know still apply.
Since it builds on established standards, we’ll cover what’s new with declarative Web Push by reviewing parts of original Web Push along the way. Let’s start with a high level overview of original Web Push. It relies almost entirely on JavaScript in the form of an installed Service Worker. A Service Worker contains the code that handles “push ” events to display notifications.
Then you need a push subscription. It contains information your server needs to reach the user’s browser, such as the URL to use for sending a push message. In response to a user gesture, your JavaScript requests a push subscription, then sends it to your server for later use.
When it's time to send a notification, you use the URL in the subscription to send a push message. In WebKit browsers you’ll be sending it to the same Apple Push Notification Service that powers our native apps, but you don't need an Apple developer account to use these subscriptions.
The message makes its way to the browser, which looks up the responsible Service Worker and launches it. The browser dispatches a push event to that Service Worker, which includes all the data you sent in your push message.
The Service Worker parses the message and constructs a JavaScript call to the showNotification API, which displays the notification.
Later, when the user taps or clicks on that notification, the browser once again launches the appropriate Service Worker if it isn’t still running, and dispatches a notificationclick event to it. Your handler then has the job of doing something useful, which is almost always opening a window to a URL.
That’s how original Web Push works today. A majority of the steps described are handled by JavaScript that you need to write and the browser needs to run.
While declarative Web Push doesn’t completely eliminate JavaScript, it get’s us close. The only JavaScript you need with declarative Web Push is to get that push subscription, no longer needing a Service Worker.
Once you send a declarative push message, the browser receives it like before and parses it, looking for valid JSON.
It makes sure the JSON describes a valid user visible notification then displays it automatically.
The browser also knows how to automatically handle taps or clicks on the notification. We’ll cover how the browser knows what to do shortly but first back to the JavaScript required to get that push subscription. Let’s cover how that code looked before with original Web Push and then how it looks now with declarative Web Push.
This will look familiar to those of you who’ve used original Web Push before.
As I mentioned, original Web Push requires an installed Service Worker before going any further. Once you have your Service Worker registration, you can access its PushManager object in response to a user gesture to request a push subscription.
The code to get a push subscription with declarative Web Push is nearly the same as before, but since no Service Workers are required, PushManager is now also available on the window object.
And here’s the magic. If you’re using pure declarative Web Push, that’s all the code you have to write. Declarative Web Push defines a standard JSON format for push messages. Here is an example of a minimal valid message from our team’s critical infrastructure tool, the Browser Pets web app.
It includes a required entry describing a user visible notification.
That notification is required to have both the title text and a URL to be navigated to if the user taps or clicks the notification.
But this top entry is this magic value for a declarative push message. You must always have a web_push key with the value 8-0-3-0.
8030 is the original Internet Engineering Task Force RFC standard for web push messages, and we figured it’s extremely unlikely anybody would be including it.
Remember earlier we covered the flow of a declarative push message through the browser.
Looking for the magic key is part of that flow.
What happens if the browser attempts to parse JSON from the push message and fails? In that case it falls back to original Web Push, using a Service Worker to handle the message.
It also falls back to original Web Push if the JSON doesn’t have the magic key.
What if the push message contains JSON, and has the magic key, but it does not describe a valid notification? In that case, the browser simply does nothing, dropping the message on the floor. But if a push message makes it past all these checks, the browser displays the notification automatically.
A notification title and navigate URL are the minimum requirements for a valid notification. But if you have experience with original Web Push you know JavaScript has way more options when creating a notification. Declarative Web Push supports them all.
Here, we specify a body for the message, a notification tag, and we request that the platform play the default notification sound, if possible. These are just examples, anything supported by the W3C standard NotificationOptions dictionary is respected here.
There’s more. Application badges, for things like unread counts, tend to go hand-in-hand with notifications, so declarative push messages also support built-in updating of the app badge.
It’s a breath of fresh air just how many notifications you can now have the browser display automatically. But sometimes your needs are more specific and you can’t completely rely on the browser for everything.
We learned this lesson with native push on iOS and macOS, and apps using the UserNotifications framework have had this ability for awhile. While those push messages always describe a visible notification, the app can choose to refine it into something more useful.
Declarative Web Push supports this too, in the form of optional processing by a Service Worker. Why is this so important? It’s useful when you have extremely high standards for the accuracy of your notifications. For example, the Browser Pets server might notify a user that they have 7 unread messages, unaware that the user has already read 3 of them. JavaScript on the client device can update the notification to help the user.
Sometimes you mathematically cannot include the notification text. Users of Browser Pets expect world class end-to-end encryption when they send direct messages to each other, and a key on the client device is the only way to decode the notification. Let’s see how that looks. Here’s what the notification JSON looks like for a typical Browser Pets direct message.
The JSON contains the data that was encrypted on the senders device. Our user’s device has the key to decrypt this data and can do so using its optional Service Worker.
The JSON also includes an entry specifying that "mutable” is true. Most declarative push messages are handled automatically, but this entry tells the browser that this notification needs to be processed by the service worker.
This is the JavaScript that Browser Pets uses to handle decrypting direct messages.
We gave our Service Worker a push event handler, just like you would as a hard requirement with original Web Push. One new thing is that if the event being dispatched originates from a push specified to be mutable, the event now has a copy of the notification proposed by the declarative JSON.
Inspecting that notification is how we know it is meant to be a direct message, and how we can access the encrypted data.
Remember our flow chart for declarative Web Push? After validating the notification description, the browser looks for the "mutable” entry.
If it is missing, or false, the browser displays the notification automatically.
If it’s true, and if the Service Worker shows a replacement notification, then the browser uses the replacement instead of the plain text from the push message.
So if our Service Worker successfully decrypts the direct message and replaces the proposed notification, the browser will display this decrypted message.
But if it fails to decrypt the message and therefore fails to offer a replacement, the original plain text notification will be used instead.
The declarative notification will also be used in cases where the Service Worker cannot be launched perhaps because privacy features have removed it, or the device is otherwise under resource pressure. The way declarative Web Push uses its optional Service Worker JavaScript is exactly the same as how original Web Push requires Service Workers. And that leads us to possibly my favorite part. Let’s go over backward compatibility.
Today, most major browser engines support original Web Push and many websites already use it. While wide adoption of declarative Web Push would be better for everyone, we made sure it’d be easy for you to adopt while keeping your notifications working in all browsers. For many of you who already use original Web Push and do simple JSON parsing to display a notification, I’d wager the format of your push messages evolved piece by piece as your needs grew and got more involved. That’s certainly how Browser Pets developed over the years. Once the WebKit team got declarative Web Push working, we wanted Browser Pets to take advantage of it to deliver the most efficient and reliable notifications possible. But of course push has to continue working in all browsers. Let me go over how we updated it.
This Browser Pets notification JSON grew up organically over time.
At first, it just included title text for the notification.
Originally all notification clicks opened the main Browser Pets app, but then we added this clickURL entry to configure where the notification click might go.
Next, some engineers figured notification body text was important.
I’ll personally take the blame for the next change - it was my idea for notifications to play the system alert sound when possible.
The next engineer acknowledged that we were basically configuring our notifications with a web standard NotificationOptions dictionary, and decided to put that in code explicitly. Of course, they didn’t go back and update previous options.
This ad-hoc JSON format has all the bits and pieces that make up an API call to showNotification, just with different names and structure.
Reorganizing it to match the declarative standard format was trivial. Renaming each property to their standard name found in a NotificationOptions dictionary was also easy.
Once we added the magic key to tell the browser this was a declarative push message, we got automatic notifications in newer browsers that support them! Returning to that ad-hoc JSON. With original Web Push, the push message is only part of the story. Your Service Worker needs to do something with it. Here’s the original Browser Pets Service Worker. Each argument we crammed into that JSON had to be pulled out by name and we had to build up a NotificationOptions dictionary for the eventual call to showNotification.
Now remember what the declarative push message looks like.
By design, the critical member of a declarative message that describes the notification is itself a valid NotificationOptions dictionary. So once we’ve reformatted our push message to be valid declarative JSON, rewriting our service worker to handle it is super straightforward.
We pull out the “notification” member from the JSON extract the title and pass them in to showNotification as-is.
Once you’ve refactored your push message JSON and your Service Worker’s push event handler, your Web Push messages take advantage of every browser.
Browsers that support declarative Web Push handle them reliably and efficiently.
And browsers that don’t yet support declarative Web Push handle them through JavaScript you write, just like all original Web Push messages. We’re excited about declarative Web Push and hope it can work for everyone. Give it a shot in Safari 18.5 and later on macOS, or web apps saved to the home screen on iOS 18.4 and iPadOS 18.4 and later. If you’re supporting Web Push in your app for the first time, you can opt-in to the declarative format from day 1. If you already use Web Push, there’s no better time to start the transition. And moving away from the legacy Safari Push notification format, which is itself declarative, has never been easier. As you adopt it, keep the resources associated with this session handy to give feedback to the web standards community or to the WebKit project.
You can also check out these sessions for details on how our browsers support Web Push in general, as well as more about what’s new in Safari and WebKit this year.
Thanks for watching!
-
-
- 0:00 - Introduction
Push notifications, pioneered by Apple in 2009 for iPhone OS, is now standard feature across mobile and desktop platforms. Safari Push Notifications were introduced in Safari 7 but were platform-specific. The web standards community then developed Web Push, which was initially fully JavaScript-driven but posed performance, privacy, and maintenance issues. Building on observations of common usage patterns, the team is evolving Web Push to allow notifications to be declared directly in JSON, eliminating the need for JavaScript code execution, enhancing efficiency, privacy, and user experience, aligning Web Push more closely with the benefits of native app notifications.
- 3:50 - Declarative Web Push
Declarative Web Push is a user-friendly and efficient enhancement to the original Web Push system. It simplifies the process by utilizing a standardized format for push messages, requiring no code. Designed with the open web in mind, it is backward compatible and builds on established standards. The original Web Push system heavily relies on JavaScript and Service Workers to handle push events and display notifications. In contrast, Declarative Web Push significantly reduces JavaScript dependency. Now, JavaScript is only needed to obtain a push subscription; the browser then automatically handles displaying notifications and user interactions upon taps or clicks.
- 7:49 - Push subscriptions
With declarative Web Push, the code to get a push subscription is nearly the same, but no service workers are required, as you can access the PushManager on the window object. Declarative Web Push uses a standard JSON format using the 'web_push' key for the browser to automatically display a notification.
- 9:53 - Declarative JSON format
Declarative Web Push builds on the basics of a notification title and URL, allowing for full W3C standard options like message body, tags, sounds, and app badge updates. It automates many browser notifications but also provides flexibility for more specific needs, akin to native push on iOS and macOS.
- 11:09 - Service Worker support
Declarative Web Push enhances the original Web Push system by handling notifications without code, but also allowing optional processing of notifications through Service Workers. This is particularly useful for ensuring accuracy and maintaining privacy, for example, in applications like reading messages, or decrypt end-to-end encrypted direct messages. The notification JSON can include a 'mutable' flag, indicating that the notification needs Service Worker processing. If the Service Worker successfully decrypts and replaces the notification, the browser displays the decrypted message. If not, the original plain-text notification is used. This approach ensures backward compatibility with existing Web Push implementations while providing more efficient and reliable notifications in newer browsers that support declarative Web Push.