I am trying out require.js and only include on js file at my main page. That main.js loads loads other scripts.
I am testing the performance of my site with yslow. It says that my page has 15 js files and I should try combining them into one. Isn't this the the purpose of require.js? That I shouldn't have to combine all my js into one large file?
Well, the idea of RequireJS is to build your scripts into modules (small parts). While doing that, you will notice that you are going to be dealing with many modules and thus many files.
To solve the "many files" problem, RequireJS has an optimizer.
RequireJS has an optimization tool that does the following
Combines related scripts together into build layers and minifies them via UglifyJS (the default) or Closure Compiler (an option when using Java).
Optimizes CSS by inlining CSS files referenced by #import and removing comments.
Related
Recently I just picked up Typescript for a personal project. Since the project is designed to be ran locally (explicitly file://), I won't be able to use import/export features due to CORS restrictions. Aware of another similarly written question but lacking the specific context on my use case, I pose these questions:
How does one tell Typescript that all (or at least certain) scripts are imported to HTML via <script type="text/javascript" src="./source.js">?
Does Typescript's tsc build projects with this in mind? Also, does it edit existing HTML files to take this into consideration too? If not, are there tools to automate this process as well?
I don't want to bundle them like webpack or tsc-bundle does, since a secondary objective to this project is to keep all .js files human-readable just as much as the .ts files do.
Building Typescript using tsc -p tsconfig.json, configured to "target" : "ES2015" and "module" : "None", only outputs their respective .js files and doesn't update any of the HTML's <script> includes. Am currently maintaining the html file by manually inserting and juggling any new modules that emerges over the course of development.
My current load order in index.html is as follows:
index.js handles UI controls and loads first.
The remaining pseudo-modules .js files loads in-between, since these only define classes and doesn't perform any operations, so I figured it's safe to load them here.
main.js handles all the code from javascript "modules" and loads last.
My main concern is that my in-between modules might load out of order due to human error.
Edit: Running a local webserver is out of the question too, since the project is meant to target audience with limited technical knowledge, with the index.html file the only file they need to run in their browser.
I've been browsing many of the articles here about how and why one should combine JS/CSS files for performance, but none of those articles offered any real guideline as to when is the right time.
I'm developing a single-page microsite that uses seven Javascript files (a mixture of third-party plugins from CDNs and my own files), and eight different CSS files (basically one per plugin, and my own compiled SASS file).
The site loads slowly even on the intranet here; I'm concerned about the performance outside. While searching for several plugins yesterday, I found several CodePen and plugin articles that basically said "cool kids concatenate JS" (literally) which got me thinking about this whole thing.
At what point should I start concatenating and minifying my Javascript/CSS?
And should I paste the CDN scripts into my own JS files, or is it better in the long run to have another HTTP request but use the statically served plugin files?
Edit: Just to clarify - I'm not asking for tools/techniques, but wondering when it becomes important to combine and minify files - should it always been done as #RobG suggested?
You should deliver code to UAT that is as close to production code as possible, including all minification and combining of files. If you don't, then you aren't doing proper UAT
To be honest, it depends.
People are often, wrongly, obsessed with merge-min... That's not always the case. The need for merge-min depends on a few things:
Sometimes it's faster and BETTER practice to load 2 css files than one big one? Why? Because they'll load in parallel. That simple.
So don't go with the merge-min obsession. If your users are returning, daily users, do merge and rely on browser cache. If not, optimise parallel loads by not merging.
And ignore the simplistic: 'yes you must merge because that's what was best 10 years ago and I've never questioned it' :)
When Should I Combine my JS and CSS Files?
Every time you are finished with development. specifically when your code is going to User Acceptance Test (UAT), if not earlier. thanks #RobG for mentioning it.
Which tools do you suggest?
Browserify
Let's Start with your JS files. I think a great tool for bundling various JS files/modules is Browserify.
Browsers don't have the require method defined, but Node.js does. With Browserify you can write code that uses require in the same way that you would use it in Node.
Here is a tutorial on how to use Browserify on the command line to bundle up a simple file called main.js along with all of its dependencies:
var unique = require('uniq');
var data = [1, 2, 2, 3, 4, 5, 5, 5, 6];
console.log(unique(data));
Install the uniq module with npm:
npm install uniq
Now recursively bundle up all the required modules starting at main.js into a single file called bundle.js with the browserify command:
browserify main.js -o bundle.js
Browserify parses the AST for require() calls to traverse the entire dependency graph of your project.
Drop a single tag into your html and you're done!
<script src="bundle.js"></script>
Also there is a tool similer for CSS files called browserify-css.
Gulp
gulp is a toolkit that will help you automate painful or time-consuming tasks in your development workflow. For web development (if that's your thing) it can help you by doing CSS preprocessing, JS transpiling, minification, live reloading, and much more. Integrations are built into all major IDEs and people are loving gulp across PHP, .NET, Node.js, Java, and more. With over 1700 plugins (and plenty you can do without plugins), gulp lets you quit messing with build systems and get back to work.
Public CDN scripts
should I paste the CDN scripts into my own JS files, or is it better in the long run to have another HTTP request but use the statically served plugin files?
You can keep them in public CDN; To avoid needlessly overloading servers, browsers limit the number of connections that can be made simultaneously. Depending on which browser, this limit may be as low as two connections per hostname.
Using a public CDN (like Google AJAX Libraries CDN) eliminates one request to your site, allowing more of your local content to downloaded in parallel. Read more on this here
The Setup:
I have a large SPA app using many JavaScript files that are bundled using Web Essentials bundling in Visual Studio 2013. I then include the minified js files generated by Web Essentials on my HTML page. This application does not use ASP.NET
The problem:
I would like to be able to distribute the HTML page with a single minified script referenced for production but the individual unminified scripts for development.
Reasons:
The minified scripts even with the map files make it difficult to debug. Variable and parameter names have been minified and thus the debugger does not match the source. Additionally, since everything is in one file, its hard to look at for development.
Current solution:
I have a grunt task that goes into my html file and modifies it such that the <script> tags are replaced. This has the con of growing with every file I add to the page.
Does web essentials offer a better solution than what I am currently doing that I might have simply overlooked?
You are mixing the bundling tool with the reference implementation.
Web Essentials 2013 builds bundles of compressed (minified) JavaScript, CSS, LESS, SASS and image files. Web Essentials should create the minified bundle regardless whether you are in Debug mode.
You are looking for a way to selectively reference minfied files in Release mode and originals in Debug. That may mean rather involved Razor coding to check for release version and render reference calls.
A better solution is to use ASP.NET Bundling and Minification.
It's easy to debug your JavaScript in a development environment (where the compilation Element in the Web.config file is set to debug="true" ) because the JavaScript files are not bundled or minified when debug="true"
The minified bundle will still exist if debug="true" in your Web.config. But at run-time, the framework will reference the originals files instead of the minified. Your Web.config is now responsible for maintaining which version of your assets are referenced.
Web Essential bundles are passive assets. There is no functionality in Web Essentials to distinguish between Release and Debug mode because that is a run-time action.
Note: Web Essentials 2015.0 has removed bundling and minification.
Important!
Web Essentials 2015 no longer contains features for bundling and
minifying of JS, CSS and HTML files as well as compiling LESS, Scss
and CoffeeScript files. Those features have been moved to their own
separate extensions that improves the features greatly
The common practice is to use the ASP.NET Bundler. This is another reason to get away from bundling with Web Essentials.
i ma not sure if Web-essentials can handle that scenario though
As per my current project experience below are the things i use to debug the code locally while development-
For local debugging if you are using the ASP.NET bundling feature and must have specified the file references in the BundleConfig.cs. You can enable the browser to Load each file as is by Setting the flag BundleTable.EnableOptimizations=true; in the Global.asax file. And we load the single bundle file to work on local environment
For Production we use the minified versions of the file references.
eg in your HTML you can have a check like this
#if(local){
#Scripts.Render("~/Scripts/src/BundleName");
}
else{
//Which is an partial HTML which contains the minified file references
Html.RenderPartial("ClientTemplates/MinifiedScripts");
}
Thanks
I have just used the Bundler/Minifier from here: https://github.com/madskristensen/BundlerMinifier
To help see the unbunded and unminified JS and CSS I have created a helper to render both depending on whether the web application is running with debug enabled.
see: https://bundlerminifierhelper.codeplex.com/
Example:
#Html.Bundle("/Content/Styles/Site.min.css")
#Html.Bundle("/Scripts/Scripts.min.js")
Note: Using relative paths, including the forward slash (/)
When debugging all the input files will be rendered out to the page, and when not debugging, the supplied path will be rendered out.
For CSS, I can use SASS to import one CSS file to another and produce only single CSS file. What is the similar method for Javascript files?
You might want to check out Closure Compiler (which is a Google product).
You would probably want the Closure Compiler Application form of the product.
A sample workflow would probably look like:
Create a list of your JS files and paths
Run the command to compile and concatenate files (java --jar compiler.js --js path_to_file1.js --js path_to_file2.js (etc.) compiled.js)
Closure Compiler also has a related project, Closure Stylesheets, that does the same thing for stylesheets.
This approach, of course means that there's a pre-compilation step. Depending on your backend, there also exist libraries that do the compilation when the page is built. For example, for JSP, there's Granule a tag library that creates the compiled JS and CSS files at page build.
There's a third possibility: modularization. Since you gave the example of being able to import CSS files in SASS, an analogue for JavaScript is using a module library, using either the CommonJS standard, or (the one I prefer), the AMD (asynchronous module definition) pattern, which I have personally used with RequireJS. RequireJS also comes with a nice optimizing tool that will bundle up (minify, compress, concat etc) all the required files for your application
UPDATE
Since you mentioned that you are using Django in the comments (might be useful to update the question with this info too), see if this answer helps too
You could use minify which allows you to minify and combine javascript files. It also works with CSS.
I have worked in a web project with a heavy part on JavaScript, and I have noticed that there was no style how to use JavaScript. What unsettled me most is that everyone added files here and there, which resulted in a mess to organize and deliver them. Because this will be happen in every new project, I would like to have something like a styleguide for JavaScript. This styleguide should address the following questions:
How should JavaScript files be organized in the file system during development?
How should the JavaScript parts be separated from the HTML and other parts of the application?
How should JavaScript files be delivered in the real application, so that less code has to be loaded on each request and not too much requests have to be sent?
Is there something public available as a starting point for developing our own styleguide? What are your experiences in using your styleguide? Are developers following it easily, what are the simple and what are the difficult parts in it?
(I know, more question than one, but I'm interested in the whole story here. As a background, we have used JQuery and JSF, but I don't think that will have an impact on the answer.)
If you're doing heavy client side, you are probably going the MVC way.
So I'll answer your questions with the approach taken by the brunch. Brunch projects use MVC library Backbone.js, and have strict directory structure.
How should JavaScript files be organized in the file system during development?
src/
app/
collections/
controllers/
models/
styles/
templates/
views/
vendor/
build/
web/
config.yaml
Use Stitch to organize your files as CommonJS modules. Then you will be able to use require() to define dependency between them, as well as to combine them into one file later.
How should the JavaScript parts be separated from the HTML and other parts of the application?
build directory is used to store html; build/web is used to store javascript, images, and css.
How should JavaScript files be delivered in the real application, so that less code has to be loaded on each request and not too much requests have to be sent?
At the build stage, all JavaScript is minified and combined into one file (build/web/js/app.js), so that client will have to make only one HTTP request when he / she visits your site for the first time.
It's probably a good idea to make building process as easy as possible. Brunch does that by offering brunch watch command, which monitors filesystem for changes and builds code instantly with the help of Stitch and some other tools.
(It should be noted that during development brunch projects also use CoffeeScript as the primary language; it is transparently compiled by brunch before stitching the resulting JavaScript. However, this doesn't matter as long as file organization is concerned, and is out of scope of your question.)
For all JavaScript files definitely use a separate directory. Have as many files as possible semantically. One large constructor should correspond to a separate file. Never use filename prefixes where you can create a directory.
Unix-style directory structure is often found on GitHub:
src -- for the source JavaScript.
lib -- for libraries.
tests -- for unit tests.
bin -- for executables.
dist -- for compiled files.
For compiling we use a Makefile with targets for production and development. The production version is all of files JSHint`ed, minified and concatenated into one. The development target is generating a server-side script that includes all JavaScript files dynamically (for easy inclusion into HTML).
But generally it depends. We used a widget directory for one project. This widget directory had a set of separate widget subdirectories (e.g. slider, tabs, modal-window), each of which had the following layout (inspired by DOMLoader):
html -- for HTML templates.
css -- for CSS files necessary for the widget.
js -- for the widget JavaScript constructor.
Crockford has a few stylistic guidelines and the Yahoo exceptional performance site has details which might be useful to you.
I can recommend a book: JavaScript Patterns by Stoyan Stefanov.
I think one of the best book about javascript