如何轻松地将您的网站转变为渐进式 Web 应用程序 (PWA)
简介
渐进式 Web 应用 (PWA) 是一种新兴的流行方式,旨在将原生应用的体验带入普通或传统的 Web 应用。PWA 已被 Twitter、福布斯、阿里巴巴、Instagram、Flipkart 等一些大型公司广泛采用,并已逐渐普及。
因此,在本教程中,我们将把现有的网站转变为渐进式 Web 应用。现在就开始吧 :)
简介
我确信您现在一定已经听说过或读过有关渐进式 Web 应用程序的内容,如果您还没有听说过,那么这里就有。
渐进式 Web 应用程序 (PWA) 是一种通过 Web 交付的应用软件,使用 HTML、CSS 和 JavaScript 等常见 Web 技术构建而成。它旨在适用于任何使用符合标准浏览器的平台。其功能包括离线工作、推送通知和设备硬件访问,从而能够在桌面和移动设备上打造与原生应用程序类似的用户体验。
渐进式 Web 应用主要具有以下特点:
-
可靠——它们可以立即加载,并且永远不会显示“无互联网连接”页面,即使在服务工作者缓存的帮助下,在不确定的网络条件下也是如此。
-
快速——它们通过流畅的动画快速响应用户交互。
-
引人入胜——它们感觉就像设备上的自然应用程序,具有身临其境的用户体验。
本教程的要求
-
基本网页设计技能(HTML、CSS 和 JS)
-
您需要在 HTTPS 上运行
-
您希望转换为 PWA 的正常运行的网站。
就像我说的,如果你理解整个概念以及它的实际工作原理,那么构建渐进式 Web 应用程序就非常简单和容易。
PWA 的构成要素
- Web 清单
- 服务工作者
- 您的静态网站
让我们开始吧
为了完成本教程,我们将把一个简单的随机报价 Web 应用转换为 PWA。所有文件都托管在Github上,演示代码可在此处获取。
因此,为了确保一切顺利,我们将使用 HTML、CSS 和 JavaScript 重建简单的随机报价网络应用程序。
那么让我们构建 UI。
创建新目录并创建这些文件
-
index.html
-
css/style.css
-
js/app.js
让我们构建标记。
在index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>The Igala Facts you never knew</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link href='https://fonts.googleapis.com/css?family=Roboto+Slab:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.3/animate.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-6">
<h1><span class="main-color">Random Igala</span><br />Facts</h1>
<p>The best facts about Igala in one place. You can easily see the best facts and share the ones you love on twitter with one click.</p>
</div>
<div class="col-sm-6">
<div class="row">
<div class="col-xs-6">
<a id="next-quote" class="btn btn-lg btn-default btn-block" href="#"><i class="fa fa-refresh"></i> Next Fact</a>
</div>
<div class="col-xs-6">
<a id="share" class="btn btn-lg btn-default btn-block" href="#" target="_top"><i class="fa fa-twitter"></i> Share</a>
</div>
</div>
<div id="quote-box">
<i id="quote-left" class="fa fa-quote-left"></i>
<p id="quote"></p>
<span id="author" class="main-color"></span>
<i id="quote-right" class="fa fa-quote-right"></i>
</div>
<div class="row">
<div class="col-xs-12">
<ul>
<li>Follow Us</li>
<li><a class="main-color" href="https://facebook.com/theigaladigital" target="_blank">@theigaladigital</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="hidden"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>
就像我之前说的,本教程主要教你如何将现有的网站转换为渐进式 Web 应用程序,所以我不会详细介绍 HTML 或其他内容。
— 添加此内容css/app.css
body {
background-color: rgb(0, 0, 0);
color: white;
padding-top: 50px;
font-size: 18px;
font-family: 'Roboto Slab', serif;
}
h1 {
font-size: 4em;
line-height: 70px;
margin-bottom: 40px;
font-weight: bold;
}
a:hover, a:focus, a:active {
text-decoration: none;
color: white;
transition: color 0.8s;
}
.main-color {
color: yellow;
text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.2);
font-weight: bold;
}
#quote-box {
background-color: rgba(255, 255, 255, 0.3);
border-radius: 10px;
padding: 100px 40px;
position: relative;
margin-top: 20px;
}
#quote-left, #quote-right {
color: yellow;
font-size: 3em;
position: absolute;
}
#quote-left {
top: 20px;
left: 20px;
}
#quote-right {
bottom: 20px;
right: 20px;
}
#quote {
font-size: 1.5em;
text-align: center;
}
#author {
position: absolute;
font-size: 1.1em;
left: 50px;
bottom: 30px;
}
.btn {
border-radius: 10px;
color: yellow;
border: 1px solid white !important;
transition: background 0.8s, color 0.8s;
line-height: 30px;
margin-top: 30px;
}
.btn:hover, .btn:active, .btn:focus {
color: white !important;
background-color: yellow !important;
box-shadow: none;
}
ul {
list-style-type: none;
padding: 0;
margin: 10px 0 0 0;
float: right;
white-space: nowrap;
overflow: hidden;
}
li {
display: inline-block;
margin: 0 0 0 1px;
}
#hidden {
display: none;
}
如果仔细查看,您会发现没有显示引号,因此我们必须添加 JavaScript 功能来处理该问题。
— 添加此内容js/app.js
$(document).ready(function () {
$("#next-quote").on("click", function (e) {
e.preventDefault();
var randomQuoteNumber = getRandomQuoteNumber();
updateQuote(randomQuoteNumber);
});
var q = location.search.split("?q=")[1];
if (q >= 0 && q < quotes.length) {
updateQuote(q);
} else {
$("#next-quote").click();
}
});
function updateQuote(quoteNumber) {
var randomQuote = quotes[quoteNumber];
$("#quote").html(randomQuote.quote);
$("#author").html(randomQuote.author);
$("#quote-box").removeClass().addClass("animated bounceIn").one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
$(this).removeClass();
});
$("#share").attr("href", "https://twitter.com/intent/tweet?text=\"" + encodeURIComponent($("#hidden").html(randomQuote.quote).text()) + "\" https://igalafacts.igaladigital.org?q=" + quoteNumber);
}
function getRandomQuoteNumber() {
return Math.floor(Math.random() * quotes.length);
}
var quotes = [{"author": "IgalaDigital", "quote": "Did You Know That Ojaina is the place where the Attah's of Igala are burried?"},
{"author": "IgalaDigital", "quote": "Did You Know That the first aircraft that visited the Igala Kingdom landed at Idah in 1955?"},
{"author": "IgalaDigital", "quote": "Did You Know That Attah Ameh Oboni, had seen to the completion of an aerodrome in 1954 at Idah?"},
{"author": "Ilemona", "quote": "Did you know that the Igala alphabet was adopted from the English alphabet. The latter has five (5) vowels: “a,” “e,” “i,” “o,” “u.”?"},
{"author": "Achimugu Ilemona", "quote": "Did you know the Igala alphabet is made up of thirty-one (31) letters: some vowels, others consonants?"},
{"author": "IgalaDigital", "quote": "Did You Know That Ojaina is a restricted place only allowed for members from the Attah Ruling House?"},
{"author": "IgalaDigital", "quote": "Did you know that Ata Ameh Oboni speak fluently in Igala, Ebira & Hausa?"},
{"author": "Onuche Joseph", "quote": "Did you know that the Ígálá language has seven (7) vowels: “a,” “e,” “ẹ,” “i,” “o,” “ọ,” “u” (encompassing both all the 5 English vowels and two indigenous ones, ‘ẹ’ and ‘ọ’).?"},
{"author": "Naomi", "quote": "Did You Know That Idah is also called Idah Alu Ogo Oja Abutu Eje?"},
{"author": "Inikpi", "quote": "Did you know that Abutu- Eje was the first Igala Ruler?"},
{"author": "IgalaDigital", "quote": "Did you know that you may likely come home to meet one of your family member dead if you kill an animal at Ojaina?"},
{"author": "IgalaDigital", "quote": "Did you know that ata Ameh Oboni took his own life on the night of June 26, 1956?"},
{"author": "IgalaDigital", "quote": "Did you know that the mighty Ata Ameh Oboni died at the age of 51?"},
{"author": "IgalaDigital", "quote": "Did you know that attah Ameh Oboni schooled in Okene(Ebira Land) between 1934 and 1939? Learned in Hausa Literature"},
{"author": "IgalaDigital", "quote": "Did you know that ata Ameh Oboni started off as a market stall tax collector for Idah and Ejule market?"},
{"author": "IgalaDigital", "quote": "Did you know that Ata Obaje Ocheje moved Ameh Oboni from being a market stall tax collector to be come a cheif as onu ugwolawo due to his hard work?"},
{"author": "IgalaDigital", "quote": "Did you know that Ameh Oboni was moved to ankpa from ugwolawo as the judge, commonly known as *Wakali, to be in charge of seven districts?"},
{"author": "IgalaDigital", "quote": "Did you know that Patrick A. Okpanachi, Mallam Garba and Peter Achimugwu were the first in Igala Land that speaks and write in English Language?"},
{"author": "IgalaDigital", "quote": "Did you know that Peter Achimugwu was the man that led the campaign to remove Ameh Oboni as the Attah?"}
]
这只是 JavaScript 基础知识,如果你完全不理解这些内容,可以购买《JavaScript 教师手册》。这本书将教你现代 JavaScript 的所有基础知识和内容。点击 此处
Grammar JavaScript
获取免费副本。
现在您应该有一个可以显示事实的可运行的应用程序。
让我们把它变成 PWA
PWA 的三个基本标准:
- Web 清单
Web 应用清单是一个 JSON 文件,它会告知浏览器您的渐进式 Web 应用,以及它在安装在用户桌面或移动设备上时的行为方式。典型的清单文件包含应用名称、应用应使用的图标以及应用启动时应打开的 URL。
-
Service Worker
是一种脚本,允许浏览器在后台独立运行,从而实现无需网页或用户交互的功能。目前,它们已经包含推送通知和后台同步等功能。 -
图标
这些图标控制你的应用程序,并针对不同的设备提供不同的尺寸。如果没有它们,你的 PWA 应用将无法运行。
现在让我们开始吧。
在我们继续之前,请确保你正在使用实时服务器
使用(Chrome 的 Web 服务器,或VSCode Live Server
创建以下文件:
sw.js
(在根目录中)
manifest.json
(在根目录中)
img/icons
(我们存储图标的地方
首先,我们需要检查浏览器是否支持服务工作者并注册一个新的。
在js/app.js
添加
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('../sw.js').then( () => {
console.log('Service Worker Registered')
})
})
}
你的最终结果app.js
应该是这样的
$(document).ready(function () {
$("#next-quote").on("click", function (e) {
e.preventDefault();
var randomQuoteNumber = getRandomQuoteNumber();
updateQuote(randomQuoteNumber);
});
var q = location.search.split("?q=")[1];
if (q >= 0 && q < quotes.length) {
updateQuote(q);
} else {
$("#next-quote").click();
}
});
function updateQuote(quoteNumber) {
var randomQuote = quotes[quoteNumber];
$("#quote").html(randomQuote.quote);
$("#author").html(randomQuote.author);
$("#quote-box").removeClass().addClass("animated bounceIn").one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function() {
$(this).removeClass();
});
$("#share").attr("href", "https://twitter.com/intent/tweet?text=\"" + encodeURIComponent($("#hidden").html(randomQuote.quote).text()) + "\" https://igalafacts.igaladigital.org?q=" + quoteNumber);
}
function getRandomQuoteNumber() {
return Math.floor(Math.random() * quotes.length);
}
var quotes = [{"author": "IgalaDigital", "quote": "Did You Know That Ojaina is the place where the Attah's of Igala are burried?"},
{"author": "IgalaDigital", "quote": "Did You Know That the first aircraft that visited the Igala Kingdom landed at Idah in 1955?"},
{"author": "IgalaDigital", "quote": "Did You Know That Attah Ameh Oboni, had seen to the completion of an aerodrome in 1954 at Idah?"},
{"author": "Ilemona", "quote": "Did you know that the Igala alphabet was adopted from the English alphabet. The latter has five (5) vowels: “a,” “e,” “i,” “o,” “u.”?"},
{"author": "Achimugu Ilemona", "quote": "Did you know the Igala alphabet is made up of thirty-one (31) letters: some vowels, others consonants?"},
{"author": "IgalaDigital", "quote": "Did You Know That Ojaina is a restricted place only allowed for members from the Attah Ruling House?"},
{"author": "IgalaDigital", "quote": "Did you know that Ata Ameh Oboni speak fluently in Igala, Ebira & Hausa?"},
{"author": "Onuche Joseph", "quote": "Did you know that the Ígálá language has seven (7) vowels: “a,” “e,” “ẹ,” “i,” “o,” “ọ,” “u” (encompassing both all the 5 English vowels and two indigenous ones, ‘ẹ’ and ‘ọ’).?"},
{"author": "Naomi", "quote": "Did You Know That Idah is also called Idah Alu Ogo Oja Abutu Eje?"},
{"author": "Inikpi", "quote": "Did you know that Abutu- Eje was the first Igala Ruler?"},
{"author": "IgalaDigital", "quote": "Did you know that you may likely come home to meet one of your family member dead if you kill an animal at Ojaina?"},
{"author": "IgalaDigital", "quote": "Did you know that ata Ameh Oboni took his own life on the night of June 26, 1956?"},
{"author": "IgalaDigital", "quote": "Did you know that the mighty Ata Ameh Oboni died at the age of 51?"},
{"author": "IgalaDigital", "quote": "Did you know that attah Ameh Oboni schooled in Okene(Ebira Land) between 1934 and 1939? Learned in Hausa Literature"},
{"author": "IgalaDigital", "quote": "Did you know that ata Ameh Oboni started off as a market stall tax collector for Idah and Ejule market?"},
{"author": "IgalaDigital", "quote": "Did you know that Ata Obaje Ocheje moved Ameh Oboni from being a market stall tax collector to be come a cheif as onu ugwolawo due to his hard work?"},
{"author": "IgalaDigital", "quote": "Did you know that Ameh Oboni was moved to ankpa from ugwolawo as the judge, commonly known as *Wakali, to be in charge of seven districts?"},
{"author": "IgalaDigital", "quote": "Did you know that Patrick A. Okpanachi, Mallam Garba and Peter Achimugwu were the first in Igala Land that speaks and write in English Language?"},
{"author": "IgalaDigital", "quote": "Did you know that Peter Achimugwu was the man that led the campaign to remove Ameh Oboni as the Attah?"}
]
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('../sw.js').then( () => {
console.log('Service Worker Registered')
})
})
}
我们将使用 Workbox 库来支持我们的服务工作者
Workbox 是 Google 开发的一组库和 Node 模块,可以轻松缓存资产并充分利用用于构建渐进式 Web 应用程序的功能。
我们的服务工作者的想法是缓存所有文件(字体、JavaScript、CSS、图像等),以便我们可以在页面加载后离线访问它们。
关于Service Worker,需要理解的重点是,您可以掌控网络。您可以决定缓存什么、如何缓存以及如何将缓存的数据返回给用户。
—sw.js
添加以下内容:
importScripts('https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js');
if (workbox) {
console.log("Yay! Workbox is loaded !");
workbox.precaching.precacheAndRoute([]);
/* cache images in the e.g others folder; edit to other folders you got
and config in the sw-config.js file
*/
workbox.routing.registerRoute(
/(.*)others(.*)\.(?:png|gif|jpg)/,
new workbox.strategies.CacheFirst({
cacheName: "images",
plugins: [
new workbox.expiration.Plugin({
maxEntries: 50,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 Days
})
]
})
);
/* Make your JS and CSS âš¡ fast by returning the assets from the cache,
while making sure they are updated in the background for the next use.
*/
workbox.routing.registerRoute(
// cache js, css, scc files
/.*\.(?:css|js|scss|)/,
// use cache but update in the background ASAP
new workbox.strategies.StaleWhileRevalidate({
// use a custom cache name
cacheName: "assets",
})
);
// cache google fonts
workbox.routing.registerRoute(
new RegExp("https://fonts.(?:googleapis|gstatic).com/(.*)"),
new workbox.strategies.CacheFirst({
cacheName: "google-fonts",
plugins: [
new workbox.cacheableResponse.Plugin({
statuses: [0, 200],
}),
],
})
);
// add offline analytics
workbox.googleAnalytics.initialize();
/* Install a new service worker and have it update
and control a web page as soon as possible
*/
workbox.core.skipWaiting();
workbox.core.clientsClaim();
} else {
console.log("Oops! Workbox didn't load 👺");
}
现在我们的服务工作者可以工作,并且会在页面加载后缓存文件。
现在让我们让我们的应用程序可安装。
— 添加此内容manifest.json
{
"name": "Igala Facts",
"short_name": "Igala Facts",
"icons": [
{
"src": "img/icons/icon-72x72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "img/icons/icon-96x96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "img/icons/icon-128x128.png",
"sizes": "128x128",
"type": "image/png"
},
{
"src": "img/icons/icon-144x144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "img/icons/icon-152x152.png",
"sizes": "152x152",
"type": "image/png"
},
{
"src": "img/icons/icon-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "img/icons/icon-384x384.png",
"sizes": "384x384",
"type": "image/png"
},
{
"src": "img/icons/icon-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/index.html",
"display": "standalone",
"background_color": "#000",
"theme_color": "#ffff00"
}
您的PWA 图标尺寸应为
px
和 以下尺寸:72x72
,,,,,,,,, 您可以使用Web Manifest Generator来生成96x96
您的128x128
144x144
152x152
192x192
384x384
512x512
manifest.json
现在我们需要将我们的 Web 应用连接到清单,以允许从该页面“添加到主屏幕”。将其添加到您的index.html
<link rel="manifest" href="/manifest.json" />
<meta name="theme-color" content="#333" />
如果您有多个页面,则需要将其添加到所有页面。您也可以使用此处使用的
相同方法theme-color
manifest.json
现在你的最终结果index.html
应该是这样的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>The Igala Facts you never knew</title>
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link href='https://fonts.googleapis.com/css?family=Roboto+Slab:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.3/animate.min.css">
<link rel="manifest" href="manifest.json" />
<meta name="theme-color" content="yellow" />
</head>
<body>
<div class="container">
<div class="row">
<div class="col-sm-6">
<h1><span class="main-color">Random Igala</span><br />Facts</h1>
<p>The best facts about Igala in one place. You can easily see the best facts and share the ones you love on twitter with one click.</p>
</div>
<div class="col-sm-6">
<div class="row">
<div class="col-xs-6">
<a id="next-quote" class="btn btn-lg btn-default btn-block" href="#"><i class="fa fa-refresh"></i> Next Fact</a>
</div>
<div class="col-xs-6">
<a id="share" class="btn btn-lg btn-default btn-block" href="#" target="_top"><i class="fa fa-twitter"></i> Share</a>
</div>
</div>
<div id="quote-box">
<i id="quote-left" class="fa fa-quote-left"></i>
<p id="quote"></p>
<span id="author" class="main-color"></span>
<i id="quote-right" class="fa fa-quote-right"></i>
</div>
<div class="row">
<div class="col-xs-12">
<ul>
<li>Follow Us</li>
<li><a class="main-color" href="https://facebook.com/theigaladigital" target="_blank">@theigaladigital</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="hidden"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="js/app.js"></script>
</body>
</html>
恭喜,您已成功将您的网站转变为渐进式 Web 应用程序。
结论
在本文中,我们了解了通过添加清单文件和 Service Worker 构建 PWA 是多么简单快捷,它极大地提升了传统 Web 应用的用户体验。PWA 快速、安全、可靠,而且最重要的是,它们支持离线模式。
现在许多框架都为我们设置了服务工作文件,但是,了解如何使用 Vanilla JavaScript 实现它可以帮助您理解 PWAs。
附言:如果您遇到问题,可能是 HTTPS 的问题。PWA 不支持 HTTP,因此如果您在本地计算机上工作,请确保使用 http-server 或 live-server 运行。
感谢您的阅读!
在Twitter或Facebook上关注我,我无处不在@dfiredeveloper
文章来源:https://dev.to/dfiredeveloper/how-to-easily-turn-your-website-to-a-progressive-web-app-pwa-2nm4