Proposal 3 is certainly the most efficient, however it is also the most time consuming to implement. Memcache doesn't include this feature, so you'd either have to find some other framework or roll your own (using Gearman in this case). It's not super hard, but it's not trivial and it adds a significant moving part to your system that can fail. I'd make sure to d all the appropriate research before committing to any decision. You might find that proposal 1/2 won't be a huge bottleneck after all and you could save yourself several days of time.
This sounds suspiciously like you're trying to invent output caching. I definitely wouldn't agree that it's hard to do partial page caching in MVC, it's just that you would need to use partial Views with their own Controller actions to do it as opposed to having the View itself call its sub-Views, which can be slightly counter-intuitive. (So in ASP.net MVC you'd want to use Html.RenderAction as opposed to Html.RenderPartial). There's a name for this particular pattern that is currently escaping my recollection.
I would suggest that the main flaw with your design is that Views will have to know things about the architecture of the site. So they'll have to know about where to get their data from AND how to get it, they'll have to know about where to cache it, when to cache it, when not to cache it, etc.
Realistically you should be trying to separate layers away from knowledge of other layers, as the less knowledge each layer has of another the easier it is to change a layer (i.e. switch DB, add a transparent data caching layer, move a DB call across to a web service, etc.).
I would suggest that if you're going to implement such an idea, and there isn't a native output caching system in your MVC-framework-of-choice, that you add the caching layer to the Controller actions. Unless you've got some VERY heavyweight Views that need to do large amounts of recursive rendering of Models (something that's very rare) the actual HTML generation time is miniscule compared to DB calls and client network latency, so take a more pragmatic approach and cache where you need to cache, i.e. in the application layer.
If you really need custom output caching then you probably want to just slip in a caching layer above your Controller actions with either a wrapping class (if you're using a dynamic language) or a different implementation of an interface (if in a static language) that can hijack the calls to the Action and react accordingly.
As for caching that reacts to DB changes, you'd be better off with a caching layer that takes into account both loading and saving in your repository class, with each save call flushing the cache (or part of the cached set) and each load being gracefully degraded from cache to DB when needed (i.e. use the cache when the cached data is available). That way you keep the database driven behaviour close to the database.
Best Answer
You need a cache busting solution. The role of cache busting is:
In a Grunt-based project it's common to use grunt-rev to ensure that all files that need to be refreshed are given unique names, based on their content.
If you ensure that your JSON files get cachebusting filenames along with the references to them in your Javascript, clients will always load the JSON files that the Javascript expects.
The advantage of hash-based file naming is that files that have not changed will get the same filenames after cache-busting, so browsers can continue to safely use cached content when it has not changed.
Obviously this is the kind of thing you want to be automated as part of your project's production build so you don't have to keep track of changing file names & references manually.