Jak zoptymalizować progresywne aplikacje internetowe: wykraczanie poza podstawy

Opublikowany: 2022-03-10
Szybkie podsumowanie ↬ Udowodniono , że progresywne aplikacje internetowe zwiększają zaangażowanie użytkowników i skutecznie obniżają koszty. Zbudowanie nowoczesnego PWA wymaga czegoś więcej niż tylko podstawowej konfiguracji, aby nadążać za oczekiwaniami użytkownika. Dlatego spójrzmy z pierwszej ręki na dodawanie współczesnych cech do PWA, od działania w trybie offline po przyjazne dla użytkownika prośby o pozwolenie.

Progresywne aplikacje internetowe (PWA) wciąż zyskują popularność w 2020 roku. Nie jest to zaskoczeniem, biorąc pod uwagę korzyści wynikające z wyższych współczynników konwersji, zaangażowania klientów, zmniejszonej szybkości ładowania strony oraz niższych kosztów rozwoju i kosztów ogólnych.

Widzimy, jak szanowane firmy również odnoszą sukcesy dzięki swoim PWA, takim jak Twitter, Uber, Tinder, Pinterest i Forbes. I wszyscy chwalą się ogromnymi korzyściami płynącymi z wdrażania progresywnych aplikacji.

Dobrą wiadomością jest to, że tworzenie PWA nie jest czymś, na co mogą sobie pozwolić tylko firmy o dużych budżetach. Aplikacje te w równym stopniu służą małym i średnim firmom, a ich tworzenie nie jest aż tak skomplikowane.

W magazynie Smashing można znaleźć obszerny Przewodnik dla początkujących po progresywnych aplikacjach internetowych, który koncentruje się na budowaniu rdzenia PWA.

Pójdźmy jednak o krok dalej i dowiedzmy się, jak wdrażać nowoczesne funkcje w PWA, takie jak funkcjonalność offline, optymalizacja sieciowa, wrażenia użytkownika na różnych urządzeniach, możliwości SEO oraz nieinwazyjne powiadomienia i żądania. Znajdziesz również przykładowy kod lub odniesienia do bardziej szczegółowych przewodników, dzięki którym możesz zaimplementować te wskazówki w swoim PWA.

Szybki przegląd progresywnych aplikacji internetowych (PWA)

Nie pomijajmy podstaw i szybko przejdźmy do serca PWA.

Co to jest PWA?

„Progresywne aplikacje internetowe (PWA) są budowane i ulepszane za pomocą nowoczesnych interfejsów API, aby zapewnić większe możliwości, niezawodność i łatwość instalacji, jednocześnie docierając do każdego, w dowolnym miejscu i na dowolnym urządzeniu za pomocą jednej bazy kodu”.

— programiści Google

Innymi słowy, PWA to strony internetowe, z których użytkownicy mogą korzystać jako samodzielne aplikacje. Różnią się one od aplikacji natywnych głównie tym, że PWA nie wymagają instalacji i mogą być używane z różnymi urządzeniami — aplikacje natywne są tworzone głównie dla urządzeń mobilnych.

Jak działają PWA?

Rdzeń PWA składa się z trzech komponentów: manifestu aplikacji internetowej, pracowników usług i powłoki aplikacji. Szczegółowe instrukcje ich budowania znajdziesz we wspomnianym powyżej poradniku dla początkujących.

Oto, co robią te komponenty.

Manifest aplikacji internetowej

Manifest aplikacji internetowej jest podstawą do uruchomienia witryny internetowej jako samodzielnej aplikacji w trybie pełnoekranowym. Możesz zdefiniować wygląd PWA, zoptymalizować go pod kątem różnych urządzeń, a także przypisać ikonę wyświetlaną po instalacji aplikacji.

Pracownicy usług

Pracownicy serwisu umożliwiają korzystanie z PWA w trybie offline, pobierając dane z pamięci podręcznej lub informując użytkownika o braku połączenia z Internetem. Pracownicy serwisu pobierają również najnowsze dane po przywróceniu połączenia z serwerem.

Architektura powłoki aplikacji

