Django: Bootstrap Cdn or Loading Bootstrap Files from Local Server

Django: Bootstrap CDN or loading Bootstrap files from local server?

The main point and reason for using CDNs for loading any files (not just Bootstrap files) as opposed to hosting those files on your server is SPEED!

CDNs can drastically increase the speed/performance of your website.

That is because of 2 things:

  1. CDNs allow more files to be loaded in parallel i.e. at the same time! While if you host the same files on your own server, they will be loaded one after the other and depending on how many files (including image files etc.) your web page has to load, that alone can make a huge difference in performance.

  2. Files that are used on MANY websites (such as Bootstrap files for example) are already cached in the browser of your website visitors! So, they don't have to load them at all which is an even greater gain in speed/performance. This assumes that you are using CDNs that are used by thousands or hundreds of thousands of websites to load the same files (because the browser will only use cached files if the URL/path to those files on your website is identical to the CDN URLs that another website, previously visited by the user, also uses).

Also, you can include a small piece of JavaScript or jQuery that checks whether or not the external CDN file is available and if the CDN happens to be down for some reason, then and ONLY THEN that piece of JavaScript would load the corresponding files from your local server.

Should I use Bootstrap from CDN or make a copy on my server?

Why Not Both ¯\_(ツ)_/¯ ? Scott Hanselman has a great article on using a CDN for performance gains but gracefully falling back to a local copy in case the CDN is down.

Specific to bootstrap, you can do the following to load from a CDN with a local fallback:

Working Demo in Plunker

<head>
<!-- Bootstrap CSS CDN -->
<link rel="stylesheet" href="~https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css">
<!-- Bootstrap CSS local fallback -->
<script>
var test = document.createElement("div")
test.className = "hidden d-none"

document.head.appendChild(test)
var cssLoaded = window.getComputedStyle(test).display === "none"
document.head.removeChild(test)

if (!cssLoaded) {
var link = document.createElement("link");

link.type = "text/css";
link.rel = "stylesheet";
link.href = "lib/bootstrap.min.css";

document.head.appendChild(link);
}
</script>
</head>
<body>
<!-- APP CONTENT -->

<!-- jQuery CDN -->
<script src="~https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<!-- jQuery local fallback -->
<script>window.jQuery || document.write('<script src="lib/jquery.min.js"><\/script>')</script>

<!-- Bootstrap JS CDN -->
<script src="~https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<!-- Bootstrap JS local fallback -->
<script>if(typeof($.fn.modal) === 'undefined') {document.write('<script src="lib/bootstrap.min.js"><\/script>')}</script>
</body>

Updates

  • you can also do the same test using YepNope or fallback.js
  • per Flash's comment and this solution, updated answer to check for .visible class instead of testing for rgb(51, 51, 51)
  • per deste's comment, updated to use .hidden and .d-none for either Boostrap 3.x or 4
  • when testing if a stylesheet loaded, you have to look for a style that would have been applied, create an element, and see if it has been applied.
  • Updated the stylesheet to load immediately in the head by using vanilla js. You need to create a test element using Document​.create​Element(), apply bootstrap classes, use Window​.get​Computed​Style() to test for display:none, and then conditionally insert a stylesheet using js.

Best Practices

To your question on Best Practices, there are a lot of very good reasons to use a CDN in a production environment:

  1. It increases the parallelism available.
  2. It increases the chance that there will be a cache-hit.
  3. It ensures that the payload will be as small as possible.
  4. It reduces the amount of bandwidth used by your server.
  5. It ensures that the user will get a geographically close response.

To your versioning concern, any CDN worth its weight in salt with let you target a specific version of the library so you don't accidentally introduce breaking changes with each release.

Using document.write

According to the mdn on document.write

Note: as document.write writes to the document stream, calling document.write on a closed (loaded) document automatically calls document.open, which will clear the document.

