TrilonIO / aspnetcore-angular-universal

ASP.NET Core & Angular Universal advanced starter - PWA w/ server-side rendering for SEO, Bootstrap, i18n internationalization, TypeScript, unit testing, WebAPI REST setup, SignalR, Swagger docs, and more! By @TrilonIO
https://www.trilon.io
MIT License
1.46k stars 434 forks source link

Browser caching (Azure) and Minify JavaScript on build #541

Closed hakonamatata closed 6 years ago

hakonamatata commented 6 years ago

Hi

Great work on version 5.0 @MarkPieszak :heart:

Want to show a really nice image I got after uploading the new version to Azure. (Did comment out the translate part)

Google PageSpeed Insights results

That is very close to a perfect score from Google Pagespeed insight!

The only thing missing is Minifying the .js files, it would be nice to add this to the build process.

This is already in the webpack.config.js so I guess this is meant to be added at some point

        // new webpack.optimize.UglifyJsPlugin({
        //   compress: false,
        //   mangle: false
        // }),
        // Plugins that apply in production builds only

Second part, this might be just a Azure thing, but I haven't been able to set the expiration date of the files.

I tried adding this to web.config:

<staticContent>
  <clientCache cacheControlMode="UseMaxAge" cacheControlMaxAge="7.00:00:00" />
</staticContent>
<httpProtocol>
  <customHeaders>
    <add name="Cache-Control" value="public" />
  </customHeaders>
</httpProtocol>

But I still get

http://angularuniversal.azurewebsites.net/dist/0.js (expiration not specified)
http://angularuniversal.azurewebsites.net/dist/main-client.js (expiration not specified)
http://angularuniversal.azurewebsites.net/dist/vendor.js (expiration not specified)

Does anyone know a solution for this?

Flood commented 6 years ago

In your startup.cs you can write

app.UseStaticFiles(new StaticFileOptions()
            {
                OnPrepareResponse = context =>
                {
                    //Do not add cache to json files. We need to have new versions when we add new translations.

                    if(!context.Context.Request.Path.Value.Contains(".json")) { 
                        context.Context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
                        {
                            MaxAge = TimeSpan.FromDays(30) //Cache everything except json for 30 days
                        };
                    } else {
                        context.Context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
                        {
                            MaxAge = TimeSpan.FromMinutes(15) //Cache json for 15 minutes
                        };
                    }
                }
            });

This will add 30 days cache to all files except .json files.

MarkPieszak commented 6 years ago

So the problem with Uglify is that it'd complicate the build process a bit, in that - if you truly want to "Uglify", you can't have a Vendor file. So we'd have different ones for Dev & Prod.

All of that leg work and complicated webpack builds has been setup in the CLI, so when we move to that - we'll immediately get to reap all the benefits :)

Glad it's working so far for everyone though ! :+1: Pumped.

hakonamatata commented 6 years ago

Thanks @Flood, that worked perfectly!

Added this to Startup.cs:

      // app.UseStaticFiles();

      app.UseStaticFiles(new StaticFileOptions()
      {
        OnPrepareResponse = c =>
        {
          //Do not add cache to json files. We need to have new versions when we add new translations.

          if (!c.Context.Request.Path.Value.Contains(".json"))
          {
            c.Context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
            {
              MaxAge = TimeSpan.FromDays(30) // Cache everything except json for 30 days
            };
          }
          else
          {
            c.Context.Response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue()
            {
              MaxAge = TimeSpan.FromMinutes(15) // Cache json for 15 minutes
            };
          }
        }
      });

30 day caching

desktop

phone

Perfect score on phone and close to perfect on desktop! Very impressive.

I suggest we add Floods code to the repo, I could make a pull request, but don't want to take credit for @Flood's code 😜

I understand @MarkPieszak πŸ‘

Flood commented 6 years ago

Haha, no worries! Go ahead! πŸ‘

MarkPieszak commented 6 years ago

I think it's a good idea, let's add it in there! Send a PR whenever 🍾

hakonamatata commented 6 years ago

done and done. I'm closing this issue since everything is resolved now.