Powłoka aplikacji jest tym, co widzą użytkownicy, gdy uzyskują dostęp do PWA. Jest to minimalny kod HTML, CSS i JavaScript wymagany do obsługi interfejsu użytkownika. Tworząc PWA, możesz buforować zasoby i zasoby powłoki aplikacji w przeglądarce.

Więcej po skoku! Kontynuuj czytanie poniżej ↓

Wdrażanie nowoczesnych cech w PWA

Oprócz podstawowych funkcji, nowoczesne aplikacje PWA zawierają dodatkowe cechy, które dodatkowo kierują użytkowników w kierunku bardziej niezwykłego doświadczenia użytkownika.

Przyjrzyjmy się niektórym specyficznym nowoczesnym cechom PWA i dowiedz się, jak dodawać je do PWA. Poniższe cechy są uważane za świetne dodatki do podstawowego PWA przez programistów Google.

Aplikacja działa w trybie offline, tak jak w trybie online

Tworząc PWA, możesz również opracować niestandardową stronę offline jako część rdzenia. Jednak jest to o wiele bardziej przyjazne dla użytkownika, jeśli Twoje PWA będzie nadal działać nawet bez połączenia z Internetem — do pewnego momentu, w którym połączenie stanie się konieczne. W przeciwnym razie wrażenia użytkownika mogą być tak frustrujące, jak trudy Ankity Masand z zamawianiem ciasta, jak opisuje w swoim artykule o problemach związanych z PWA.

Możesz osiągnąć bardziej znaczące wrażenia użytkownika, korzystając z zawartości pamięci podręcznej, synchronizacji w tle i ekranów szkieletowych. Przyjrzyjmy się każdemu.

Zawartość w pamięci podręcznej z IndexedDB

IndexedDB to system pamięci masowej NoSQL w przeglądarce, którego można używać do buforowania i pobierania wymaganych danych, aby PWA działała w trybie offline.

Jednak nie wszystkie przeglądarki obsługują IndexedDB , więc pierwszą rzeczą, którą chcesz zrobić, jest sprawdzenie, czy przeglądarka użytkownika ją obsługuje.

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

Następnie możesz utworzyć zawartość w pamięci podręcznej za pomocą interfejsu IndexedDB API. Oto przykład od programistów Google dotyczący otwierania bazy danych, dodawania magazynu obiektów i dodawania elementu do tego sklepu.

 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'); }; }

Synchronizacja w tle

Jeśli Twoje PWA synchronizuje dane w tle, użytkownik może wykonywać akcje w trybie offline, które są następnie wykonywane po przywróceniu połączenia internetowego. Prostym przykładem jest aplikacja do przesyłania wiadomości. Użytkownik może wysłać wiadomość w trybie offline bez konieczności czekania na jej wysłanie — synchronizacja w tle automatycznie wysyła wiadomość po przywróceniu połączenia.

Oto przykład, jak opracować funkcję synchronizacji w tle, autorstwa Jake'a Archibalda.

 // 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'); });

Następnie posłuchaj zdarzenia w /sw.js :

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

Ekrany szkieletowe

Jedną z głównych zalet korzystania z ekranów szkieletowych jest to, że użytkownicy postrzegają aplikację jako działającą, a nie bezczynną. Podczas gdy użytkownik nie ma połączenia, szkieletowy ekran wyświetla interfejs bez zawartości — który następnie wypełnia się po przywróceniu połączenia.

Code My UI udostępnia kilka doskonałych fragmentów kodu, których możesz użyć do stworzenia szkieletu ekranu dla swojego PWA.

Przykłady ekranów szkieletowych w Code My UI
Przykłady ekranów szkieletowych w Code My UI. (duży podgląd)

Optymalizacja na podstawie wykorzystania sieci

Główną zaletą PWA jest to, że zapewnia użytkownikom szybsze działanie. Możesz dodatkowo zoptymalizować szybkość ładowania, ustawiając PWA w sieci opartej na pamięci podręcznej, ustalając priorytety zasobów i korzystając z ładowania adaptacyjnego w oparciu o jakość sieci.

