Browser Caching of javascripts and css files in mvc project - javascript

I have to cache the static javscript and css files in my SPA(durandal+knockout) .
When i put debug='false' in my webconfig of the app , the app gives the 'jQuery not defined' and 'KO not defined' error . This is happening even when the bundles are having the jQuery and KO javascript libraries.
Any suggestions and solutions for this issue ??

What is the importance of specifically mentioning caching of static JavaScript and CSS and the debug='false'; You felt it was important enough to mention first but then didn't tell us what's so special about it and why we need to consider it. - We need more infomation if this is critical to the problem.
i.e.
What is special about the caching is it located somewhere other than you site?
Does you app do something different when in debug mode?
Why does debug='false' effect the bundles which are dependent ONLY on the URL you request?
My Guess
Does you app make different requests when in debug mode so that it can see the individual debug versions of the libraries rather than one large single line file?
Have the two libraries been included in the non debug version. I've often seen MVC projects use a partial view to load both the CSS and JavaScript
something like _Script.cshtml
#if (HttpContext.Current.IsDebuggingEnabled)
{
... All the debug ./ developer versions of files listed here individually
}
else
{
#Scripts.Render("~/bundles/jquery")
}
Also if your static content is 'cached' on a separate URL / Site / CDN and you used NuGet to install Knockout or other libraries then it entirely possible that the where installed in the be local /Scripts folder and not the other site.

Related

Are there any downsides in using CDN only for Bootstrap JS parts?

I'm theming Bootstrap with custom styles, by using a local copy of the source SASS files as described on the official documentation, and importing them in a custom.scss file.
I'm mainly willing to customize the appearance, non the functionality; so, in example: colors, typography and the so-called "Sass options".
In this kind of scenario, are there any downsides or possible problems in importing the JS part of Bootstrap (I'm referring in particular to bootstrap.bundle.min.js) in my project by using a CDN instead of providing it from local?
EDIT: Please note that I'm not asking how loading a resource from CDN is different from loading it from local, I'm just asking if loading a part of Boostrap from CDN and another from local could lead to problems or unexpected behavior.
This is probably a silly question, I'm reasonably sure that I can do this without incurring in any problem, but I'd like to have some feedback from someone more expert than me.
If you can, you should host the JS yourself.
Since bootstrap uses integrity parameters in their example "how to use" code, you don't really have to be scared about cross site scripting attacks if their CDN is compromised (unless you leave them out in your code). The files will simply not be loaded.
That is still however not something you want: If their CDN is compromised or their servers simply crash, you will not be able to load the JS anymore and parts of your app might become unusable.
You could, however, first attempt to serve from the cdn and if that's not possible give the user a local version. That way you can utilize the cache and be save when bootstrap servers go down. Here's a small excerpt taken from freecodecamp:
<script>
if (! $.fn.modal) {
document.write('<script src="YOUR JS LOCATION"></script>');
}
</script>
You should put this underneath the line where you include the bootstrap CDN.
The code simply checks if a function from bootstrap is available and if not loads it from your local server.

Why the downloaded web pages have so long *.js files?

I am learning to develop a website.
I am the backend developer but have no experience in this web development.
I have several good references such as https://mvs.org/
In order to see how many lines of code or structure of the web pages, I downloaded the entire web page using Httrack.
I am surprised that a few *.js files include around 60,000 lines of code.
Does it mean that the web developer of the pages wrote that many codes?
or am I missing something here?
It might be a library such as JQuery or React.js, which indeed can include many lines.
Sometimes (usually) all .js files are also bundled into one big file.
Front end development implies different requirements than when one is developing on the backend.
Your context is the browser and you want to reduce the number of HTTP requests as much as possible, thus you generally bundle all your javascript files into one big file using tools such as webpack.
Your code will then be bundled with all the needed npm modules, that's why you end up with one large javascript file.

How to include external Javascript in GWT offline application

I have a GWT (well, GXT) application that uses an external JavaScript library to add functionality to my app. My application must work offline, too, and herein lies my problem.
I am aware that adding files to the public folder will make them accessible by my GWT app, but this will not work in case of offline use. GWT compiles my app to make it available offline without problem, but it doesn't include the external JavaScript library.
So, whenever I work within the application and reach the point where said library is needed, the browser will attempt a GET request because the library hasn't been loaded yet and doesn't remain in the cache of the browser reliably.
Is there a way to add the library to my app so that it will be cached together with my GWT app? The library consists of several folders, JS files, images, CSS, etc. My only idea is to dynamically create an Appcache Manifest that dumps ALL files in the browser cache.. in which case I'm scared of breaking the GWT offline functionality.
Yes you can generate a manifest at compile time. Just use a linker that extends com.google.gwt.core.ext.linker.AbstractLinker.
See for example this example manifest linker
or see Writing a GWT Linker
or see this stackoverflow thread
I do that to include google fonts and to produce a manifest that will only include files for that specific language permutation.

asp.net mvc 3 - specialized bundling and minification for separate views

In Summary
When bundling and minifying JavaScript, is it good practice to have a single site-wide JS bundle or multiple specific bundles?
If the latter, then how can these bundles be added to each View (not layout) and still get the server to return the individual non-minified JS files when in debug mode?
In Detail
I read a very interesting article detailing how to use the bundling and minification that is available in the MVC4 framework in the an ASP.NET MVC3 web application: click for article
In this article, it describes how to add a link to a particular bundle from the layout page:
Scripts.Render("~/bundles/MyBundle")
And I can see how this approach is great for creating a site-wide bundle.
However, I'm not sure what the best-practice is regarding whether to have a single site-wide bundle, or multiple specialized bundles and I'd appreciate advice here. As I see it, the pros and cons of a single site-wide bundle are:
Cons:
slows down initial load of home page (even with minimization)
may be harder to ensure no JS conflicts.
Pros:
all subsequent pages have nothing new to download
just one bundle to administer
Okay - assuming that best practice turns out to be multiple bundles.... That being the case, I see how easy it is to add a bundle to a layout page, but how about specific views? Each View should register the JS that it requires (in a script section) and then this is added to the bottom of the page's body so that it loads last (unlike CSS which you add to the Header so that it loads first). I managed this using the following code, but the problem with this route is that the JS always comes out as the single minified file which isn't that helpful in debug mode.
#<script src="#Scripts.Url("~/bundles/myBundle")"></script>
Many thanks in advance
Griff
You can do both. In order to render the specialized bundles, you can do this:
Create a scripts section in your _Layout.cshtml. I usually put mine at the bottom of the page just before the closing body tag, but you could also put it in the head:
#RenderSection("scripts", required: false)
Then, in your view, you define the section like so:
#section scripts {
#Scripts.Render("~/bundles/myspecialuniquebundlejustforthisview")
}
When you do it this way, the bundle will only be compressed and minified when you either compile with debug="false" or explicitly set BundleTable.EnableOptimizations = true during debug time.

Managing jQuery Plugins

