如何优化渐进式Web应用程序:超越基础

渐进式Web应用程序已被证明可以提高用户参与度并有效降低成本。建立现代化的PWA不仅需要核心设置来满足用户的期望。因此,让我们直接了解如何为PWA添加现代特征,从离线功能到用户友好的权限请求。

渐进式Web应用程序(PWA)在2020年仍将继续流行。考虑到更高的转换率,客户参与度,降低的页面加载速度以及更低的开发和开销成本,这并不奇怪。

我们可以看到受人尊敬的公司也通过其PWA获得成功,例如Twitter,Uber,Tinder,Pinterest和Forbes。他们都为实施渐进式应用程序带来巨大收益。

好消息是,开发PWA并非只有大型预算公司才能负担得起。这些应用程序平均为小型企业和普通企业提供服务,创建起来并不那么复杂。

您可以在Smashing Magazine上找到全面的《渐进式Web应用程序初学者指南》,该指南侧重于构建PWA的核心。

但是,让我们更进一步,学习如何为PWA部署现代质量,例如脱机功能,基于网络的优化,跨设备用户体验,SEO功能以及非侵入式通知和请求。您还将找到示例代码或对更具体指南的引用,以便可以将这些技巧应用于PWA。

渐进式Web应用程序(PWA)快速概述

让我们不要跳过基础知识,而快速了解PWA的核心。

什么是PWA?

“渐进式Web应用程序(PWA)使用现代API进行了构建和增强,以提供增强的功能,可靠性和可安装性,同时只需一个代码库即可在任何设备上访问任何地方的任何人。”

-谷歌的开发者

换句话说,PWA是用户可以用作独立应用程序的网站。它们与本机应用程序不同,主要是因为PWA不需要安装并且可以与各种设备一起使用-本机应用程序主要是为移动设备构建的。

PWA如何工作?

PWA的核心由三个组件组成:Web应用程序清单,服务工作者和应用程序外壳。您可以在上述初学者指南中找到有关构建这些对象的详细说明。

这些组件的作用如下。

Web App清单

Web应用程序清单是使网站在全屏模式下作为独立应用程序运行的核心。您可以定义PWA的外观,针对不同的设备对其进行优化,并分配在应用程序安装后显示的图标。

服务人员

服务工作人员通过获取缓存的数据或通知用户不存在Internet连接来启用PWA的脱机使用。恢复服务器连接后,服务人员还可以检索最新数据。

应用程序外壳架构

用户访问PWA时将看到应用程序外壳。这是驱动用户界面所需的最低HTML,CSS和JavaScript。开发PWA时,可以在浏览器中缓存应用程序外壳程序的资源和资产。

为您的PWA部署现代特征

除了核心功能之外,现代的PWA还具有其他特征,这些特征进一步推动其用户获得更加非凡的用户体验。

让我们看一下PWA的一些特定现代特征,并了解有关将其添加到PWA中的信息。Google开发人员认为以下质量是基本PWA的重要补充。

该应用程序可以像联机操作一样脱机工作

构建PWA时,您还可以开发自定义的脱机页面作为核心部分。但是,如果您的PWA甚至在没有Internet连接的情况下仍能继续运行,甚至在需要连接的特定点上,仍将更加方便用户使用。否则,用户体验就像Ankita Masand对订购蛋糕的折磨一样令人沮丧,就像她在她的PWA痛点文章中所描述的那样。

通过使用缓存的内容,后台同步和框架屏幕,可以实现更重要的用户体验。让我们看看每个。

缓存内容 IndexedDB

IndexedDB 是浏览器内的NoSQL存储系统,可用于缓存和检索所需的数据以使PWA脱机工作。

但是,并非所有浏览器都支持IndexedDB,因此您要做的第一件事是检查用户浏览器是否支持它。

