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.
Related
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>
I'm trying to build a HTML template with a small javascript code. Here is the stuff... At the root, I built two files :
index.html
<!DOCTYPE html>
<html lang="fr">
<head>
<title>HTML Template</title>
<!-- Header initialized with /header-footer.js -->
</head>
<body>
<footer>
<!-- Footer initialized with /header-footer.js -->
<script type="text/javascript" src="/headerfooter.js"></script>
</footer>
</body>
</html>
headerfooter.js
(function () {
/*************** HEADER *****************/
const headerBeforeAppend = document.querySelector('head')
document.querySelector('head').innerHTML = `
${headerBeforeAppend.innerHTML}
<meta charset="UTF-8">
<meta content="width=device-width,initial-scale=1" name="viewport">
<!-- CSS -->
<!-- Google fonts -->
<link href="https://fonts.googleapis.com/css?family=Montserrat:100,400,700" rel="stylesheet">
<!-- Bootstrap, Materialize, etc... you see the idea -->
<!-- Javascript -->
<!-- Fontawesome -->
<script src="https://use.fontawesome.com/45d80bbe59.js"></script>
<!-- jQuery, Bootstrap scripts, etc... you see the idea -->
`
/*************** FOOTER *****************/
const footerBeforeAppend = document.querySelector('footer')
document.querySelector('footer').innerHTML = `
${footerBeforeAppend.innerHTML}
<!-- JQuery (for Bootstrap) -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<!-- Bootstrap CDN v4 alpha-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
`
})()
The idea is, when I load the index.html in a browser, to have the headerfooter.js script to write my <head> section and my <footer> section with the <links> and <script> I need.
It's actually working perfectly when, for the script, the code I write is the relative path to the script : <script type="text/javascript" src="headerfooter.js"></script>, but it's not working with the absolute path to the root: <script type="text/javascript" src="/headerfooter.js"></script>.
This is a problem, because I would like this to be a template, so that I include this script in every html page I will create in my web folder without having to re-write the path everytime. Did I make a mistake somewhere ?
(PS: is it a bad practice trying to build a template like that ?)
How you run your page will matter.
If you're trying to run it with the file:// protocol (by just opening index.html), an absolute path won't resolve correctly. You'll want to somehow run an local server (there are dozens of ways to do this, depending what all you're using, too large a scope for this question).
If you are running some kind of local server (i.e., http://localhost), then try opening the file directly with http://localhost/headerfooter.js. If that doesn't work, your file isn't quite where you think it is.
I have done jquery code in an aspx page. Now I want to move the code to Report-Filter.js file. I tried to move and execute. But it doesn't work.
This is my code;
<link href="css/jquery-ui.css" rel="stylesheet" />
<script src="js/jquery-3.1.1.js"></script>
<script src="js/jquery-ui.js"></script>
<script src="js/Report-Filter.js"></script> -------> // code
<script src="js/bootstrap.js"></script>
<link href="css/bootstrap.css" rel="stylesheet" />
<link href="css/ReportsSalesAll-style.css" rel="stylesheet" />
<link href="css/Accordian-Hide-Show.css" rel="stylesheet" />
<script src="js/Accordian-Hide-Show.js"></script>
<script type="text/javascript">
$(document).ready(function () {
// Moved code to Report-Filter.js file
})
</script>
But I didn't get the output. What I did wrong in my code.
There is no need to write script tags in .js file remove script tags from js file
<script type="text/javascript">
$(document).ready(function () {
// Moved code to Report-Filter.js file
})
</script>
Should be
$(document).ready(function () {
// Moved code to Report-Filter.js file
})
Also it would be better to place the link of file just before close of body tag
I'm not entirely sure what you are trying to do, but I'm going to assume some things.
What I think you need is
Create a new file and put the javascript code in there with respects
to what Leopard says.
Reference your new javascript file in your code as shown in your
question. Be sure to reference this AFTER you reference the JQuery
libraries.
Test your code. For example, by putting an alert in your Javascript
file somewhere. Like this: alert("test");
Some general tips:
Always put the CSS references before the JS references (Preferably in
the head of the document). This way the page won't stutter visually
while loading, because the elements put on the screen will already be
styled.
Always put the scripts you are referencing below your HTML elements.
This way the page won't take too long to display, because the scripts
won't load beforehand, but afterwards (which is correct anyway,
because your code run's after the document has finished loading)
Eventually it should look something like this:
Javascript file (js/new-javascript-file.js):
$(document).ready(function () {
alert("test");
})
Html / CSHtml / Aspx file (not sure what you are using):
<link href="css/jquery-ui.css" rel="stylesheet" />
<link href="css/ReportsSalesAll-style.css" rel="stylesheet" />
<link href="css/Accordian-Hide-Show.css" rel="stylesheet" />
<link href="css/bootstrap.css" rel="stylesheet" />
<script src="js/jquery-3.1.1.js"></script>
<script src="js/jquery-ui.js"></script>
<script src="js/Report-Filter.js"></script>
<script src="js/bootstrap.js"></script>
<script src="js/Accordian-Hide-Show.js"></script>
<script src="js/new-javascript-file.js"></script>
I have quite a bunch of script and libraries that I am using in my website, which takes like 5 to 8 seconds to load.
ex.
<script type="text/javascript" src="../lib_components/jquery/dist/jquery.min.js"></script>
<script type="text/javascript" src="../lib_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../lib_components/angular/angular.js"></script>
<script type="text/javascript" src="../lib_components/angular-resource/angular-resource.min.js"></script>
<script type="text/javascript" src="../lib_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script type="text/javascript" src="../lib_components/angular-cookies/angular-cookies.min.js"></script>
<script type="text/javascript" src="../lib_components/angular-ui-router/release/angular-ui-router.min.js"></script>
<script type="text/javascript" src="../lib_components/lodash/dist/lodash.min.js"></script>
<script type="text/javascript" src="../scripts/js/overdo.js"></script>
I want to show a loading bar till all the scripts have been loaded, can anyone guide me on whats needs to be done for that?
There is very simple approach you can use in case when all the scripts you want to load are loaded synchronously (you don't use modules loader, async attributes, etc) - like in your example.
The trick is add progress indicator script the very first on the page, before all your heavy scripts. It is also make sense to inline this script (because it shouldn't be too big ideally):
<script>
// some progress bar implementation progress.show()
console.log('showing progress, loading bar, etc.');
</script>
<script src="../lib_components/jquery/dist/jquery.min.js"></script>
<script src="../lib_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="../lib_components/angular/angular.js"></script>
<script src="../lib_components/angular-resource/angular-resource.min.js"></script>
<script src="../lib_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="../lib_components/angular-cookies/angular-cookies.min.js"></script>
<script src="../lib_components/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="../lib_components/lodash/dist/lodash.min.js"></script>
<script src="../scripts/js/overdo.js"></script>
<script>
// hiding loading bar
console.log('scripts loaded')
</script>
Now, for the implementation of the actual progress bar, it's up to you how and what to render. However, remember that depending on where you put those scripts DOM tree might not be loaded yet (if scripts are in <head>). I would anyway recommend to place scripts before closing </body>. The ideal structure for this approach would be:
<!DOCTYPE html>
<html>
<head>
<!-- some styles, no scripts here -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<link rel="stylesheet" href="assets/styles.css" />
</head>
<body>
<div class="loading" hidden>Loading...</div>
<!-- Some application HTML code -->
<script>
// show/create progress/loading
var loading = document.querySelector('.loading')
loading.hidden = false
</script>
<!-- many script tags ... -->
<!-- ... -->
<script>
// hide/remove progress/loading
loading.parentNode.removeChild(loading)
</script>
</body>
</html>
How can I replace following lines with links to the Google jQuery API?
1st line is already done.
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" src="catalog/view/javascript/jquery/tab.js"></script>
<script type="text/javascript" src="catalog/view/javascript/jquery/fancybox/jquery.fancybox-1.3.1.pack.js"></script>
<script type="text/javascript" src="catalog/view/javascript/jquery/fancybox/jquery.easing-1.3.pack.js"></script>
<script type="text/javascript" src="catalog/view/javascript/jquery/jquery.cookie.js"></script>
and maybe even this line:
<link rel="stylesheet" type="text/css" href="catalog/view/javascript/jquery/fancybox/jquery.fancybox-1.3.1.css" media="screen" />
You can't...google doesn't host these plugins like they do jQuery Core and jQuery UI.
You can see what they host here: http://code.google.com/apis/libraries/devguide.html
The plugins are not a part of the CDN as of yet. Plugins are mostly user built, so I doubt if there will be a CDN for that.