Przyjrzyjmy się, jak możesz je rozwinąć do swojego PWA.

Najpierw buforuj, potem sieć

Użycie najpierw zawartości z pamięci podręcznej dodatkowo umożliwia działanie PWA w trybie offline i toruje użytkownikom drogę do dostępu do zawartości nawet w obszarach o niskim zasięgu sieci. Możesz to zrobić, tworząc Service Worker do buforowania zawartości, a następnie ją pobierając.

Oto przykład autorstwa Jeffa Posnicka dotyczący buforowania statycznego kodu HTML przy użyciu pracowników usług.

 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; }()); } });

Priorytetyzacja zasobów

Domyślnie aplikacje PWA mają większą wydajność niż podobne aplikacje natywne ze względu na ich uproszczoną naturę. Ponadto, ponieważ PWA korzystają z pamięci podręcznej przeglądarki, możliwe jest wskazanie, które zasoby mają priorytet i muszą zostać wyrenderowane, jeszcze zanim zostaną użyte. Działa to głównie z elementami statycznymi, ponieważ zawartość dynamiczna wymaga aktualizacji przed jej pobraniem.

Możesz określić priorytet elementów, używając ciągu <link> w kodzie HTML. Możesz także określić pliki serwera innych firm, używając rel=”preconnect” i rel=”dns-prefetch.”

Maximiliano Firtman podaje prosty przykład, ustalając priorytety czcionek internetowych w silniku przeglądarki:

 <link rel=”preload” as=”font” href=”font.woff” crossorigin>

Wdrażanie ładowania adaptacyjnego

Prędkości Internetu Wi-Fi i 4G nie są wszędzie dostępne, a użytkownicy nadal łączą się z Internetem za pomocą połączeń 2G i 3G. Ponieważ chcesz, aby Twoje PWA było dostępne dla jak największej liczby osób, możesz chcieć je zoptymalizować, aby działały również przy niższych prędkościach Internetu.

Możesz to osiągnąć, wdrażając ładowanie adaptacyjne, które ładuje elementy PWA na podstawie typu połączenia, które posiada użytkownik.

Adaptacyjna ilustracja ładowania od Google.
Adaptacyjna ilustracja ładowania od Google. (duży podgląd)

Najprostszym sposobem jest skorzystanie z narzędzia Google Workbox, które zawiera wiele gotowych wtyczek do strategii buforowania.

Załóżmy, że chcesz zdefiniować niestandardową strategię buforowania. Oto jak możesz to zrobić jako przykład od Demian Renzulli i 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; }, };

Następnie przekaż wtyczkę do strategii cacheFirst zawierającej wyrażenie regularne pasujące do adresów URL obrazów (np. /img/ ):

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

Doskonałe wrażenia użytkownika na wszystkich platformach

Doskonałe PWA działa bezproblemowo w przeglądarkach, urządzeniach mobilnych i tabletach. Podczas gdy korzystanie z urządzenia z systemem Android jest najpopularniejszym sposobem (z 38,9% udziałem w rynku) dostępu do Internetu, optymalizacja aplikacji dla wszystkich platform jest częścią rozwoju podstawowych funkcji PWA.

Możesz podjąć dalsze kroki, aby zwiększyć użyteczność i zapewnić użytkownikom wspaniałe wrażenia, na przykład zmniejszyć nerwowość podczas ładowania PWA i upewnić się, że PWA działa z dowolną metodą wprowadzania.

Oto jak możesz podejść do każdego z tych aspektów.

Zmniejszenie „skokowego” ładowania treści

Nawet przy szybkim Internecie zawartość witryny może się zmieniać podczas ładowania, ponieważ elementy witryny ładują się w kolejności. Efekt ten jest jeszcze gorszy przy niższych prędkościach połączenia i bardzo szkodzi wrażeniu użytkownika.

Najczęstszymi elementami powodującymi przesuwanie się treści podczas ładowania są obrazy, ponieważ są one zazwyczaj większe i nie stanowią priorytetu podczas ładowania treści. Możesz rozwiązać ten problem za pomocą „leniwego ładowania”, używając mniejszych obrazów zastępczych, którym możesz nadać priorytet po wyrenderowaniu struktury HTML.

