Next.js: Safari cache on dev

Created on 11 Dec 2018  路  13Comments  路  Source: vercel/next.js

The context
Safari 12.0.1
nextjs in dev mode
/pages/index.js with simplest react code:

import React from 'react'

class PageIndex extends React.Component{
    constructor(props){
        super(props)
    }
    render(){
        return (<div>123</div>)
    }
}
export default PageIndex;

Behaviour

  1. I change text to 1234
  2. Change blinks to 1234 and gets back to 123
  3. In network I see "in memory" near index.js
  4. This little icon in network, develop->empty caches, option + cmd + R, alltogether has no impact on this fact
bug p2 needs investigation

Most helpful comment

Still having this issue also. Not being able to use Safari for development is a real bummer.

All 13 comments

I can't reproduce this issue, tried on codesandbox: https://codesandbox.io/s/l2zqw773kz

@timneutkens It's definitely an issue, I can repro it too.

CodeSandbox is not really an accurate reproduction of how people run development mode. For example, clearly CodeSandbox is running everything through some kind of HTTPS proxy, because that hello world page is served over HTTPS right? But the dev server you get when you run next dev does not serve up via HTTPS, and HTTPS is something that could easily be influencing the browser's caching decisions.

I did some experiments and here's what I found:

  • The <link rel="preload"> that Next.js adds for resources like pages/index.js greatly affects how Safari decides to honor cache headers like Cache-Control.
  • When I remove the preload completely, Safari will correctly get the script every time.
  • When I add crossorigin="anonymous" to the preload, Safari doesn't refetch it every time, but appears to bust its own cache (which shouldn't exist for the file in the first place) after a few seconds, so more refreshes do eventually refetch it (instead of never refetching).

This is most likely an issue with Safari's preload handling unless there's some special cache handling defined for preload that I'm not aware of. But, it would be nice if Next.js were aware of real-world issues like this and worked around them. Is preload actually useful in dev mode? It seems like probably not, since there are far greater inefficiencies anyway like unminified bundles, hot-reload updates, etc.

I was actually able to reproduce it on CodeSandbox too, so there did not end up being a difference there.

Potentially relevant bug: https://bugs.webkit.org/show_bug.cgi?id=187726

Interesting, so let's re-open this, I guess we could drop the preload tags in development 馃

link-rel-preload primes the memory cache which I believe is per connection and crossorigin="anonymous" forces the request into a different connection. The disk cache, however, (surprisingly) ignores the crossorigin-ness.

Script and link element must definitely have the same crossorigin value (or none).

@cramforce so by default Next.js won't add crossorigin to both, meaning it's potentially an issue with the way safari handles it? 馃 Basically in development the bundles all have the same url and the Cache-Control header is the following:
https://github.com/zeit/next.js/blob/canary/packages/next/server/next-dev-server.js#L130

I just noticed that for error pages we set a different Cache-Control that is more involved: https://github.com/zeit/next.js/blob/canary/packages/next-server/server/next-server.ts#L247

Potentially implementing that for dev assets would make sense 馃

@timneutkens Maybe switch from the header to a per page-load random value as part of the URL. Would also defend against overzealous ServiceWorkers.

@timneutkens When I was experimenting with this I actually tried changing that exact line with all manner of caching headers including max-age, no-cache, an Age that was clearly over the max, etc. and Safari just ignored all of them, unfortunately.

Looks like it started to work after I add ?date=Date.now() to page links in Next sources.

Still having this issue also. Not being able to use Safari for development is a real bummer.

I am having the same issue with my Safari.

Workaround which works for me is:
CMD+ALT+E _(Safari > Develop > Empty Caches)_

I'm seeing this today with Safari 13.0.4 and Next.js 9.1.7.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jesselee34 picture jesselee34  路  3Comments

kenji4569 picture kenji4569  路  3Comments

DvirSh picture DvirSh  路  3Comments

rauchg picture rauchg  路  3Comments

knipferrc picture knipferrc  路  3Comments