I am struggling with the performance optimizations for scripts and CSS in Asp.Net Core MVC app.
I use bootstrap with LoadCSS to preload it. FontsAwesome CSS and JavaScripts are loaded after the content.
My _Layout page looks something like this.
<head> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1"> <script> LoadCSS script here... </script> <script async defer src="https://use.fontawesome.com/releases/v5.2.0/js/all.js" integrity="sha384-4oV5EgaV02iISL2ban6c/RmotsABqE4yZxZLcYMAdG7FAPsyHYAPpywE9PJo+Khy" crossorigin="anonymous"></script> <link rel="preload" as="style" type="text/css" onload="this.onload=null;this.rel='stylesheet'" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous"> <noscript> <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous"> </noscript> <style> inline critical path CSS here... </style> </head> <body> <div class="container-fluid body-content"> @RenderBody() @RenderSection("scripts", false) </div> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script async src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js" integrity="sha384-o+RDsa0aLu++PJvFqy8fFScvbHFLtbvScb8AjopnFD+iEQ7wo/CG0xlczd+2O/em" crossorigin="anonymous"></script> </body>
This works great and I am getting good performance scores (94 on Google PageSpped), as long as the page does not contain an input form.
For pages that do have input form, performance optimizations stop working, and Google PageSpeed is complaining about render blocking jquery.js and bootstrap CSS. For some reason Bootstrap seems to load twice!? Below is what the PageSpeed says for the pages with the form, other pages don't have this issue.
Remove render-blocking JavaScript:
https://code.jquery.com/jquery-3.3.1.slim.min.js
Optimize CSS Delivery of the following:
https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css
I don't quite understand what is happening here. Somehow, presence of of the form seems to force bootstrap to load early and preload and LoadCSS does not "work".
The form does use client side data validation, possibly this is the culprit.
1 Answers
Answers 1
I managed to resolve the problems. I read on a number of sites that JavaScript should be placed just before closing body tag for best performance, but it seems this advice is somewhat dated. It actually makes more sense to place scripts in the head and use defer. Defer will load them in parallel without blocking rendering and execute them after and in order, which is perfect.
The CSS problem was due to some missing items in inline critical CSS, namely form-control. This was causing the entire CSS to be loaded, for some reason twice. I used penthouse to generate the critical CSS for each page then merged them.
Improved layout page:
<head> <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1"> <script> LoadCSS script here... </script> <script async defer src="https://use.fontawesome.com/releases/v5.2.0/js/all.js" integrity="sha384-4oV5EgaV02iISL2ban6c/RmotsABqE4yZxZLcYMAdG7FAPsyHYAPpywE9PJo+Khy" crossorigin="anonymous"></script> <link rel="preload" as="style" type="text/css" onload="this.onload=null;this.rel='stylesheet'" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous"> <noscript> <link rel="stylesheet" type="text/css" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" integrity="sha384-Smlep5jCw/wG7hdkwQ/Z5nLIefveQRIY9nfy6xoR1uRYBtpZgI6339F5dgvm/e9B" crossorigin="anonymous"> </noscript> <style> inline critical path CSS here... </style> <script defer src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script defer src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> <script defer src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script> </head> <body> <div class="container-fluid body-content"> @RenderBody() @RenderSection("scripts", false) </div> </body>
0 comments:
Post a Comment