Oto przykład autorstwa programistów Mozilli, w jaki sposób można dodać lekki obraz, który jest ładowany jako pierwszy przed rzeczywistym obrazem w JavaScript:

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

Plik app.js przetwarza atrybuty data-src w następujący sposób:

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

A następnie utwórz pętlę:

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

Możesz również zapoznać się z dokładnym przewodnikiem na Smashing Magazine o ograniczeniu przeskakiwania treści z innymi elementami.

PWA działa z dowolną metodą wprowadzania

Omówiliśmy, jak PWA powinny działać z różnymi urządzeniami. Aby pójść o krok dalej, musisz również uwzględnić inne metody wprowadzania, z których użytkownicy mogą korzystać na tych urządzeniach, takie jak dotyk, mysz i rysik.

Dodanie interfejsu Pointer Events API do PWA głównie rozwiązuje to pytanie. Oto jak możesz do tego podejść według programistów Google.

Najpierw sprawdź, czy przeglądarka obsługuje zdarzenia wskaźnika:

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

Następnie możesz zdefiniować akcje, które mogą wykonać różne metody wprowadzania:

 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; }

Ponieważ większość przeglądarek ma już funkcje dotykowe, nie musisz nic więcej dodawać.

Wykrywalny przez wyszukiwanie

Jedną z kluczowych zalet PWA w porównaniu z aplikacją natywną jest to, że PWA jest z natury stroną internetową, a wyszukiwarki mogą je indeksować. Dzięki temu możesz wdrożyć strategie SEO, aby zawartość PWA była łatwiejsza do znalezienia.

Możesz zacząć od upewnienia się, że każdy adres URL w Twoim PWA ma unikalny, opisowy tytuł i metaopis, który jest podstawą wszelkich działań optymalizacyjnych SEO.

Przyjrzyjmy się innym krokom, które możesz wykonać, aby umożliwić wyszukiwanie w PWA.

Przeanalizuj wyszukiwalność swojego PWA

Google ma doskonałe narzędzie w swojej Search Console, które analizuje Twoją witrynę (PWA) i raportuje wyniki. Możesz go użyć do podstawowego skanowania swojej witryny i wykrycia słabych punktów, które możesz następnie zacząć naprawiać.

Alternatywnie możesz użyć Lighthouse w przeglądarce Chrome, aby przeprowadzić audyt SEO.

Najpierw przejdź do docelowego adresu URL. Następnie naciśnij Control+Shift+J (lub Command+Option+J na Macu), aby otworzyć menu narzędzi programisty. Wybierz zakładkę Lighthouse, zaznacz pole kategorii SEO i wygeneruj raport.

Przeglądarka Google Chrome Zrzut ekranu z kategorii narzędzi dla programistów Lighthouse.
Przeglądarka Google Chrome Zrzut ekranu z kategorii narzędzi dla programistów Lighthouse. (duży podgląd)

Użyj uporządkowanych danych

Wyszukiwarka Google korzysta z danych strukturalnych, aby zrozumieć przeznaczenie treści na Twojej stronie internetowej.

Dane strukturalne to ustandaryzowany format dostarczania informacji o stronie i klasyfikowania zawartości strony; na przykład na stronie z przepisami, jakie są składniki, czas i temperatura gotowania, kalorie i tak dalej.
- Google

Zanim zaczniesz kodować, Google przygotował również przydatną listę typowych błędów danych strukturalnych i odpowiednie wskazówki, jak je naprawić. Przestudiowanie tego materiału powinno dać ci dobry punkt odniesienia, czego należy unikać.

Frederick O'Brien napisał doskonały przewodnik na temat magazynu Smashing, Baking Structured Data Into The Design Process , w którym opisuje, jak budować dane strukturalne od samego początku.

Przyjazne dla użytkownika powiadomienia i prośby o pozwolenie

Wreszcie, możesz zwiększyć wygodę użytkownika, optymalizując powiadomienia i prośby o pozwolenie, aby służyły Twoim użytkownikom — a nie tylko mylące i denerwujące.