if (!('indexedDB' in window)) {
  console.log('This browser doesn/'t support IndexedDB');
  return;
}

之后,您可以使用IndexedDB API创建缓存的内容。这是来自Google开发人员的一个示例,该示例打开数据库,添加对象存储并向该存储添加项目。

var db;
var openRequest = indexedDB.open('test_db', 1);
openRequest.onupgradeneeded = function(e) {
var db = e.target.result;
console.log('running onupgradeneeded');
if (!db.objectStoreNames.contains('store')) {
var storeOS = db.createObjectStore('store',
{keyPath: 'name'});
}
};
openRequest.onsuccess = function(e) {
console.log('running onsuccess');
db = e.target.result;
addItem();
};
openRequest.onerror = function(e) {
console.log('onerror!');
console.dir(e);
};
function addItem() {
var transaction = db.transaction(['store'], 'readwrite');
var store = transaction.objectStore('store');
var item = {
name: 'banana',
price: '$2.99',
description: 'It is a purple banana!',
created: new Date().getTime()
};
var request = store.add(item);
request.onerror = function(e) {
console.log('Error', e.target.error.name);
};
request.onsuccess = function(e) {
console.log('Woot! Did it');
};
}
后台同步

如果您的PWA在后台同步数据,则用户可以在脱机时执行操作,然后在恢复Internet连接时执行这些操作。一个简单的示例是消息传递应用程序。用户可以在脱机时发送消息,而无需等待发送消息-连接恢复后,后台同步会自动发送消息。

这是Jake Archibald如何开发背景同步功能的示例。

// Register your service worker:
navigator.serviceWorker.register('/sw.js');
// Then later, request a one-off sync:
navigator.serviceWorker.ready.then(function(swRegistration) {
return swRegistration.sync.register('myFirstSync');
});

然后在中收听事件/sw.js

self.addEventListener('sync', function(event) {
if (event.tag == 'myFirstSync') {
event.waitUntil(doSomeStuff());
}
});
骨架屏幕

使用框架屏幕的主要好处之一是用户会感觉到应用程序正在工作,而不是闲置。当用户没有连接时,框架屏幕将在没有内容的情况下绘制界面-一旦恢复连接,该界面就会填充。

代码我的UI具有一些出色的代码段,可用于为PWA创建框架屏幕。

如何优化渐进式Web应用程序:超越基础

根据网络使用情况进行优化

PWA的主要好处是可以为用户提供更快的体验。您可以通过让PWA使用缓存优先网络,优先化资源并根据网络质量使用自适应加载来进一步优化加载速度。

让我们看看如何将这些开发到PWA中。

先缓存,再缓存网络

首先使用缓存的内容,可以使您的PWA脱机运行,甚至为用户在低网络覆盖区域访问内容铺平道路。您可以通过创建服务工作者来缓存内容,然后提取内容来做到这一点。

这是Jeff Posnick的一个示例,它介绍了如何使用Service Worker缓存静态HTML。

self.addEventListener('fetch', event => {
if (event.request.mode === 'navigate') {
// See /web/fundamentals/getting-started/primers/async-functions
// for an async/await primer.
event.respondWith(async function() {
// Optional: Normalize the incoming URL by removing query parameters.
// Instead of https://example.com/page?key=value,
// use https://example.com/page when reading and writing to the cache.
// For static HTML documents, it's unlikely your query parameters will
// affect the HTML returned. But if you do use query parameters that
// uniquely determine your HTML, modify this code to retain them.
const normalizedUrl = new URL(event.request.url);
normalizedUrl.search = '';
// Create promises for both the network response,
// and a copy of the response that can be used in the cache.
const fetchResponseP = fetch(normalizedUrl);
const fetchResponseCloneP = fetchResponseP.then(r => r.clone());
// event.waitUntil() ensures that the service worker is kept alive
// long enough to complete the cache update.
event.waitUntil(async function() {
const cache = await caches.open('my-cache-name');
await cache.put(normalizedUrl, await fetchResponseCloneP);
}());
// Prefer the cached response, falling back to the fetch response.
return (await caches.match(normalizedUrl)) || fetchResponseP;
}());
}
});
优先分配资源

默认情况下,由于PWA的精简特性,它们比类似的本机应用程序具有更高的性能。此外,由于PWA使用浏览器的缓存,因此可以指示哪些资源具有优先级,甚至在使用它们之前就需要对其进行渲染。这主要适用于静态元素,因为在提取动态内容之前需要对其进行更新。

您可以通过使用HTML中的字符串来指定元素的优先级<link>。您还可以使用rel=”preconnect”和指定第三方服务器文件rel=”dns-prefetch.”

Maximiliano Firtman通过在浏览器引擎中优先设置Web字体,给出了一个简单的示例:

<link rel=”preload” as=”font” href=”font.woff” crossorigin>
实现自适应加载

WiFi和4G的互联网速度并非随处可用,用户仍然可以通过2G和3G连接上网。由于您希望PWA被尽可能多的人访问,因此您可能希望对其进行优化以使其以较低的Internet速度运行。

您可以通过实施自适应加载来实现此目的,该加载基于用户具有的连接类型来加载PWA元素。

网站建设

网站建设

Google的自适应加载插图。(大型预览)

最简单的方法是使用Google的Workbox工具,该工具包括许多用于缓存策略的现成插件。

假设您要定义一个自定义缓存策略。以下是Demian Renzulli和Jeff Posnick所提供的示例:

const adaptiveLoadingPlugin = {
requestWillFetch: async ({request}) => {
const urlParts = request.url.split('/');
let imageQuality;
switch (
navigator && navigator.connection
? navigator.connection.effectiveType
: ''
) {
//...
case '3g':
imageQuality = 'q_30';
break;
//...
}
const newUrl = urlParts
.splice(urlParts.length - 1, 0, imageQuality)
.join('/')
.replace('.jpg', '.png');
const newRequest = new Request(newUrl.href, {headers: request.headers});
return newRequest;
},
};

接下来,将插件传递给cacheFirst包含正则表达式以匹配图像网址(例如/img/)的策略:

workbox.routing.registerRoute(
new RegExp('/img/'),
workbox.strategies.cacheFirst({
cacheName: 'images',
plugins: [
adaptiveLoadingPlugin,
workbox.expiration.Plugin({
maxEntries: 50,
purgeOnQuotaError: true,
}),
],
}),
);

在所有平台上的出色用户体验

出色的PWA可在浏览器,移动设备和平板电脑上无缝运行。虽然使用Android设备是访问Internet的最流行方式(市场份额为38.9%),但针对所有平台优化应用程序是开发PWA核心功能的一部分。

您可以采取进一步措施来提高可用性并提供出色的用户体验,例如减少PWA加载时的跳动,并确保PWA可与任何输入法一起使用。

您可以按照以下方法处理所有这些方面。

减少“跳动”的内容加载

即使使用高速Internet,在加载时网站的内容也会发生变化,因为网站的元素是按顺序加载的。连接速度较慢时,此效果会更糟,并严重损害用户的使用体验。

导致内容在加载时发生移位的最常见元素是图像,因为它们通常较大,而不是加载内容时的优先级。您可以使用较小的占位符图像来解决“延迟加载”这一问题,这些占位符图像可以在呈现HTML结构之后确定优先级。

这是Mozilla开发人员的示例,说明如何添加轻量级图像,该图像首先在JavaScript中的实际图像之前加载:

<img src='data/img/placeholder.png' data-src='data/img/SLUG.jpg' alt='NAME'>

app.js文件按如下方式处理data-src属性:

let imagesToLoad = document.querySelectorAll('img[data-src]');
const loadImages = (image) => {
image.setAttribute('src', image.getAttribute('data-src'));
image.onload = () => {
image.removeAttribute('data-src');
};
};

然后创建一个循环:

imagesToLoad.forEach((img) => {
loadImages(img);
});

您也可以在Smashing Magazine上查看有关减少内容与其他元素一起跳跃的详尽指南。

PWA适用于任何输入法

我们已经介绍了PWA如何与各种不同的设备一起工作。要更进一步,您还需要考虑用户可以在这些设备上使用的其他输入法,例如触摸,鼠标和手写笔。

将Pointer Events API添加到PWA主要解决了这个问题。根据Google的开发人员,您可以按照以下方法进行处理。

首先,检查浏览器是否支持指针事件:

if (window.PointerEvent) {
// Yay, we can use pointer events!
} else {
// Back to mouse and touch events, I guess.
}

接下来,您可以定义各种输入法可以执行的操作:

switch(ev.pointerType) {
case 'mouse':
// Do nothing.
break;
case 'touch':
// Allow drag gesture.
break;
case 'pen':
// Also allow drag gesture.
break;
default:
// Getting an empty string means the browser doesn't know
// what device type it is. Let's assume mouse and do nothing.
break;
}

由于大多数浏览器已经具有启用触摸功能,因此您无需添加其他任何内容。

与本地应用程序相比,PWA的主要优势之一是PWA本质上是一个网站,搜索引擎可以对其进行索引。这使您可以部署SEO策略,以使您的PWA内容更易于发现。

您可以首先确保PWA中的每个URL都有唯一的描述性标题和元描述,这是任何SEO优化活动的基础。

让我们看看您可以采取其他一些步骤来使PWA可搜索。

 

分析PWA的可发现性

Google的Search Console中有一个出色的工具,可以分析您的网站(PWA)并报告结果。您可以使用它对您的网站进行基本扫描,并发现任何薄弱环节,然后就可以开始进行修复。

另外,您也可以在Chrome浏览器中使用Lighthouse来进行SEO审核。

首先,导航到目标URL。然后按Control+Shift+J(或Command+Option+J在Mac上)打开开发人员的工具菜单。选择“灯塔”选项卡,选中“ SEO类别”框,然后生成报告。

如何优化渐进式Web应用程序:超越基础
Google Chrome浏览器Lighthouse开发人员工具类别SEO屏幕截图。(大型预览)
使用结构化数据

Google的搜索引擎使用结构化数据来了解内容在您网页上的用途。

结构化数据是一种标准化格式,用于提供有关页面的信息和对页面内容进行分类;例如,在食谱页面上,成分是什么,烹饪时间和温度,卡路里等等。
— Google

在您开始编码之前,Google还整理了一份有用的常见结构化数据错误列表,并提供了相关的修正指南。学习此材料应为您避免的事情提供一个良好的基线。

弗雷德里克·奥布赖恩(Frederick O’Brien)在Smashing Magazine上撰写了出色的指南,将结构化数据烘焙到设计过程中,从一开始就描述了如何构建结构化数据。

用户友好的通知和权限请求

最后但并非最不重要的一点是,您可以通过优化通知和权限请求来提高用户体验,以便它们为您的用户服务-而不是使用户感到困惑和烦恼。

虽然通常可以依靠常识,但是您也可以实现一些实用技巧,例如创建非侵入式推送通知以及为用户提供取消订阅消息的选项。

细微的交流许可请求

有两种现代的方法可以自动化网站和用户之间的通信-聊天机器人和通知。

在PWA上下文中,聊天机器人的主要优点是它不需要用户的许可即可与用户进行交互。但是,取决于您使用的哪个聊天机器人应用程序,用户可能会漏掉微妙的消息。另一方面,通知需要用户的许可,但更为可见。

由于您可以将聊天机器人添加为单独的第三方应用程序,因此我们将重点放在创建用户友好的推送通知上。如果您首先需要有关如何创建推送通知的指南,那么Indrek Lasn就是一个很好的指南。

创建非侵入式许可请求的最直接方法是使用双重请求。这意味着您将在用户操作系统的默认交互之上包括对站点的自定义交互。

马特·甘特(Matt Gaunt)通过以下图像为这种效果提供了完美的插图。

这是不提供上下文的默认通知权限请求:

网站建设

网站建设

错误的UX权限请求示例由Permission UX提供。(大型预览)

这是在上述默认通知权限之前添加的自定义交互:

如何优化渐进式Web应用程序:超越基础
权限UX的良好UX权限请求示例。(大型预览)

通过在操作系统的默认警报之前添加自定义警报,您可以向用户更清楚地描述通知的目的。这增加了用户选择接收您站点通知的机会。

使用户可以退出通知

对于用户而言,禁用站点的推送通知非常烦人,无论他们使用什么设备。因此,就用户体验而言,为用户提供退出消息的选项很长。

这是Matt Gaunt的示例,说明如何在代码和UI中实现取消订阅的功能:

首先,定义pushButton的点击监听器:

pushButton.addEventListener('click', function() {
pushButton.disabled = true;
if (isSubscribed) {
unsubscribeUser();
} else {
subscribeUser();
}
});

然后,添加一个新功能:

function unsubscribeUser() {
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
// TODO: Tell application server to delete subscription
return subscription.unsubscribe();
}
})
.catch(function(error) {
console.log('Error unsubscribing', error);
})
.then(function() {
updateSubscriptionOnServer(null);
console.log('User is unsubscribed.');
isSubscribed = false;
updateBtn();
});
}

这是成功实现订阅按钮以禁用通知(如果用户选择)后在控制台中的外观。

网站建设

网站建设

Console.logMatt Gaunt成功启用/禁用通知功能的示例。(大型预览)

结论

PWA具有强大的功能,可以增加您的网站流量并扩大用户体验。为了进一步优化您的PWA,您可以使用本文介绍的这些现代解决方案来增强性能和功能。

您也不需要一次实现所有功能。随意挑选最相关的选项,因为这些建议中的每一个都可以帮助您进一步提高PWA。

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/262067.html

(0)
上一篇 2022年5月25日
下一篇 2022年5月25日

相关推荐

发表回复

登录后才能评论