We all get excited (hopefully) about starting from scratch with the latest version of our favourite framework, maybe a brand new app, maybe a port or rewrite of existing but if we are not careful, we will rush in, build some poor foundations and then end up with the same mess we wanted to leave behind when deciding to do a rewrite.

Of the several rewrites I have done, I think the best overall advice is: Get a small part of everything working in a Proof of Concept (PoC), which allows you to choose the best patterns, try out some alternatives for each part of the system, wire up various systems which are often left until later (and which are then a pain to wire up) and to look at the result and see whether various maintenance activities look like they will be easy enough to perform.

Below I have listed some of the considerations.

Framework/language

This is often already decided by our expertise. If we write .Net, we'll probably choose that and I personally think that's fine. .Net Core and Java might be miles faster than PHP in certain online speed tests but in most cases, the combinations of code, hosting and expertise will all have more of an impact on the final performance than the pure choice of language/framework.

The issue that can be a bit more tricky to decide is whether to replace something like .Net+Razor with .net+ReactJS which does give some nice advantages but the same rules apply to the decision. Expertise first and then try a number of slices of your system and see if you can understand the ReactJS way more easily than the Razor way.

CSS/SASS/etc

If you are not using some kind of CSS compiler then you should be. Hand-cranking CSS is a pain but there are still decisions to make, most of which will probably be dictated by your choice of UI framework. LESS and SASS/SCSS are the most common but again, stick with expertise since the differences are probably not great for most of our applications although read the niche cases and decide for yourself.

Once you have chosen a platform, you will then need to decide how to produce the CSS files themselves. You can pre-compile and put them in the webroot somewhere, you can pre-compile and send them to a CDN or you can have a CSS pre-compiler wired up so that any calls to the resources calls into the file system, builds things if needed and returns back the correct version. Each of these has advantages and disadvantages but you should consider how somebody is going to update a CSS file after deployment. Are you happy to do a full deployment to achieve this? If not, you need automatic cache busting strings that are generated, usually from MD5 hashes of the file, appended to the resource paths.

Bundling

Another no-brainer is bundling resources into few HTTP requests. If you have 10 scripts, you can create a single bundled JS that gets loaded with one request. You will again have to balance the reduction of HTTP requests with the other extreme of a single very large bundle that most pages won't use and which will change every time anything inside any script changes. We used to have a common js and then page-specific ones so that 2 requests was still OK but we didn't bloat pages unecessarily.

Again, this can be pre-compiled (using gulp for example) and then put onto the web server or CDN as well as being generated dynamically.

Minification

Similar to the above, minifying files is easy and can save quite a lot on transmission sizes. As above, they can be pre-compiled and used locally or on a CDN.

Internationalisation

Unless you know that you will never translate a site, which most of us probably don't, then we need to try out some alternatives, even if we don't bother translating everything now (a good system should be easy enough to use, even if there are no translation yet). Ask yourself not just how the app will work but where is the work being done? Where is the data being transmitted to/from and how will you manage updates to translations? Database-translations are dynamically updatable but might cause a performance hit. Static ones are faster but might require a full deployment to update. Maybe you don't update text that frequently, maybe you do.

I recommend looking at Mozillas Fluent translation framework which has some really clever ideas in it like how to specify that in English we might only have single or plural but in other languages, there are other multiples.

Caching

Unless you absolutely know that no more than 20 people will ever use your app at once (and sometimes even if it less than that), caching is critical for moving performance into RAM where it is fast and away from the database which is expensive and hard to scale. Getting the pattern right, however, is not always easy. You want the code to read fluently and not have random places that caches are used. You also want to be careful assuming that just because a caching interface is built-in, that it is exactly what you want or need (Yes .Net, I'm looking at you!)

Authentication

Most frameworks have authentication functionality built-in but they are not all great and the configuration is not always easy. As well as basic "Form authentication" that uses username/password, think about OAuth2/OpenID Connect for single-sign-on, 2-factor functionality for security and a system that allows a modern and correct storage of password hashes (Not MD5 - I will cut you!).

The basic HTML layout

Although we theoretically separate content from presentation, the reality is that each UI framework has a certain required set of elements in order to work. Most dialogs are not a single div but might contain nested divs for the title, body and footer of the dialog. Since we might need to change these from what we start out with, we need to keep the code in re-usable units so that if we have to add another nested div for our new framework, firstly we only change it in one place and secondly, we don't break everything in the process.

We also need to ensure that we liberally apply classes or ids to decorate sets of elements so that if we need to pick out, e.g. menu buttons, we can easily do this in CSS and not be finding stuff in files! Following the lead of the frameworks is easy enough, look how Bootstrap (or someone else) decorates the elements in a menu to be nice and selectable in the style sheet.

Horizontally scaling

If you are not building rubbish, it's almost certain that you need to scale horizontally on your web servers. You need to think about sharing session content, even if you use sticky sessions, using a database or other shared system. You also need to avoid using the local file system for anything that needs permanently storing. Use cloud storage instead, which can be shared between all your servers and more importantly doesn't get lost when a server dies (and they do die).

Automation and Devops

You should also design your app to deploy in one-step and ideally in a cookie-cutter way. To get true elastic scaling you do not want to carry out 100 steps of deployment and especially do not want to do anything manual other than changing the number of replicas you need. You need to think about how appsettings will get injected either by the deployment tool or by the system itself.