I'm building large applications with the Google Maps API, and I'm finding the need to be more modular in my development approach, and could use some direction.
My goal is to logically break out my code into different JS files - so there will always be a "base" JS file that takes care of loading the map, adding base functionality, etc. But for different clients, I want to build on this base without duplicating code. So the base JS file stays put, and I just add some additional functionality to another client-specific JS file, and load both of these into the application. The problem with this approach is that I need to wait until the Google Maps API is completely loaded before loading any other JS files, otherwise the second JS file doesn't have access to API objects and errors out.
So are there any libraries or frameworks out there that address this big-picture and little-picture issue? I ran into Require.js as a solution, but I want to see what all of the options are here. Any direction is much appreciated.
RequireJS is probably your best bet here. It will load scripts in parallel, but execute them in dependency order. It looks like the async plugin referenced in that blog post will work as advertised with the Google Maps loader. Once you get into projects with more than a handful of JavaScript files and classes, and try out RequireJS, you'll wonder how you ever did without it.
Related
I'm trying to figure out a way to automatically generate an ApplicationCache manifest file from all the HTML,CSS,JavaScript and images files used by our website.
We need this because we need to support offline usage of the website. More precisely, offline usage of an ArcGIS API for JavaScript webapp.
We are not using service workers instead of the ApplicationCache because supporting iOS is a critical requirement and service workers are not supported at all on iOS, on any browser.
The idea is that I'll manually call a function after the site is fully loaded that will dynamically create the text to be used for the new manifest. Then manually copy/paste it in the manifest file. So it's something I would only do when something in the site changes and the manifest file needs to be updated.
This tool, ManifestR, is very close: http://westciv.com/tools/manifestR/
but has two issues with it:
1- It does not handle image file URLs found in CSS files properly. For instance if it finds url(../images/myimage.png) it will add the relative link ../images/myimage.png directly in the manifest file instead of adding the non-relative link like www.mysite.com/images/myimage.png.
2- It does not list any of the scripts loaded through dojo.require (AMD modules).
I'm thinking of using similar code to fix these issues and compile the list of files. I already see how to fix #1, but can't figure out how to fix #2.
So, using JavaScript, how can I find the list of all script URLs used by the website, not just those loaded trough tags (found in window.scripts object), but those loaded using AMD modules as well?
Basically I want to compile the same list that Chrome is showing me for the website in the Sources pane.
Ex:
I'm thinking that if this isn't available anywhere, maybe I could create a proxy function to dojo.require that keeps tracks of all files loaded through AMD.
But I wanted to ask here first, maybe I missed a tool of script that already does this? Or maybe my plan isn't good?
Thanks
I've never used ApplicationCache for an ArcGIS API for JavaScript app, but I would recommend that you first serve up a custom Dojo build of your application in order to bundle your code into one or more build layers. If you configure your Dojo build properly (no small feat) you should know the exact scripts that will be required.
Also, I'd suspect that once you figure out how to get the list of scripts, you may have special considerations in order to get the Dojo AMD loader to be able to use the cached files. See: dojo and the offline application cache
Good luck.
I'm working on a web project that uses webgl content generated with unity. When trying to load the required js files the browser freezes for around 30 seconds. The main js file has 35MB size unzipped so this seems to be the cause.
I want to avoid this freeze if possible but I couldn't manage to do it using WebWorkers since the script needs access to UI. My other possible solution is to try to split the js file into smaller ones but I don't know how to do it. Do you have any suggestions?
If you add async to your script tag like this <script async src="app.min.js"></script> it will not block rendering anymore. Also caching the script in the browser or delivering it from a CDN can help reduce the download time.
35MB are, however, way too much for a website. Are you sure there isn't a lot of unused stuff like libraries in it?
We recently wrote an article with web performance best practices, with explanations to critical rendering path and other fronted concerns here
35 MB just for the JS file seems ridiculous. It could be that the entire build is probably of that size (textures, media, etc.). Have a look here on how to reduce the build size.
Though 35 MB is wayyyy to much for a JS file, you can start by following pointers:
Create utilities and reuse the code. This can be at any level. Be it generic component (HTML generating code) or validation logic, if it can be configured using arguments, make a function and use it.
If you have Hard-coded JSON in your js, move them to .josn files and load them only when they are required.
Split files based on sections in view. In SPAs, there are cases when a section is not visible. For such cases, don't load such files. Spread your code base from 1 file to 100s of file.
If you have a lot of event listeners, move them to different file. You can have section_event.js, section_data.json, section_utils.js and section_index.js. If there involves lot of data parsing, you can even have section_parser.js
Basic Idea is to split code into multiple files. Then, make code more reusable. You can even look into loading libraries to reduce your load.
Also, load a resource only when required. SPA have stages. Load concerned files when they are needed. Split download from 1 time to partial, on-demand approach. Also look into webpack or grunt or gulp to minify js.
I like keeping myself busy building modular web-applications, but don't want to spend time where I can save some..
For example I'm building a news module that should be easily implemented over multiple sites, because the same web-application is used.
However not all websites will need a news module. Is it better/easier/faster to create an inline stylesheet/javascript file built into the module itself, than to create a big external stylesheet/javascript with all the libraries? Even though the file for the news module is not needed on all other webpages?
It seems to be much easier to create an inline library in the module itself. So that this only gets loaded when needed, and saves load time and bandwidth on the other pages.
The other thing is that I like writing 'plug-and-play' modules. Say I move a file across the file server into the module folder, and the application will take care of the rest. With inline sheets, I dont have to add new lines to the header/footer etc.
What is the best solution for this? When also taking into account that I rather spend 10 minutes moving a file and it works, than to spend 1 hour appending external libraries just because its more of a 'good practice'?
If you re building web applications, are you using the MVC patern? Do you separate your concerns? (your Templates/Views, your Models, and your logic(Controllers))
If you follow MVC, it makes easier maintaining and customizing your app.
To answer to your exact question, what you need is RequireJS. This way you have only one place to declare your requirements, and RequireJS will handle the rest.. Load order and more..
Quoting from the requirejs website:
Over time, if you start to create more modular code that needs to be
reused in a few places, the module format for RequireJS makes it easy
to write encapsulated code that can be loaded on the fly.
Inline is never a solid way to maintain CSS. Take care to separate the description of your layout from your views. You can easily include the file in the same directory as the module so it should not be an issue.
Or if you want just to load "on fly" some script you can use jQuery.getScript , http://api.jquery.com/jQuery.getScript/ . Otherwise you should follow George's way.
We are developing a javascript component to be used in a JSF app and we're using Dojo.
The thing is we only need specific parts of the library and we'd like to only insert into our webapp the files/folders we use to accomplish our goal.
We could do this 'by hand' but in the future we might need to add other functionality from Dojo and then we will not know what resources we need -> I guess by this moment you realised we are no Dojo/js gurus.
Basically we are looking for a way to automate this process. We were thinking of getting a list of the dependencies and then create a small script to 'filter' the files.
Is this possible ? Have anyone tried this before ?
Thanks.
I may be misinterpreting your request, but I think dojo does what you want out of the box. Since the latest versions of dojo follow the Asynchronous Module Definition (AMD) format, you use a global require function to describe what dependencies a specific block of code have, and only those modules are loaded. An example from the sitepen dojo intro:
require(["dojo/dom", "dojo/domReady!"], function(dom){
var greeting = dom.byId("greeting");
greeting.innerHTML += " from Dojo!";
});
If you only want to have to to load a single <script/> tag, you'll want to look into the dojo builder. Using the online build tool You can select what packages you want included into the dojo.js layer and it will bundle everything up into a zip file that includes dojo.js/dojo.js.uncompressed.js which contains dojo core in addition to the modules you selected.
Ok, we did this by doing the following (just in case anyone will need this):
* declare a JSF filter and map it to /js/* (all dojo resources are under /js folder, this may need to be modified to fit your folder structure); this way, all requests for a dojo resource will be filtered.
* in the filter class, get all the requested files: (HttpServletRequest) request).getRequestURI() and write it line by line in a file: now you have all the needed resources.
* parse that file with a script, line by line, and copy the files to another location -> build the folder structure.
* use the created files in your WebContent folder (or wherever you need it), you have a clean library -> you only deploy what you use.
The web is littered with full-blown JavaScript libraries who say they will save your day and make your web development life much easier. You get encouraged to include these “mere 80 kb” libraries that is supposed to be the solution to all your needs, and practically make the web site work by itself. Needless to say, I’m not a big follower of JavaScript libraries,, especially since they almost always include lots of superfluous code, so I thought I’d put together a tiny library with only essential JavaScript functions.
The result of that is EJ – Essential JavaScript.
EJ consists of functions that I use all the time and they make writing JavaScript go faster and the result is being able to do work more efficiently. It is also about having the things you would write again and again for every web site you produce in one neat and tiny file instead, to be able to focus on the new things you need to address
This may be a dumb question for web guys. But I am a little confused over this. Now, I have an application where I am using a couple of Javascript files to perform different tasks. Now, I am using Javascript bundler to combine and minify all the files. So, at runtime there will be only one app.min.js file. Now, Requirejs is used to load modules or files at runtime. So, the question is if I already have all things in one file, then do I need requirejs? Or what is a use case scenario where I can use requirejs and/or bundler?
Please let me know if any further details are needed.
Generally you only use RequireJS in its loading form during development. Once the site is done and ready for deployment, you minify the code. The advantage here is RequireJS knows exactly what your dependencies are, and thus can easily minify the code in the correct order. Here is what it says on the RequireJS website:
Once you are finished doing development and want to deploy your code for your end users, you can use the optimizer to combine the JavaScript files together and minify it. In the example above, it can combine main.js and helper/util.js into one file and minify the result.
This is a hotly contested issue among many proficient javascript developers. Many other languages have a "compilation" phase where the entire program is bundled up for deployment (JBoss's .WAR files come to mind). Programmers that come from more traditional backgrounds often favor this approach.
Javascript has seen such growth in recent years that it is difficult to chart exact best practices, but those that appreciate the more functional nature of Javascript often prefer the module loading approach (like require.js uses).
I wrote Frame.js which works much like require.js, so my bias is towards the module loader approach.
To answer your question directly, yes, it is one or the other.
Most that argue for packing your scripts into a single file believe it enables more compression and is thus more efficient. I believe the efficiency advantages of packaging are negligible in most cases because: (1) module load times are distributed over the entire session, (2) individual modules can be compressed to nearly the same percentage, (3) individual modules can be cached by the server and routers separately, and (4) loading scripts only when they are needed ultimately allows you load less code for some users and more code overall.
In the long run, if you can see an advantage to dynamic script loading use it. If not, bundle your scripts into a single file.
It depends on your application. If you're making a server-side app with only modest javascript (less than 100kb minified) then go for total bundling, you're probably going to be fine.
But if you're making a javascript app and have a ton of code in it, then your needs are going to be different.
For example, in my app I bundle all the core files. There's jQuery, underscore, backbone, my main app files, my user login system, my layout system, my notifications and chat system, all are part of my big initial file.
But I have many other modules as well that isn't part of the initial bundle, that are loaded after those.
The forums, the wiki, the wysiwyg, color picker, drag/drop, calendar, and some animation files are part of the second category. You need to make reasonable decisions about what's commonly used and needed immediately vs what can be delayed.
If I include everything immediately I can get above a meg of javascript, which would be insane and make the initial boot unacceptably slow.
The second category starts downloading after initSuccess event fires from the initial file.
But the second category is more intelligent than the first in that it loads what's more important first. For example if you're looking at the wiki it'll load the wiki before it loads the color picker.