Chociaż generalnie możesz polegać na zdrowym rozsądku, istnieją również praktyczne wskazówki, które możesz wdrożyć, takie jak tworzenie nieinwazyjnych powiadomień push i umożliwienie użytkownikowi rezygnacji z otrzymywania wiadomości.

Subtelne prośby o pozwolenie na komunikację

Istnieją dwa nowoczesne sposoby automatyzacji komunikacji między stroną internetową a użytkownikiem — chatboty i powiadomienia.

W kontekście PWA główną zaletą chatbota jest to, że nie wymaga on zgody użytkownika na interakcję z użytkownikiem. Jednak w zależności od tego, z jakiej aplikacji chatbota korzystasz, użytkownik może przegapić subtelną wiadomość. Z drugiej strony powiadomienia wymagają zgody użytkownika, ale są znacznie bardziej widoczne.

Ponieważ możesz dodać chatbota jako oddzielną aplikację innej firmy, skupmy się na stworzeniu przyjaznego dla użytkownika powiadomienia push. Jeśli potrzebujesz przewodnika, jak utworzyć powiadomienie push, oto świetny, autorstwa Indreka Lasna.

Najprostszym sposobem utworzenia nieinwazyjnego żądania uprawnień jest użycie podwójnego żądania. Oznacza to, że umieszczasz niestandardową interakcję w swojej witrynie nad domyślną interakcją z systemu operacyjnego użytkownika.

Matt Gaunt oferuje doskonałe ilustracje tego efektu za pomocą poniższych obrazów.

Oto domyślne żądanie uprawnień do powiadomień, które nie zawiera kontekstu:

Przykład złego pozwolenia na UX
Przykład nieprawidłowego żądania pozwolenia UX przez Permission UX. (duży podgląd)

A oto niestandardowa interakcja dodana przed domyślnym uprawnieniem do powiadamiania opisanym powyżej:

Przykład dobrej prośby o pozwolenie UX
Przykład dobrej prośby o pozwolenie UX przez Permission UX. (duży podgląd)

Dodając alert niestandardowy przed alertem domyślnym systemu operacyjnego, możesz wyraźniej opisać użytkownikowi cel powiadomienia. Zwiększa to szansę, że użytkownik zdecyduje się na powiadomienia z Twojej witryny.

Zezwól użytkownikowi na rezygnację z powiadomień

Dla użytkownika wyłączenie powiadomień push witryny jest dość irytujące, niezależnie od urządzenia, z którego korzysta. Dlatego umożliwienie użytkownikowi rezygnacji z otrzymywania wiadomości ma duży wpływ na wrażenia użytkownika.

Oto przykład od Matta Gaunta, jak zaimplementować funkcję anulowania subskrypcji w kodzie i interfejsie użytkownika:

Najpierw zdefiniuj detektor kliknięć przycisku pushButton :

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

Następnie dodaj nową funkcję:

 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(); }); }

Oto jak to wygląda w konsoli po pomyślnym zaimplementowaniu przycisku subskrypcji, aby wyłączyć powiadomienia, jeśli użytkownik wybierze.

Console.log przykład pomyślnego włączenia/wyłączenia funkcji powiadomień
Console.log przykład pomyślnej funkcji włączania/wyłączania powiadomień autorstwa Matta Gaunta. (duży podgląd)

Wniosek

PWA mogą być niezwykle skuteczne w zwiększaniu ruchu w Twojej witrynie i zwiększaniu wygody użytkowników. Aby jeszcze bardziej zoptymalizować PWA, możesz użyć tych nowoczesnych rozwiązań opisanych w tym artykule, aby zwiększyć wydajność i funkcjonalność.

Nie musisz też wdrażać wszystkiego na raz. Zachęcamy do wybrania najbardziej odpowiednich opcji, ponieważ każda z tych sugestii pomoże Ci rozwinąć PWA.

Dalsze zasoby

  • Szkolenie z progresywnych aplikacji internetowych od Google
  • Progresywne aplikacje internetowe od web.dev
  • Progresywne aplikacje internetowe (PWA) firmy Mozilla