magento / pwa-studio

🛠Development tools to build, optimize and deploy Progressive Web Applications for Magento 2.
https://developer.adobe.com/commerce/pwa-studio/
Open Software License 3.0
1.07k stars 683 forks source link

Implement basic offline experience for Venia (PWA) #374

Closed ericerway closed 5 years ago

ericerway commented 6 years ago

This issue is for the following packages:

[ ] venia-concept [ ] pwa-buildpack [X] peregrine [ ] pwa-module [ ] pwa-devdocs

Description

As a shopper, I want basic feedback on the Venia storefront when my device is having connectivity issues or offline so that I know that I can have an uninterrupted shopping experience.

This is a requirement for PWA per Google Lighthouse and applies to all of the Venia storefront.

Assumptions

Tasks

ericerway commented 6 years ago

Kamino cloned this issue to magento-research/pwa-studio

ericerway commented 6 years ago

Marking as in progress from @pcvonz and team -- preview here: http://upward.bargreen.io

pcvonz commented 6 years ago

Some notes on the obstacles I've encountered so far. Let me know if anything sounds incorrect:

Problem: Refreshing a page when offline results in a cache miss if that page wasn't refreshed directly. When first visiting Venia, upward will return an html file, however, every subsequent load doesn't, which creates a problem when trying to cache every visited page.

Possible Solution: This is a pretty easy fix: Cache requests in the MagentoRouteHandler. Recipe for how to access the cache in the Workbox docs.


Problem: The fetchRoute function of resolveUnkownRoute in Peregrine makes a POST request to the graphql endpoint. Caching of graphql queries in venia is solved pretty easily with apollo-cache-persist, but that isn't the case with Peregrine.

Possible Solution: (slap dash, probably not what we want)

Bypass MagentoRouteHandler when offline and request the html file from Cache.

Possible Solution 2:

Probably the way it should be done :sweat_smile:

Cache each query to urlResolver to localStorage:

    {
        '/': {data: {urlResolver: {type: "CMS_PAGE", id: 2}}}
        '/crown-summit-backpack.html': {data: {urlResolver: {type: "PRODUCT", id: 3}}}
    }

Is it weird if we use apollo-cache-persist in Venia and then cache the urlResolver queries manually? I guess if we're caching a lot of stuff in Peregrine we may want to add the ability to hook in different storage providers(?)


Related issue in the Workbox repo

Hopefully that all makes sense, I'm still learning this as I go along. It's also pretty late on a Friday :smile:

@zetlen @rowan-m

pcvonz commented 6 years ago

Possible solution 3 (for the fetchRoute POST problem):

Looks like the ability to make a GET request to the graphql endpoint has already come up. There is an issue for it in the graphql-ce repo[1]. Once this is implemented, caching the response from fetchRoute should be easy.

[1] Related issue

rowan-m commented 6 years ago

Great progress so far! Adding a few comments here on things I've seen. They may not all be relevant to this issue, but I wanted to make sure it's down.

  1. As per the Lighthouse audit, the manifest is missing the 192px and 512px icons.
  2. As per the Lighthouse audit, the manifest is missing a "theme_color"
  3. Definitely happier with only trying to cache GET requests.
  4. The manifest has a .webmanifest extension, which is fine but .json is more the convention. Sending the content-type: application/json header would be good though. I don't see any header currently.
  5. Not sure about the homescreen entry in the upward config. Given that at least 3 icon sizes are needed, I feel like this is better served as static content.
  6. Enhancement: Offline page should should be able to intelligently continue to the content once the connection is restored. This should be with a combination of listening for the online event and a configurable timeout (default to 30 sec) when the the request will be retried.
  7. Enhancement: Ideally, the user should have some indication when they are being served offline content. This is tricky from a UX point of view because it's hard to tell the difference between just using the cache for a slow connection versus really being offline. A reasonable compromise is showing a persistent indicator (toast, banner, etc) when navigator.onLine is not true.
  8. Discussion: Product pages probably need more sophisticated caching based on business, commercial, or even regulatory needs. Cache needs an expiry at the least. Should other aspects be changed when serving from cache - for example, showing the price?
pcvonz commented 6 years ago

Offline indicator demo: Notification appears at the top of the page (not fixed). Once the user is online again it disappears and loads the page. online_offline_online