I have a very complex Chrome Extension that has gotten too large to maintain in its current format.  I'd like to restructure it, but I'm 15 and this is the first webapp or extension of it's type I've built so I have no idea how to do it.TL;DR: I have a large/complex webapp I'd like to restructure and I don't know how to do it. Should I follow my current restructure plan (below)? Does that sound like a good starting point, or is there a different approach that I'm missing? Should I not do any of the things I listed?While it isn't relevant to the question, the actual code is on Github and the extension is on the webstore.The basic structure is as follows:index.html<html>    <head>        <link href=css/style.css rel=stylesheet /> <!-- This holds the main app styles -->        <link href=css/widgets.css rel=stylesheet /> <!-- And this one holds widget styles -->    </head>    <body class=unloaded>        <!-- Low-level base elements are hardcoded here, the unloaded class is used for transitions and is removed on load. i.e: -->        <div class=tab-container tabindex=-1>                       <!-- Tab nav -->        </div>        <!--            Templates for all parts of the application and widgets are stored as elements here.            I plan on changing these to <script> elements during the restructure since <template>'s need valid HTML.        -->        <template id=template.toolbar>            <!-- Template content -->        </template>        <!-- Templates end -->        <!-- Plugins -->        <script type=text/javascript src=js/plugins.js></script>        <!-- This contains the code for all widgets, I plan on moving this online and downloading as necessary soon. -->        <script type=text/javascript src=js/widgets.js></script>        <!-- This contains the main application JS. -->        <script type=text/javascript src=js/script.js></script>    </body></html>widgets.js(initLog || (window.initLog = [])).push([new Date().getTime(), A log is kept during page load so performance can be analyzed and errors pinpointed]);// Widgets are stored in an object and extended (with jQuery, but I'll probably switch to underscore if using Backbone) as necessaryvar Widgets = {    1: { // Widget ID, this is set here so widgets can be retreived by ID        id: 1, // Widget ID again, this is used after the widget object is duplicated and detached        size: 3, // Default size, medium in this case        order: 1, // Order shown in store        name: Weather, // Widget name        interval: 300000, // Refresh interval        nicename: weather, // HTML and JS safe widget name        sizes: [tiny, small, medium], // Available widget sizes        desc: Short widget description,        settings: [            { // Widget setting specifications stored as an array of objects.  These are used to dynamically generate widget setting popups.                type: list,                nicename: location,                label: Location(s),                placeholder: Enter a location and press Enter            }        ],        config: { // Widget settings as stored in the tabs object (see script.js for storage information)            size: medium,            location: [San Francisco, CA]        },        data: {}, // Cached widget data stored locally, this lets it work offline        customFunc: function(cb) {}, // Widgets can optionally define custom functions in any part of their object        refresh: function() {}, // This fetches data from the web and caches it locally in data, then calls render. It gets called after the page is loaded for faster loads        render: function() {} // This renders the widget only using information from data, it's called on page load.    }};script.js(initLog || (window.initLog = [])).push([new Date().getTime(), These are also at the end of every file]);// Plugins, extends and globals go here. i.e. Number.prototype.pad = ....var iChrome = function(refresh) { // The main iChrome init, called with refresh when refreshing to not re-run libs    iChrome.Status.log(Starting page generation); // From now on iChrome.Status.log is defined, it's used in place of the initLog    iChrome.CSS(); // Dynamically generate CSS based on settings    iChrome.Tabs(); // This takes the tabs stored in the storage (see fetching below) and renders all columns and widgets as necessary    iChrome.Status.log(Tabs rendered); // These will be omitted further along in this excerpt, but they're used everywhere    // Checks for justInstalled => show getting started are run here    /* The main init runs the bare minimum required to display the page, this sets all non-visible or instantly need things (such as widget dragging) on a timeout */    iChrome.deferredTimeout = setTimeout(function() {        iChrome.deferred(refresh); // Pass refresh along, see above    }, 200);};iChrome.deferred = function(refresh) {}; // This calls modules one after the next in the appropriate order to finish rendering the pageiChrome.Search = function() {}; // Modules have a base init function and are camel-cased and capitalizediChrome.Search.submit = function(val) {}; // Methods within modules are camel-cased and not capitalized/*  Extension storage is async and fetched at the beginning of plugins.js, it's then stored in a variable that iChrome.Storage processes.  The fetcher checks to see if processStorage is defined, if it is it gets called, otherwise settings are left in iChromeConfig*/var processStorage = function() {    iChrome.Storage(function() {        iChrome.Templates(); // Templates are read from their elements and held in a cache        iChrome(); // Init is called    });};if (typeof iChromeConfig == object) {    processStorage();}Objectives of the restructureMemory usage:  Chrome apparently has a memory leak in extensions, they're trying to fix it but memory still keeps on getting increased every time the page is loaded.  The app also uses a lot on its own.Code readability: At this point I can't follow what's being called in the code. While rewriting the code I plan on properly commenting everything.Module interdependence: Right now modules call each other a lot, AFAIK that's not good at all since any change you make to one module could affect countless others.Fault tolerance: There's very little fault tolerance or error handling right now.  If a widget is causing the rest of the page to stop rendering the user should at least be able to remove it.Speed is currently not an issue and I'd like to keep it that way.How I think I should do itThe restructure should be done using Backbone.js and events that call modules (i.e. on storage.loaded => init).Modules should each go in their own file, I'm thinking there should be a set of core files that all modules can rely on and call directly and everything else should be event based.Widget structure should be kept largely the same, but maybe they should also be split into their own files.AFAIK you can't load all templates in a folder, therefore they need to stay inline.Grunt should be used to merge all modules, plugins and widgets into one file.  Templates should also all be precompiled.Question:Should I follow my current restructure plan? Does that sound like a good starting point, or is there a different approach that I'm missing? Should I not do any of the things I listed?Do applications written with Backbone tend to be more intensive (memory and speed) than ones written in Vanilla JS?Also, can I expect to improve this with a proper restructure or is my current code about as good as can be expected?
Restructuring a large Chrome Extension/WebApp
design patterns;javascript;architecture;readability
Memory usage: Chrome apparently has a memory leak in extensions, they're trying to fix it but memory still keeps on getting increased every time the page is loaded. The app also uses a lot on its own.You need to define what alot is, and what too much is. Memory usage is only a problem when there isn't enough. Investigating memory problems has little to do with refactoring. You need to locate any offending code and plug the leak. If you know your code is leaking memory, than I would try to isolate the offending areas and go to stackoverflow.com to seek advise on fixing it.Code readability: At this point I can't follow what's being called in the code. While rewriting the code I plan on properly commenting everything.This is a very subjective issue. Code structure, source code comments and code readability are all matters of opinion. Module interdependence: Right now modules call each other a lot, AFAIK that's not good at all since any change you make to one module could affect countless others.Now this is where we can help you. There are multiple platforms and tools out there for Javascript developers to address these issues. There are also multiple design patterns that address these issues. There are package builders, code compilers and dependency injectors.I use AngularJS with Google's Closure compiler. Angular gives me dependency injection, and closure gives me compile time warnings and packaging.You'll have to decide what tools work for you. Trust me. It's a painful process to pick a tool.Fault tolerance: There's very little fault tolerance or error handling right now. If a widget is causing the rest of the page to stop rendering the user should at least be able to remove it.This is a high-level requirement. It's something to keep in mind when you are rewriting it.Do applications written with Backbone tend to be more intensive (memory and speed) than ones written in Vanilla JS?No. Backbone does not offer anything that addresses your specific issues. It's designed to be a light-weight library that offers you only a couple of base classes to mimic a MVC pattern. The developers wanted something that had a very light-weight foot-print. I don't think a Chrome extension needs to be light-weight. It's installed on the PC and runs local. You can afford to go with something heavier and offers a more robust framework.Also, can I expect to improve this with a proper restructure or is my current code about as good as can be expected?You've made some basic mistakes if fixed will greatly improve your time maintaining the code.I could create a list of issues, but that's not the point of this answer.What you want to learn is the building blocks of highly maintainable code.Have you put code into easy to locate files, or is everything in one big file?Can you tell by looking at your files what is new untested code and old reliable code?Can you test it?Does each file have a clear name and contain code that is clear of it's purpose.Is each file simple. Short and to the point.Are your functions written to prevent misuse.The list goes on like that, but hopefully you get the idea.