Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supplant MagentoRouteHandler #1966

Merged
merged 9 commits into from
Nov 13, 2019
Merged

Supplant MagentoRouteHandler #1966

merged 9 commits into from
Nov 13, 2019

Conversation

jimbo
Copy link
Contributor

@jimbo jimbo commented Nov 8, 2019

Description

Now that we're using React Router 5.1.0, which includes hooks and real context, we no longer need our customized router. Not only can we replace custom code with canonical implementations (similar to our adoption of Apollo hooks), we can eliminate render props at the base of the app, which should improve rendering performance across the board.

Added

  • The new Routes component replaces renderRoutes()
  • The new MagentoRoute component replaces MagentoRouteHandler
  • The new useMagentoRoute talon replaces MagentoRouteHandler

Changed

  • VeniaAdapter now renders BrowserRouter directly
  • The Apollo client object now exposes apiBase

Related Issue

PWA-137

Acceptance

This is a one-for-one refactor; just ensure there no regressions.

Verification Stakeholders

@dpatil-magento

Verification Steps

  1. Navigate to the home page
  2. Navigate to a category page and product page
  3. Navigate to a known nonexistent page (e.g., /foo.html)
  4. Navigate to the search page

Checklist

  • I have not updated the documentation accordingly, if necessary.
  • I have not added tests to cover my changes, if necessary.

@jimbo jimbo added version: Minor This changeset includes functionality added in a backwards compatible manner. version: Major This changeset includes incompatible API changes and its release necessitates a Major version bump. and removed version: Minor This changeset includes functionality added in a backwards compatible manner. labels Nov 8, 2019
@PWAStudioBot
Copy link
Contributor

PWAStudioBot commented Nov 8, 2019

Messages
📖

Access a deployed version of this PR here. Make sure to wait for the "pwa-pull-request-deploy" job to complete.

📖 DangerCI Failures related to missing labels/description/linked issues/etc will persist until the next push or next nightly build run (assuming they are fixed).
📖

Associated JIRA tickets: PWA-137.

Generated by 🚫 dangerJS against 79b9b33

Copy link
Contributor

@revanth0212 revanth0212 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel we should use the SW for caching purposes instead of manipulating cache ourselves. Along with that couple other minor requests/queries.

@@ -0,0 +1,15 @@
const addToCache = async (...urls) => {
if (!window.caches) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is good to see caching but can we delegate this work to the SW? 2 reasons:

  1. No main thread cycles wasted
  2. cacheName can change in the future and having it hardcoded here can be a potential cause for bugs. We can leave this to the SW and if the cacheName changes in the future workbox will take care of it.

You can use sendMessageToSw to send a message along with the list of URL you want to cache and have a handler on the SW do the caching part.

For instance:

On the UI:

sendMessageToSW('PREFETCH_URLS', { urls: ['https://develop.pwa-venia.com/main.css', 'https://develop.pwa-venia.com/font.woff'] })

In SW:

registerMessageHandler('PREFETCH_URLS', prefetchUrls)

Check out this example:

registerMessageHandler(PREFETCH_IMAGES, handleImagePreFetchRequest);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good feedback, I agree with you on all points. I'd like to handle the change in a separate PR, though. This one is just a 1:1 refactor—nothing about addToCache has changed here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addToCache implementation is different here, though. The original implementation had some big problems, so I'm not about bringing it back, but I think this isn't populating the cache correctly. Can you confirm that it's actually caching and reusing the urlResolver responses? I think this is just caching an app shell instead of a GraphQL response.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Call me crazy, but did I do something other than just move this code into its own file?

packages/venia-ui/lib/components/Routes/routes.js Outdated Show resolved Hide resolved
Copy link
Contributor

@supernova-at supernova-at left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

@zetlen made some changes recently so that we might recover from a temporary error state (and not cache it and return it forevermore).

Just making sure these changes don't regress that functionality.

@@ -1 +0,0 @@
export { default } from '../../components/SearchPage';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this felt redundant 👍

Copy link
Contributor

@zetlen zetlen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extremely in favor of this. There are other optimizations that we ought to do for resolving unknown routes, but you're right that this PR's scope is just right as it is.

Not explicitly approving because I'd like to know if the addToCache implementation is actually working. Here's the repro for that.

  1. Clear app cache, start a new (non-incognito) session.
  2. Load homepage.
  3. Click Dresses category
  4. Back button to homepage
  5. Soft-refresh page to wipe in-memory cache
  6. Open network inspector, make sure cache is not disabled
  7. Click Dresses category again

Expected: It reuses the cached route resolution and doesn't call /graphql again with urlResolver.

If the cache is working, that's great. If it isn't working, can we just comment it out for now? (The original cache had no TTL, so I'm glad it's gone.)

@@ -0,0 +1,15 @@
const addToCache = async (...urls) => {
if (!window.caches) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addToCache implementation is different here, though. The original implementation had some big problems, so I'm not about bringing it back, but I think this isn't populating the cache correctly. Can you confirm that it's actually caching and reusing the urlResolver responses? I think this is just caching an app shell instead of a GraphQL response.

const getRouteComponent = async (apiBase, pathname) => {
// At build time, `fetchRootComponent` is injected as a global.
// Depending on the environment, this global will be either an
// ES module with a `default` property, or a plain CJS module.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very clear, thank you.

} catch (e) {
const routeError = e.message === '404' ? NOT_FOUND : INTERNAL_ERROR;

console.error(e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this, too.

@sirugh
Copy link
Contributor

sirugh commented Nov 12, 2019

Expected: It reuses the cached route resolution and doesn't call /graphql again with urlResolver.

I'm getting the expected outcome. Can someone else check this as well?

Copy link
Contributor

@sirugh sirugh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments, nothing hold this PR up. Great work!

Also, FWIW I tried to repro the issue with addToCache that @zetlen mentioned but I could not. Hopefully someone else can double check!

return client;
}, [apiBase, apollo]);

return (
<ApolloProvider client={apolloClient}>
<ReduxProvider store={store}>
<Router apiBase={apiBase}>{children}</Router>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify we are intentionally not removing the unused Router implementation right? We also have some old devdocs for it so I want to make sure we're not leaving outdated references lying around.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. I didn't delete any of the old implementations since it wasn't strictly necessary to achieve the goal here. So we have a choice:

  • Remove unused files, such as Router and MagentoRouteHandler
  • Deprecate unused files, but remove them later on

@@ -9,7 +9,7 @@ import Main from '../Main';
import Mask from '../Mask';
import MiniCart from '../MiniCart';
import Navigation from '../Navigation';
import renderRoutes from './renderRoutes';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here -- we're not deleting the old stuff on purpose, right?

}

// add the pathname to the browser cache
addToCache(pathname);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the old implementation we had a catch that logged errors in development. Can we add that here? I know we're probably changing this soon so nbd either way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that is here still. One of the other reviewers suggested that I remove the process.env check since it was redundant, so I did that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, didn't realize we eliminated consoles in prod.

@dpatil-magento dpatil-magento merged commit d0164ba into develop Nov 13, 2019
@dpatil-magento dpatil-magento deleted the jimbo/magento-routes branch November 13, 2019 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg:peregrine pkg:venia-ui version: Major This changeset includes incompatible API changes and its release necessitates a Major version bump.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants