Create two templates: "addresses" and "address". Put in a checkbox called "primary" and attach other fields (i.e. FieldtypeStreetAddress). Create a pagefield on the user template called "addresses". Now you can have as many addresses as you want, but when the user loads it won't instantly loads all the address field. Just the page field with the ID's. If you need to render it on the front-end with the primary first, you can easily sort or assign another class to highlight the primary address. Since the Page field is really powerful and we use a relational database, try to use it as much as you can. Be careful with too many joins, but for this use case it would suffice.

First off, just increase raw power. Try bumping up your VPS with more power. Easy solution and this stuff is so cheap nowadays.
Upgrade the software if possible
I've had instances with 300+ fields on a template with more than 500k pages. Queries started to slow down around 200 fields. I bumped the Mariadb version to the latest, switched to INNOdb, PHP 7.2.x and it was running pretty smoother on a digitalocean medium sized VPS ($40/mo). We also had tons of runtime fields and we cached those so a page save would do the calculations instead of calculating runtime. When we eliminated those the application became really snappy with 200-300 concurrent key users doing all kinds of imports and running reports while the 1000 regular concurrent users didn't notice lots of slowdown. Most of the slowdown nowadays come from the interface itself. We used a lot of jQuery kinda tooling inside ProcessWire admin and since the users don't have the fanciest computers, some browsers are not really capable of rendering the back-end. I guess we needed to switch to a SPA, but I'm not working on the project anymore.
Jup, this is the key. Especially while desiging applications this is really important.
Try to split up as many as you can. I don't store address information on the order, but on the client, and possible even on an address template which you can re-use. You can also use Page fields to combine all those. To comply to GDPR you can also store the blob of address info in one or two fields on the order itself. So if a client requests to remove his data you can easily remove the accoun and associated addresses. And you still have the address data.
Another solution is to use the FieldsetPage to create on instance of all address/personal information. In the background PW creates another page containing the info. You add this field to the page once for invoice and once for the shipping info.

Any updates on this? I've been occupied lately, but spotted some details too. A seperate repo would be awesome. I've referenced the Ember kind-of-way before (including their awesome RFC process), but I also like their approach to a volunteer based website on github. Also checkout the README with other public repositories too. All community / PR merge request based.

In my setup each site is a rootPage. So in my case there are two rootPages:
Home
Company one (NL, DK, DE, EN)
About us
Employees
Contact
Company two (NL, DE, EN)
About us
Employees
Products
Contact
I also set the language based on the domain.

I have one multi-lingual, multi-site set-up running with Soma's module with the following config:
Two sites
Company one
NL -> domain.nl
EN -> domain.com
DK -> domain.dk
DE -> domain.de
Company two
NL -> domain.com/nl
EN -> domain.com
DE -> domain.com/de
The only real caveat (other than the issues mentioned by Soma) I see is that you define languages a top level. So whilst we don't use DK on Company two the language is visible in the admin. I always wanted to create a solution for this, but since the client doesn't gave a high priority it is still an idea.
Another thing is I had to manually create xml sitemaps since the sitemap modules are not compatible with this set-up.
edit: Since the website at root parents pages allowing access to only one site is pretty easy using AdminRestrictBranch.

We ran into issues after a few days (luckily we noticed the errors ourselves) so we were pretty quick to use the Decimal field by sforsman. We didn't use floats for money luckily. We pinged Ryan back in the day to implement this in the core or at least throw a warning when someone uses the float field. We also needed to make a distinguish between empty and 0 values so the client could use this in ListerPro to filter on. That is why there a fork. You can see more discussion here -> https://github.com/processwire/processwire-requests/issues/126.

You can also override the theme by using the classname of the theme and adding the extension.
From the top of my head, no. Just make sure the naming is 100% identical. If no dependancies it should work bases on the file naming. You might want to get more support in the relevant support thread.
Not sure. You can easily hook into this. I like to core to be as lean as possible since Ryan is effectively the only one working on it.