However, the usage here is intentional. The code needs to be executed before the DOM is fully loaded and also in the correct order. If jQuery fails, we need to inject it into the document inline before we attempt to load bootstrap, which relies on jQuery.

HTML Output After Load:

Example Output

In both of these instances though, we're calling while the document is still open so it should inline the contents, rather than replacing the entire document. If you're waiting till the end, you'll have to replace with document.body.appendChild to insert dynamic sources.

Aside: In MVC 6, you can do this with link and script tag helpers

CSS link to Bootstrap works in localhost but not on deployment server

<link href="./static/css/bootstrap.min.css" rel="stylesheet>"

here "./static" refers to the folder named "static" in current directory and if you are using "/static" which means folder named "static" in root directory.
Both make the difference on server side.

and if its not working then you can add its bootstrap link

 <!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">

<!-- Optional theme -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">

<!-- Latest compiled and minified JavaScript -->
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>

How to load local static files if CDN fails? (django)

Do not try to do this in server-side. CDN services are built to be reliable in that they are geographically distributed and fault-tolerant and use the best practices available.

You can't find out if the CDN servers work for your user by pinging them from your Django application. Your user is located differently and might have very different network conditions, e.g. be using a mobile network connection from a different country, and have a network provider that experiences outages.

You could, indeed, ping the CDN servers, which would probably resolve into your Django application getting one CDN load balancer address and trying to see if that works for you or not, and falling back to others, if the CDN source is down. Then you would probably have to see, for every resource you have, that is every JavaScript and CSS file, if they are available, and load a local backup, if not. On the server side. This is very slow and error-prone. Networks can fail for a googolplex different reasons.

The proper way to go about this is to

  • Only use local servers for serving those static files, distribute the load with application servers that each have their own versioned copies of your static files. If your application server works, it should have the copies available as well;
  • Do the checks on the client-side, because server side queries will slow your server down to a halt if it is not close to your CDN network, and you generally do not wish to depend on any external resources on the server side;
  • Or, as I would recommend, set up your own CDN which serves your local files from a proxied URL or subdomain. Read more below.

Ideally, if you wish to use a reliable CDN source, you would set up a CDN server with redundancy on the same infrastructure you use to host your files in.

For your site is located in www.example.com, which is your Django application server address. You would set up cdn.example.com domain which would be a CDN service, for example CloudFront or similar, that proxies your requests to www.example.com/static/ and mirrors your static files as a CDN, taking the load off your application server. You can just define your Django application to use the http://cdn.example.com/static address for serving static files. There are multiple different services for providing a CDN for your application, CloudFront is just one option. This will get your static, CDNable files near to your user.

Ideally, your application servers and CDN servers are hosted on the same, redundant infrastructure, and you can claim that if one part of your infrastructure works the others will as well, or other your service provider is violating your SLA. You do NOT wish to use broken infrastructure and drive away your customers, or use hacks that will eventually break in production.

My CSS File not loading in Django but Bootstrap file loads fine

you can do this one:

<link href="css/mystyles.css" rel="stylesheet" /> 

or

   {% load staticfiles %}
<link rel="stylesheet" href="{% static "css/mystyles.css" %}" type="text/css">

This one works

SEE THE PAGE

Including Bootstrap 4 & JQuery only works via CDN, not by including local .js files. Why?

The reason why it's not working is because you're trying to use href attribute on a <script> tag.

As you can see 2 out of 3 of the <script> tags below the <-- This doesn't work line use href instead of src the attribute, change that and as long as the path is the correct one it should work just fine.

Django deploy : Should I use bootstrap3 CDN?

Though it should work both way. But I will recommend to use Bootstrap CDN.

But if it is not working there, then just have a check where your static files are stored after running python manage.py collectstatic on production server and make changes accordingly.

And if downloaded bootstrap is not working now that means none of your css file will work coz your static files are stored somewhere else by python manage.py collectstatic. Hence it is not the problem of downloaded bootstrap or cdn.



Related Topics



Leave a reply



Submit