Skip to content
This repository has been archived by the owner on Jan 23, 2021. It is now read-only.

Do a better job of explaining dynamicUrlToDependencies #156

Open
jeffposnick opened this issue Aug 24, 2016 · 11 comments
Open

Do a better job of explaining dynamicUrlToDependencies #156

jeffposnick opened this issue Aug 24, 2016 · 11 comments

Comments

@jeffposnick
Copy link
Contributor

dynamicUrlToDependencies important concept for any site that includes server-side rendering and which uses partial templates/includes to produce a final HTML resource. However, it's importance and use cases aren't explained as well as they should be in the documentation.

I think the actual https://github.com/GoogleChrome/sw-precache#dynamicurltodependencies-objectstringarraystring entry can be expanded some, as well as incorporating an explanation of why it's useful into the main text of the docs.

Also, renaming it as part of a major version change could help.

CC: @addyosmani @jpmedley

@addyosmani
Copy link
Contributor

After re-reading our current docs around dynamicUrlToDependencies a few times, I think the current naming is actually fine.

What we could do is expand the paragraph explaining why it's useful to include a few more practical examples. The current Jade one is great. Maybe include a PHP one (it's sadly still super popular on the server) .

@wernight
Copy link

wernight commented Dec 6, 2016

Agree on explaining about the benefit of using it and possibly issues if not using it.

@wernight
Copy link

wernight commented Dec 6, 2016

If I get it correctly, setting a dynamicUrlToDependencies results in that URL being cached (pre-cached?) and only updated if that template changes. It should never be used if that URL contains dynamic content.

@HenrikJoreteg
Copy link
Contributor

HenrikJoreteg commented Mar 7, 2017

@jeffposnick @addyosmani related to this, it'd be nice if I could supply my own hash or even have the "dependency" part of this just be a string of HTML. We have a scenario where we're the HTML is mostly static, but a few environment-specific items get changed depending on where it's running.

So the we're generating html on the fly, once... based on an aggregated config object. So, there isn't really a single file somewhere (like a .jade file) that we can point to and say, "any time this changes the content is different." Instead, we generate an HTML string that is essentially "static" for that environment.

I'm not sure how to best support this from an API perspective.

Perhaps something like this?

dynamicUrlToDependencies: {
   //  if it's an array just have it work as it does currently but... if I'm supplying a string
   // assume that it's already a hash?
   '/': someHashStringDerivedFromMyHTMLString
}

I'd be willing to take a stab at sending a PR with this functionality if you think that would be good. Thoughts??

@HenrikJoreteg
Copy link
Contributor

HenrikJoreteg commented Mar 7, 2017

or even just:

dynamicUrlToDependencies: {
   //  if it's an array just have it work as it does currently but... if I'm supplying an object
   //  just assume i already did the work of hashing/sizing it.
   '/': {
     size: 1639, // whatever stat.size
     hash: '944c9aef2dfdc2b0f3b00c0b861028af' // whatever derived hash
   }
}

☝️ with this approach there's less magic strings, and you'd still retain "total size" calculations

@tconroy
Copy link

tconroy commented Apr 28, 2017

Hi All. I'm having a difficult time understanding dynamicUrlToDependencies in a server-rendered react app, where there are not really any static templates -- the "app shell" / initial markup is a template string, returned from a function.. ie:

function pageTemplate(html, injectedStyles) {
  return `
  <!DOCTYPE html>
  <html lang="en">
    <head>
      <meta charset="UTF-8">
      <style> ${injectedStyles} </style>
    </head>
    <body>
      <div id="root">${html}</div>
      <script src="https://cdn.com/path/vendorsBundle.js" />
      <script src="https://cdn.com/path/appBundle.js" />
    </body>
  </html>
`
}

//  react app setup, generate markup from react
const html = renderToString(
  <Provider store={store}>
    <RouterContext {...renderProps} />
  </Provider>
);

// load above-the-fold styles into memory
const injectedStyles = fs.readFileSync(path.resolve(__dirname, './assets/AboveFold.css'), 'utf8');

// send the generated markup
res.send(pageTemplate());

.. after this initial render, all routing is done client-side.

In a setup like this, how would you use dynamicUrlToDependencies to cache your "app shell" (presumably the contents of pageTemplate()? )

@dmaevac
Copy link

dmaevac commented Aug 31, 2017

@tconroy did you find an answer to this?

@tconroy
Copy link

tconroy commented Sep 1, 2017

Hi @DveMac -- I did not. It seems to be the goals of sw-precache dynamicURLToDependenciesand server-side rendering are diametrically opposed. I ended up rolling my own caching solution without the use of sw-precache.

Quite unfortunate since otherwise liked the library!

@dmaevac
Copy link

dmaevac commented Sep 3, 2017

@tconroy ok, thanks! I noticed the description in another issue you opened here describes pretty much exactly what I am trying to achieve too. At the moment I feel like I can still achieve it with this module, but Im probably not seeing the whole picture yet!
If you ended up documenting/blogging about your solution I would definitely be interested to read about it.

@jeffposnick
Copy link
Contributor Author

Sorry, just revisiting this given the recent activity.

The model that tends to work best for this sort of setup is to make your App Shell HTML generic, and then rely on client-side rendering to populate the content specific to the given URL once the App Shell has been initialized. The runtime JavaScript that's needed to do the client-rendering can be precached, meaning it won't necessarily take a network request in order to get content on the screen.

You can see an example of this at https://github.com/GoogleChrome/sw-precache/blob/master/app-shell-demo/, and in particular, the build configuration at https://github.com/GoogleChrome/sw-precache/blob/master/app-shell-demo/gulpfile.babel.js#L129

The alternative would be to set up a mapping of specific URLs to the final rendered HTML during your build process, taking advantage of the changes in #262 to specify a full string as the dependency rather than a list of files:

{
  dynamicUrlToDependencies: {
    '/page1': pageTemplate(htmlForPage1, injectedStyles),
    '/page2': pageTemplate(htmlForPage2, injectedStyles),
    // etc.
  }
}

That approach will only work if you can ensure that anytime the output of pageTemplate() might change, you have a means of re-running your build process and redeploying your service worker file. Since pageTemplate() is a server-rendered function, you'd presumably want to hook into whatever tooling you're using to deploy updates to your (Express, presumably) backend server, and ensure that your service worker build process is re-run alongside it.

@dmaevac
Copy link

dmaevac commented Sep 5, 2017

Thanks @jeffposnick , I stumbled on https://workboxjs.org and from there found https://github.com/GoogleChrome/application-shell both of which have been super helpful.
I managed to knock together a prototype that is on the right track using workbox and taking cues from the application-shell example.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants