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

Caching assets only for production environment #10919

Conversation

grabcode
Copy link
Contributor

@grabcode grabcode commented Nov 14, 2016

Motivation

In the context of a webview, one may extract assets (javascript or any types really), and relates to them through the html.

The packager Server serves this files correctly but also applies a cache based on time (a year). During development, this cache is actually bad as we need to re-iterate the process of editing/testing quickly.

I don't believe it is necessary to cache, and still wanted to make sure we would if process.env.NODE_ENV is 'production'.

Test plan

Run jest on impacted files:

node_modules/.bin/jest packager/react-packager/src/Server/__tests__/Server-test.js

@facebook-github-bot
Copy link
Contributor

By analyzing the blame information on this pull request, we identified @davidaurelio and @frantic to be potential reviewers.

@facebook-github-bot facebook-github-bot added GH Review: review-needed CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. labels Nov 14, 2016
@ide
Copy link
Contributor

ide commented Nov 14, 2016

I find it to be a significant source of subtle bugs when development and production modes differ, especially for something as important as caching. We should either always cache or never cache. Perhaps it make sense to expose an explicit flag for that but it should be independent of dev vs. production.

In this case, the asset URL uses content addressing so I'd expect that modifying your assets will always bust the cache. And could you clear the cache on the device instead when needed?

@dannycochran
Copy link
Contributor

In this case, the asset URL uses content addressing so I'd expect that modifying your assets will always bust the cache. And could you clear the cache on the device instead when needed?

Modifying the asset URL will bust the cache but not the content. So, I've been doing stuff like "src='js/main.js?version=123'" to see changes. Clearing the cache on the device might work but would be fairly cumbersome to do on every change & reload cycle.

A cacheControl propType (number) for the webview seems reasonable?

Copy link
Contributor

@ericvicenti ericvicenti left a comment

Choose a reason for hiding this comment

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

cc @davidaurelio, this looks like a reasonable change. Can you predict any breakage this would cause? Could it potentially slow down development build times?

@@ -379,7 +379,7 @@ describe('processRequest', () => {

server.processRequest(req, res);
jest.runAllTimers();
expect(res.setHeader).toBeCalledWith('Cache-Control', 'max-age=31536000');
// expect(res.setHeader).toBeCalledWith('Cache-Control', 'max-age=31536000');
Copy link
Contributor

Choose a reason for hiding this comment

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

Lets avoid commenting out lines and leaving them in here. Can we just remove them instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course.

@ide
Copy link
Contributor

ide commented Nov 14, 2016

Can you change this to another env var ex: REACT_NATIVE_ENABLE_ASSET_CACHING?

@grabcode grabcode force-pushed the fix/caching-webview-asset-on-prod-only branch from 9ca893f to ada7912 Compare November 14, 2016 21:54
@grabcode
Copy link
Contributor Author

All done. Thanks for reviewing so quickly.

@@ -502,7 +502,9 @@ class Server {
data => {
// Tell clients to cache this for 1 year.
// This is safe as the asset url contains a hash of the asset.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this comment not true any longer, or is it only referring to the urls of require('d assets? Either way, we should update this comment and explain the intention. Not every app serves to WebViews so people may forget why this is the default.

@mkonicek
Copy link
Contributor

mkonicek commented Nov 23, 2016

This change seems reasonable and I wonder why we had the caching in the first place.

I pinged @davidaurelio on messenger to ask before we merge this.

@davidaurelio
Copy link
Contributor

lgtm

@facebook-github-bot
Copy link
Contributor

@davidaurelio has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@grabcode
Copy link
Contributor Author

Thanks @davidaurelio & @mkonicek. Should I delete the branch?

@cpojer
Copy link
Contributor

cpojer commented Nov 28, 2016

Quick question: why do we need an env var to bring this behavior back? I'd prefer to limit the number of obscure env variables we support.

@ericvicenti
Copy link
Contributor

ericvicenti commented Nov 28, 2016

Good point, it is obscure. The term 'production' is used here in a misleading way. RNP is never serving prod- only for development and production builds.

I would be in support of removing this caching feature entirely. Does anybody have a use case for it?

@dannycochran
Copy link
Contributor

@ericvicenti presumably there should be a small latency improvement when caching assets, no? The flag could be useful for production builds still.

@ide
Copy link
Contributor

ide commented Nov 28, 2016

I'm still a little confused about why we couldn't always enable caching since the asset URL contained a hash of the asset. That is, there should never be stale or incorrect caches with that approach.

@jeanregisser
Copy link
Contributor

I'm the one who added the cache header in the first place. This was to fix local images being reloaded from the packager everytime they were displayed.
See #9795
The current merged change breaks it again.

I think the problem here is the packager not recomputing the hash and hence not providing a new url when the asset content actually changes.

DanielMSchmidt pushed a commit to DanielMSchmidt/react-native that referenced this pull request Jan 4, 2017
Summary:
**Motivation**

In the context of a webview, one may extract assets (javascript or any types really), and relates to them through the html.

The packager `Server` serves this files correctly but also applies a cache based on time (a year). During development, this cache is actually bad as we need to re-iterate the process of editing/testing quickly.

I don't believe it is necessary to cache, and still wanted to make sure we would if process.env.NODE_ENV is 'production'.

**Test plan**

Run jest on impacted files:
```
node_modules/.bin/jest packager/react-packager/src/Server/__tests__/Server-test.js
```
Closes facebook#10919

Differential Revision: D4226350

Pulled By: davidaurelio

fbshipit-source-id: d4bbff5b1a5b691aab197bcddb8fa9d2e43caa16
cpojer pushed a commit to facebook/metro that referenced this pull request Jan 26, 2017
Summary:
**Motivation**

In the context of a webview, one may extract assets (javascript or any types really), and relates to them through the html.

The packager `Server` serves this files correctly but also applies a cache based on time (a year). During development, this cache is actually bad as we need to re-iterate the process of editing/testing quickly.

I don't believe it is necessary to cache, and still wanted to make sure we would if process.env.NODE_ENV is 'production'.

**Test plan**

Run jest on impacted files:
```
node_modules/.bin/jest packager/react-packager/src/Server/__tests__/Server-test.js
```
Closes facebook/react-native#10919

Differential Revision: D4226350

Pulled By: davidaurelio

fbshipit-source-id: d4bbff5b1a5b691aab197bcddb8fa9d2e43caa16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants