There is a new term in 2016: Progressive Web Application (PWA), an "umbrella" term for responsive design, independent connectivity, novelty, security, explorable, recustomizable, and installable Flexible, linkable applications/websites with native application-like interactivity. Again, we all need to learn how to deal with the whole PWA concept, we need to have more discussions and exchanges of ideas, and figure out what makes our websites more sensible – let’s not repeat these mistakes when we start with responsive web design.
What is a Progressive Web Application
A Progressive Web Application (PWA) is essentially no different from an ordinary website - it is also composed of HTML, CSS and JavaScript, and lives in the browser middle. What sets a PWA apart from a normal website is a list of 10 core concepts that it needs to meet. Here’s the list taken directly from the Google Developers website:
Security – Served over HTTPS to prevent network snooping and ensure content is not tampered with.
Progressive – can be used by every user, no matter what browser the user uses, because it is always based on the principle of progressive enhancement
Responsive – adaptable to any environment: desktop computers, smartphones Cell phone, tablet, or other device.
Does not rely on network connection - enhanced with service workers, can work offline or on low-quality networks
Native application - has native application-like interaction and navigation to users like native applications experience because it is built on the app shell model.
Continuous updates – Benefiting from the service worker’s update process, applications can always stay updated.
Discoverable – Identifiable as an “application” thanks to W3C manifests metadata and service worker registration, allowing search engines to find web applications.
Revisitable – Make it easy for users to visit again with features like push notifications.
Installable – Allows users to keep apps that are useful to them on their home screen without going through the App Store.
Linkable – Applications can be easily shared via URL and can be run without complicated installation.
Following these guidelines will ensure that your app runs well not only when viewed in a browser, but also when launched solely from the home screen shortcut. You may find the wording chosen by Google quite confusing, but don’t worry, we’ll explain the rules one by one in this tutorial.
What Progressive Web Apps Are Not
The concept of PWA should not be confused with the following concepts:
Hybrid app based on Cordova
React Native
NativeScript
Electron and NW.js
All the previously mentioned technologies package HTML applications into executable files, such as .apk, .exe, etc., and then must be downloaded from Download them from the respective app stores and install them on the user's device.
PWA does not require installation and is still not available in the Google Play or iTunes app stores. To download a PWA, just visit its website and save it as a shortcut to your home screen. Developing and maintaining separate versions for iOS and Android is no longer a problem, but browser support needs to be considered.
1. Security
Most progressive web applications use native APIs and service workers, technologies that handle sensitive data and need to be handled with caution. This is why every PWA is accessed over an HTTPS connection.
If you don't have a server with an SSL certificate, the easiest way to run your project in a secure environment is through GitHub Pages or a similar service. All Github repositories can be hosted directly over HTTPS, and both GitHub and GitHub Pages are free for public repositories.
If you are just testing on the local server, you can also try Ngrok. It is a small tool that can establish a secure channel between any currently running localhost and a public URL. Ngrok is free and available on Windows, Mac and Linux systems.
2. Progressive
Essentially, progressive means that the PWA should use widely supported web technologies and run equally on as many browsers as possible. As we all know, in the world of web development, this is nearly impossible, but there are still things we can do to reach a larger user base.
For example, in the PhotoBooth application, we use the getUserMedia() API to access the hardware camera on a device. Its support on different browsers is very inconsistent - Safari doesn't support it at all, and browsers that do support it require a prefix, and usage varies.
To ensure that more people can use our application, we cover all prefixes:
navigator.getMedia = ( navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia );
If all prefixes fail, show an error:
if (!navigator.getMedia) { displayErrorMessage("你的浏览器不支持 navigator.getUserMedia 接口。"); }else { // 使用 Camera API }
Where possible, fallbacks and polyfills should be provided. The same principle applies to CSS and HTML code.
3. Responsive
Apps should look good on all devices, regardless of screen size. The UI of our application is quite simple, so we only use two media queries to control font size, padding, margin, etc.
Don’t be afraid to use CSS libraries and frameworks like Bootstrap. They make working with form grids, typography, and general responsiveness easy.
4. Independent of network connection
This is a very important point. Using service workers allows applications to run even without an Internet connection.
Some applications can be only partially cached: the UI is cached and available offline, and dynamic content still requires access to the server.
Some apps, like our PhotoBooth demo app, can be fully cached. All source code and resources will be saved locally, and the application will run exactly the same way offline and online. Here is the code that makes this magic happen:
This is an oversimplification of Service Worker and should be used with caution in commercial projects.
First you need to create a service worker JavaScript file and define the logic behind it.
sw.js
// 安装 service worker. this.addEventListener('install', function(event) { event.waitUntil( caches.open('v1').then(function(cache) { // 如果这些资源中有任何资源不能保存,缓存就会失败 return cache.addAll([ // 路径是相对于缓存来源,而不是应用程序的目录。 '/pwa-photobooth/', '/pwa-photobooth/index.html', '/pwa-photobooth/assets/css/styles.css', '/pwa-photobooth/assets/fonts/MaterialIcons-Regular.woff2', '/pwa-photobooth/assets/js/script.js', '/pwa-photobooth/assets/icons/ic-face.png', '/pwa-photobooth/assets/icons/ic-face-large.png', '/pwa-photobooth/manifest.json' ]) .then(function() { console.log('成功! App 离线可用!'); }) }) ); }); // 定义一个资源被请求时候会发生什么 // 对于我们的应用,我们以缓存优先的方式 self.addEventListener('fetch', function(event) { event.respondWith( // 试着从缓存中获取. caches.match(event.request) .then(function(response) { // 如果资源没有存储在缓存中,就回退到网络 return response || fetch(event.request); }) ); });
Then we need to link the service worker to HTML.
index.html
// 注册 Service Worker. if ('serviceWorker' in navigator) { // 路径是相对于缓存来源,而不是应用程序的目录. navigator.serviceWorker.register('/pwa-photobooth/sw.js') .then(function(reg) { console.log('Registration succeeded. Scope is ' + reg.scope); }) .catch(function(error) { console.error('Registration failed with ' + error); }); }
Now, all files in the project will be saved in the user's browser. All JavaScript variables and objects should also be stored in localStorage or IndexDB whenever possible.
5. Class native reference
When creating a PWA, it is recommended to follow a design concept called an application shell architecture. It sounds complicated, but it actually boils down to this: Applications are divided into two main components: shell and content.
The shell contains all static UI elements, such as titles, menus, drawers, etc. When caching the application, the shell should always be saved on the device because we want it to be always available. This way, when users without an Internet connection open the app, they won't see a blank screen or a running dinosaur - instead they'll see the cached app interface and appropriate error messages.
内容驻留在外壳内。它也可以被缓存,但是没有必要这样做,因为内容通常是动态的,会频繁发生改变,并且每个页面加载时都可能是不同的。
6. 持续更新
一旦被缓存了,PWA 会总是从本地存储加载。不过,如果以任何方式修改了 service workersw.js,那么在下一个页面加载时,新版本就会被下载和安装。
this.addEventListener('install', function(event) { event.waitUntil( caches.open('v1.0.1').then(function(cache) { // ... }) ); });
通过使用 service worker 更新,我们可以重新下载资源,删除旧缓存,或者彻底修改 service worker 逻辑。你可以从这篇 Google 开发者文章中,学到更多有关 SW 更新过程的知识。
7. 可发现
通过给应用程序添加一个 Web Manifest,可以提供有关应用程序的各种信息,并且可以修改应用程序在用户设备上的显示方式。它允许应用程序被带自定义图标的方式保存到主屏幕上,在一个单独的浏览器窗口中启动,以及很多其它很酷的东西。
Web Manifest 是以一个简单 JSON 文件的形式出现:
manifest.json
{ "name": "Progressive Web App: PhotoBooth", "short_name": "PhotoBooth", "description": "Simple Progressive Web App for taking selfies.", "icons": [{ "src": "assets/icons/ic-face.png", "type": "image/png", "sizes": "72x72" }, { "src": "assets/icons/ic-face-large.png", "type": "image/png", "sizes": "144x144 256x256" }], "start_url": "index.html", "display": "standalone", "background_color": "#fff", "theme_color": "#fff", "orientation": "portrait" }
大多数属性是自解释的,所以我们只讲讲较为重要的一些属性。要查看完整的 Web manifest 格式,以及所有可用的字段,请到这里。
Shortname – 这是应用保存到主屏幕上时的名称。
Icons – 不同分辨率的图标数组。
Display – 定义应用打开的方式。我们选择的是独立(standalone),所以启动 PhoneBooth 时,会以全屏窗口出现,没有浏览器导航栏或者菜单。它还会被看作为多任务中的一个单独的应用。
要注册 Manifest 文件,必须把它链接到 HTML 中:
Safari 还不支持 Web Manifest 标准,但是我们可以用如下的苹果特定的 meta 标记,定义类原生应用的行为:
8. 可再次访问
通知推送不再只限于原生应用。多亏了 service worker 和 Push API,Web 应用程序也可以发送消息给 Android 通知栏。并不是所有应用都可以从这个功能受益,但是当正确使用此功能时,通知确实可以帮助吸引用户。
这个主题已经超出了本教程的范围,因为推送很复杂,值得用一个完整的课程讲解。如果你依然想在你的 Web 应用中实现通知推送,这里有一些最好的学习资源:
Google 开发者网站上的《推送通知:及时、相关和准确》 – 这里.
Google 开发者网站上的《开放 Web 上的推送通知 – 这里.
MDN 上的《使用 Push API》 – 这里.
Push.js 库,提供处理推送通知的更清洁的 API – 这里.
9. 可安装
默认情况下,任何网站都可以用 Chrome 浏览器菜单的 "添加到主屏幕" 按钮,保存到主屏幕上。不过,让用户以这种方式 "安装" 应用程序可能有点难,因为大多数人完全不知道这个功能。
Thankfully, there is still a way for the application to prompt the user to save it, which is to use a simple installation pop-up window to prompt. To prevent developers from abusing these pop-ups, displaying them programmatically is not allowed. Instead, these windows will appear by themselves when the application meets the following conditions:
There is a valid Web Manifest.
A valid Service Worker is installed.
Access the application via HTTPS.
We meet all the conditions involved above, so when the user visits the website a few times, they will get this prompt:
10. Linkable
Anyone can access a PWA application with just a browser, so the application can be shared simply through its URL. No third-party tools are required to discover or install these apps.
If the app is running in standalone mode, it is also wise to add a share button within the app since the browser address bar and menu are not visible.
Finally
Beyond Responsiveness
After my first experience with responsive design, I realized that giving special Equipment design and programming is a road of no return. There aren't any production-ready websites that I can nail on the first try, but other non-special equipment will do. Today, adding media queries is the first thing most people think of when they discover a styling emergency on mobile, and that’s fine.
If I think about responsive design now, it means doing a lot more than media queries and flexible formatting of content. When making responsive websites, I realized that more and more people need adaptability, performance and content. I realized there is no use making a responsive website fit or performant if you forget about it. I would much rather have a fast and accessible site than an inaccessible, overloaded responsive design site designed to fit the screen every time I open it.
Same for Service Worker, when I first thought of it as just an offline solution, I realized many performance aspects and ways to make the website more accessible and better to use.
Make a progressive website – not just a progressive web application in the name
– responsive, independently connected, novel, secure, explorable, re-customizable, installable, Linkable apps (basic web sites) come with great native-like interactions, but there's one word we should never forget: progressive.
I understand that it is difficult to promote the upgrade optimization of progressive web, so I think naming them progressive web applications is excellent. I wish more people would make progressive web sites. Users will say, "Can you help make our site progressive?" Then progressive optimization and upgrades are not just a temporary thing, everyone will want to do it.
Progressive web applications are an opportunity
We will still look for the best solutions to implement progressive web applications at the beginning. I hope that will make more people aware of progressive upgrade optimization. I hope people don't make the same mistake when focusing on their device. Responsive design has changed the way I build websites. Now I think more about web content, accessibility, performance, and users. I hope to make more people aware of the fundamentals of the web when building PWAs (Progressive Web Apps).
We don’t need to repeat the mistakes of the past. It is a mistake for a PWA to only work on specific devices. Let’s focus on the “progressive” part when building a PWA, rather than the “application” itself.