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.
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>
Related
I am trying to hook up summernote wysiwyg with Laravel 8, no matter what I do I am getting a constant jquery error. I have tried to use webpack for the scripts and added scripts directly to the page. The order to my scripts should be correct and I am executing the code after the scripts However, the error is a basic error and I can't nail down the issue.
The webpack file is default and I have run npm run dev & prod.
The code listed put into a basic HTML file runs with no errors, there must be something I am doing with Laravel.
jquery.js:4055 Uncaught TypeError: "#summernote".summernote is not a function
App.blade.php
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Scripts -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script type="text/javascript" rel="script" src="{{asset('js/app.js')}}" ></script>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
//rest of the template is out of the box Laravel base install with auth installed
<form method="post">
<textarea id="summernote" name="editordata"></textarea>
</form>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
<link href="https://cdn.jsdelivr.net/npm/summernote#0.8.18/dist/summernote-bs4.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/summernote#0.8.18/dist/summernote-bs4.min.js"></script>
<script type="text/javascript" rel="script" src="{{asset('js/main.js')}}" ></script>
</body>
</html>
Main.js
jQuery(document).ready(function() {
/* $('#summernote').summernote({
placeholder: 'Hello Bootstrap 4',
tabsize: 2,
height: 100 */
// Code still produces the error here
});
});
$('#summernote').summernote({
placeholder: 'Hello Bootstrap 4',
tabsize: 2,
height: 100
});
// Code still produces the error here
Happy to provide more information, help will be greatly appreciated.
This works for me with these
Before the end of </thead>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/summernote#0.8.18/dist/summernote.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/summernote#0.8.18/dist/summernote.min.js"></script>
Inside <form>
<div id="summernote"></div>
Before the end of </body>
<script>
$(document).ready(function() {
$('#summernote').summernote();
});
</script>
Jsfiddle Preview
Useful links
Summernote Getting started
Summernote Examples
Issue might be Summernote get loaded before the JQuery library
I found a solution, I cant take credit. An older slightly related Laravel issue had a solution:
Laravel 5.4 Script loading issue
The contributor is #jordan
By isolating the script into a #section and adding $yield('scripts') below the js files solved the problem. Still not sure what Laravel is doing to the scripts as the page loads, but I have a solution. Thanks for all of your help those who contributed, I always value the input and suggestions.
I created a visualization using x3dom and d3. When I execute it as a single html file (html and js code in one file) it works fine. When I include in my website x3dom does not load properly anymore.
I broke it done to an issue loading the x3dom script.
I have a main side with the following head:
<meta charset="UTF-8">
<title>Title</title>
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="https://x3dom.org/download/1.7.2/x3dom.css" />
<link rel="stylesheet" href="stylesheet.css">
<script defer
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<script defer src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script defer src="https://d3js.org/d3.v5.min.js"></script>
<script defer src="https://x3dom.org/download/1.7.2/x3dom-full.js"></script>
<script defer src="JS/form.js"></script>
The side includes a form which is handled by another javascript that calls the visualization script on submitting by using the jquery getScript() method. The visualization script gets loaded (I tested it by doing some console output), but the x3dom is not loaded. Tested it by using the following method:
if ( x3d.node() && x3d.node().runtime ) {
// do stuff
else {
console.log("x3dom not ready")
}
My first guess was, that the include sequence is wrong, but using the same header in the single file worked (I just removed the defer tags and website specific includes(like loading local css and js)).
So how can the x3dom script not be loaded in website implemenation?
EDIT
I tried calling the visualization script from the main html page and it works.
For that I added to my head:
....
<script defer src="JS/form.js"></script>
<script defer src="JS/scatterPlot3d.js"></script>
So the problem must be calling it from another js file.
Any ideas?
Okay, there is a function
x3dom.reload()
which solves the problem.
I have implemented the Bootstrap-Year-Calendar plug-in but it appears vertically, I don't know if it has to do anything with my scripts or links.
I tried changing the version of my Jquery and bootstrap version but the result is the same.
I was following these instructions:http://www.bootstrap-year-calendar.com/#Documentation/Installation
This is my code:
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap css-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link rel="stylesheet" href="{{ static_url('css/bootstrap.min.css') }}">
<!-- CUSTOM & PAGES STYLE -->
<link rel="stylesheet" href="{{ static_url('css/custom.css') }}">
</head>
<body>
<div class="container">
<div data-provide="calendar" class="calendar">
</div>
</div>
<!-- Bootsrap -->
<script src="https://code.jquery.com/jquery-2.2.4.js" integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI=" crossorigin="anonymous"></script>
<script 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.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<link rel="stylesheet" href="{{ static_url('css/bootstrap-year-calendar.min.css') }}">
<script src="{{ static_url('js/bootstrap-year-calendar.min.js') }}"></script>
<script>
$(function() {
$('#calendar').calendar();
});
</script>
</body>
</html>
This is how it looks now
This is because you're using bootstrap 4. Bootstrap-Year-Calendar works with Bootstrap 3 versions only. If you can't use bootstrap3 in your site there is a fork customized for BS4.
From fork authors comment:- He has Migrated the classes that relied on deprecated BS3 classes and it should work. BS4 no longer uses glyphicons,So he used open-iconic as a dependency, as it was one of their recommended sources for icons (https://getbootstrap.com/docs/4.0/extend/icons/)
Im building a page using Bootstrap and still feeling my way around. Im trying to load content to a div once the page has finished loading and Im using jQuery .load method. For some reason it always comes back as : load is not a function, even when Ive copied a working example from w3schools.
My code is as follows:
$(document).ready(function(){
$(".carousel-load").load('HTML/avaleht.html');
})
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-
to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="CSS/bootstrap.min.css" >
<link rel="stylesheet" href="CSS/style.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.10/css/all.css" integrity="sha384-+d0P83n9kaQMCwj8F4RJB66tzIwOKmrdb46+porD/OvrJ+37WqIM7UoBtwHO6Nlg" crossorigin="anonymous">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<title>ASMRi</title>
</head>
<div class="carousel-load"></div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
</body>
</html>
Any sort of help is much appreciated!
You're including jQuery two times in your code, and the latter (slim version) doesn't include load() function in it. Since the latter also overrides the former, you get this error.
You need to remove this line from the code:
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
To see the difference between the two flavors, this post is a good start.
As the title of this post says, since I added the fancybox's sources to my file, other js functions doesn't work anymore. If i switch the position of js source files and put mine after fancybox's js source files, my js functions work but the fancybox no, in the other hand, the fancybox work but my js functions don't.
Here is the header of my file:
<head>
<link rel="shortcut icon" type="image/x-icon" href="imagens/its.png">
<link href="css/mystyle.css" rel="stylesheet" type="text/css"> <!-- MY CSS -->
<link href="http://fonts.googleapis.com/css?family=Amaranth" rel="stylesheet" type="text/css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<!-- FANCY BOX SOURCES -->
<!-- Add jQuery library -->
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<!-- Add mousewheel plugin (this is optional) -->
<script type="text/javascript" src="fancybox/lib/jquery.mousewheel-3.0.6.pack.js"></script>
<!-- Add fancyBox -->
<link rel="stylesheet" href="fancybox/source/jquery.fancybox.css?v=2.1.5" type="text/css" media="screen" />
<script type="text/javascript" src="fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
<!-- Optionally add helpers - button, thumbnail and/or media -->
<link rel="stylesheet" href="fancybox/source/helpers/jquery.fancybox-buttons.css?v=1.0.5" type="text/css" media="screen" />
<script type="text/javascript" src="fancybox/source/helpers/jquery.fancybox-buttons.js?v=1.0.5"></script>
<script type="text/javascript" src="fancybox/source/helpers/jquery.fancybox-media.js?v=1.0.6"></script>
<link rel="stylesheet" href="fancybox/source/helpers/jquery.fancybox-thumbs.css?v=1.0.7" type="text/css" media="screen" />
<script type="text/javascript" src="fancybox/source/helpers/jquery.fancybox-thumbs.js?v=1.0.7"></script>
<script type="text/javascript">
$(document).ready(function() {
$(".fancybox").fancybox();
});
</script>
<!-- FANCY BOX SOURCES -->
<script src="js/myjs.js"></script> <!-- MY JS SOURCE FILE -->
I think that src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" is what's doing some conflict..
What can I do ?
You're importing a very old version of jQuery for your own code http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js, but then importing the latest version for Fancybox http://code.jquery.com/jquery-latest.min.js
Many things in the jQuery library have evolved since 1.3 was released almost 5 years ago, and several old APIs no longer work. The ideal thing to do would be to modernize your own code, and then just import jQuery once (a new or new-ish version).
Start by checking the error console to find out what's breaking.