Often, when working with jQuery, the need arises to include multiple plugins. This can quickly become messy work, especially when some plugins require additional components (images and CSS files).
What are some of the "recommended" ways to:
a. Manage the required files/components (.js, .css and images) in a way that is easy to maintain, and;
b. Keep these plugin packages updated to the latest versions
I'm not necessarily looking for a tool to do this (although one that could perform this management would be useful, I suppose), but more of a way of thinking.
Update: These days there is Bower, Component and Browserify which take care of all of the following for us automatically.
I'm surprised no one has covered what I do yet. So here's how I manage scripts and resources.
I have each project I work on setup with SVN. Nearly all of the scripts I include have a SVN mirror (github has svn these days) this means that I can then use SVN externals and fetch whatever branch or version or whatever I want of that project directly into the projects scripts folder. As we are using SVN, it is easy to track, manage and update these scripts.
If a project is not on SVN, then I just add it to a common SVN project I have made, so for instance Project A and Project B, both use jquery-project-not-in-svn, so we stick jquery-project-not-in-svn into our common project's SVN repository, and then use SVN externals on Projects A and B to reference it - as explained before.
Now that covers managing, fetching and updating.
Here is how I cover script inclusions and requests.
As each project now has it's own scripts directory that contains all the scripts it needs (which is managed by SVN externals), we now have to worry about minifying them to reduce load on our server. Each project has a Makefile in it's root, which contains the command update. This command will perform the following:
Perform a SVN update (this will update all SVN externals appropriately)
Once that is done, it will pack and minify all the js files into scripts/all.js and scripts/all.min.js
I can't share the exact Makefile but I can share one which is public that handles packing/merging and minification of CSS and Javascript. Here is the link:
http://github.com/balupton/jquery-sparkle/blob/9921fcbf1cbeab7a4f2f875a91cb8548f3f65721/Makefile
By doing these things, we have achieved:
Management of external script resources over multiple projects
Updating of appropriate script resources automatically
Packing all used script resources of the project into one file
Minifying that file, such that only one JS request and one CSS request are performed.
So good luckmate, feel free to post a comment if you would like to learn more.
I would recommend not updating them unless you are experiencing a problem with the version you have or you would like to use a new feature available in the updated plugin. As the saying goes, if it ain't broke, don't fix it.
My own personal "recommended" way is to keep all my JavaScript files in one include folder, all CSS files in another, and all images in a third directory. I write shortcut functions for my projects that I can then use like <?php scriptlink( 'jquery.tooltip' ); ?> or <?php stylelink( 'jquery.thickbox' ); ?>. Each shortcut function takes a filename (only) as an argument and outputs the full HTML tag for that resource type, i.e. (in order) <script type="text/javascript" src="/includes/js/jquery.tooltip.js"></script> or <link rel="stylesheet" href="/includes/css/jquery.thickbox.css" />
Most jQuery plugins I've run across that require images allow either specifying a configuration variable in the script itself or in the code used to invoke the plugin. Stylesheets are quite easily included without mucking about with the script.
So far this method has kept me pretty sane, so I think it works rather well. I don't tear my hair out over where I stuck a particular plugin; I just include it with a function. (The system also supports subdirectories of the include directory, so e.g. <?php scriptlink( 'ui/accordion' ); ?> equals <script type="text/javascript" src="/includes/js/ui/accordion.js"></script>.)
YMMV of course, but the only issue I've had at all is with upgrades when plugin authors start distributing a jquery.plugin.pack.js version instead of jquery.plugin.min.js or vice versa, because I actually have to remember to change the filenames I look for.
(Since I've omitted the implementation of those simple functions, perhaps your version will check for different variants of the file name given. If the argument to scriptlink() is jquery.plugin, the function might check the file system to see if jquery.plugin.pack.js exists, and if not look for jquery.plugin.min.js, and if not look for jquery.plugin.js, etc.)
CDNs are great but not for debugging. Sometimes debugging really requires local access
to the scripts and CDNs are useless until in production mode. For this reason I still like
to keep both debug and minified versions around then compare results and benchmark response time until we shift to production.
All of my jQuery plugins are organised into subfolders which include the version number e.g.
/assets/js/plugin.1.4.1/plugin.1.4.1.min.js
/assets/js/plugin.1.4.1/images/image.gif
If I need to update to 1.4.2 I can drop it in a new folder without too many problem, I can even use a specific version of the plugin in different parts of the site if needed. When I site is large and your using a few different plugins it's helpful to quickly see version numbers without digging around source comments in a plugin.js file.
If a plugin requires CSS I will take the base styles out of the plugin CSS and bundle these in with my main stylesheet, requesting additional CSS files is expensive and 9 times out of 10 it will be customised anyway. Likewise with images, if I'm doing any image customisation I will bundle these into my main image sprite, otherwise I'll just link to the images into that plugin.1.4.1 directory.
Yes, you end up with a few more files in your repo but it means:
you can easily upgrade plugins just by updating your paths
you can debug plugin issues easier because you can see how out of date you are
you can roll back to an earlier version if everything breaks
You could utilize the Google CDN (Content Delivery Network) for more popular plug-ins. Google keeps it up-to-date, you can quickly choose/switch between versions, and you also get the benefits of caching from other websites that use CDN.
Example for jQuery:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
And, if you want to use a higher version automatically, change the version to 1.4 (automatic 1.4.x updates) or even 1 (automatic 1.x.x updates). Unfortunately not all plug-ins are available, but many of the major ones are.

Categories

Resources