On weight loss

As I enter my 40s, I decided to lose some of the weight I gained in my 30’s. Over the last 65 days, I lost nearly 10kg over weeks.

In addition to the aesthetic benefits, there are a significant health benefits associated with weight loss, particularly with reducing the risk of certain cancers, heart disease, diabetes, etc. Changing your diet can also significantly reduce how much you spend on food, and even have a positive environmental effect: as you significantly reduce the amount of animal protein you consume every day. Specially if you eat beef, which is pretty terrible in contributing to climate change.

I did a fairly aggressive weight-loss regime based on a couple of books+videos on body composition, nutrition, exercise, and – the often overlooked, but most critical – sleep. Below I describe how I lost ~1kg (~2.2lbs) per week.

You don’t need to be as aggressive as I was – I’m currently living on 1450 calories (~6000kj) per day, as I kinda just want the process over and done with.

Disclaimer: I’m (barely) a software engineer. I’m not a nutritionists nor a personal trainer. Weight loss is literally a form of starvation and the body will do things to defend itself. If you do this, expect it to really suck. Below I describe what worked for me. But it might not work for you.

What to expect

The losing weight part is not particularly difficult. That hard part is how your body reacts to being put into what is effectively starvation. Expect your social life to also take a toll, as dieting is extremely anti-social behavior and limits what you can consume (i.e., alcohol is mostly out, as are fun party foods, chocolate, etc.).

Social

What I personally wasn’t expecting was the negative reactions my weight loss. People seem to take your weight-loss as some kind of personal attack on them. For me, this translated to not wanting to be around people, as it felt like people were either trying to actively sabotage what I was doing, or I was letting people down by not enabling them to drink, eat, or whatever, in both moderation and excess. I enjoy drinks and dinner with my friends, so the diet has been difficult with respect to that. Now that I have a better understanding of the inputs/outputs of my own body, I hope that I can manage social situations better.

Ups and downs

Weight loss happens over time (i.e., it’s a trend), it’s not a day to day thing. Some days you weigh yourself and you’re 1kg heavier, then you weight yourself the next day and you’ve dropped 500 grams!

Sometimes, you can go up in weight an entire week and then suddenly drop – or your weight seems to stall. Other times, you think you’ve over eaten and undid all your fine work… only to find you’ve dropped a kilo for no reason!

The main thing is not to get worried when your weight goes up, as long as the overall trend is down. Basically, have faith in the system.

First month

The first month was really rough. For me, it meant:

  • Fatigue: in the first month, I felt super tired and ended up having to take 1-2 hour naps. It was also harder to get out of bed in the morning for a few weeks. This passed in time.
  • Exercising became very difficult: whereby my running times went from ~27 minutes to 31 minutes for a 5km run – I also stopped going to the gym for about 4 weeks. This passed, and I’m now running 5km in 26 minutes without any problems. I’m also back at the gym, usually going 2 times per week for around 2-3 hours.
  • Light headedness: My blood pressure kinda went all over the place and I became light headed at times. This also passed after about 6 weeks, but it was a bit scary. It even happened to me a the gym.
  • Although I’ve not exactly changed how I’d been easting over the last few years, the reduction in what I was eating did cause havoc with my digestive system (and still does even today).
  • A lot of dreams about food… about binging eating and feeling bad, about foods you miss and eating them in moderation, etc. and just weird dreams involving food.
  • Boring your significant other with stats, unsolicited health advice, and having to hear about all of the above. Sorry Barbara!

With an understanding of some of the fun side effects, we can dive into the actual weight loss.

Things you need

There are some things I’ve found indispensable in the weight loss process:

  • Calorie counter application – I recommend “Lose it!“. That’s right, we are going old school and counting calories to lose weight. The nice modern twist here is that apps like Lose It support scanning barcodes and even food – so it makes it easy… so long as you know how much you are putting in. Also, don’t be a cheap-ass! buy the subscription to the app. You will be saving so much money on food that you won’t even feel the cost of the app – and you can always unsubscribe to the app once you are done.
  • kitchen scale. Measure everything you eat, and put it into the app.
  • Body composition scale. I recommend the Renpho scale. It’s wieldy inaccurate, but it’s good enough.
  • Vegetable steamer: we are going to eat (literally) a ton of vegetables, and boiling vegetables is disgusting and just wrong!

Caloric deficit

The easiest ways to force the body to consume stored fat is to enter what is known as a caloric deficit: if input less calories than the body needs to burn everyday to function, it will instead use stored fat to stay alive and function correctly.

The precise value to put the body into a caloric deficit depends on a bunch of variables, but you can find calculators online to give you an idea of how many calories, on average, someone of a certain age, sex, weight, height, etc. burns per day: Google for “calorie deficit calculator”.

Once you know that number, you can basically subtract the number of calories from you diet that would result in weight loss. The Lose It app I mentioned above just has a scale: “how much do you want to lose per week?”. Once you set it, it automatically just suggests how many calories per day you are allowed. Then you just follow that. It’s pretty straight forward, and the app just adjusts to your weight loss over time.

When I started, my weight was 91kg, and I wanted to lose 1kg per week, so my budget was 1576cal/6594kj per day. As you become leaner, however, your body becomes more efficient, so you need less fuel per day.

At the time of writing, my weight is 80.6kg my budget is 1432cal/day to maintain a weight loss of ~1kg/week.

Body composition

Body composition is basically your fat/muscle ratios. By messing around with nutrition (i.e., food) it’s possible to manipulate your body composition significantly. Similarly, doing particular exercises with the right nutrition allows you either lose weight and/or gain muscle:

What we are doing is is basically a form of body hacking.

Nutrition

Nutrition basically comes down to 4 things:

  • Fats – oils and animal fats.
  • Carbohydrates – fiber and sugar.
  • Protein – mostly from other animals, but some from plant.
  • hydration – water, drink it… lots of it (over 1 liter… go for 2 liters).

Each basically playing a significant role in maintaining and manipulating body composition.

Fats

All fats are delicious, and in themselves don’t actually make you fat. It’s sugar that makes people fat, as it’s sugar that the body converts into fat.

However, fats super calorie/energy dense and will easily blow your daily calorie budget. Basically, we want limit fat input as much as possible not because they will make us fat, but because they will inhibit our ability to be in caloric deficit.

For example, I limit myself to 5 milliliters of olive oil in a salad (40cal) or 5 grams of butter (36cal) when cooking anything.

Eat protein, lots of it

The one we care most about in the above is protein. Protein synthesis allows us the body to build muscle, and it’s also critical for not losing muscle while we lose fat. You don’t want to end up all skinny, but also all lose all your muscle in the process. That defeats the purpose.

As a general rule, we want to eat as much protein as possible. A good goal is 1.7 x your body weight in kg… or easier, your body weight in pounds / 100. So, for me, ~170g of protein per day.

Eating that much protein can be hard, so I recommend buying whey protein powder. I’ve been using Pure Product Australia Whey Protein for about 1 year. It’s about AU$27 per kilo and usually lasts me about 6 weeks. It’s great for making protein shakes (337 calories):

  • One spoon of protein powder is 24g of protein,
  • One banana (optionally frozen).
  • Ice + water.
  • Optionally, soy milk.

Other great source of protein is eggs. I either eat 3 eggs for breakfast.

Lean meats are also a great source of protein. Basically, any fish is great because they are low in fat. Chicken breast is also really good as are chicken thigh fillets without the skin. You can generally get away with eating about 200 grams of those per day.

Beef is more complicated, because of the amount on fat (unless it’s lean). If you are eating a sirloin steak, you can generally get away with eating about 100 grams. That might not sound like a lot, but it goes a long way.

Stop eating sugar and processed things

White/added sugar is just terrible. Avoid it at all costs.

Likewise, machine processed things generally contain massive amounts of calories. This includes, bread, pasta, cheese, processed cereals (e.g., corn flakes), etc. and can basically blow your calorie budget. If it’s not fresh, or comes in a box, just avoid it.

Instead, replace all of the above with fruits and vegetables.

Fruits and vegetables

Obviously, fruits and vegetables are amazing, but some are more amazing than others. Anything sweet is going have move calories than anything not as sweet… all the way down to the tasteless, like cucumbers.

Some examples:

  • 100g Frozen cherries is 60cal.
  • 1 peach is ~45cal.
  • 1 mango is ~192cal.

As most vegetables are mostly water, they have little actual nutritional value in terms of calories. So you can basically eat large amounts amounts of them without any care. For example:

  • 100g of Cauliflower is 29cal.
  • 60g of mixed salad is 12cal.
  • 200g of capsicum is 50cal.

Nuts

Although delicious, they are unfortunately super calorie dense. I personally still can’t resist them, but try limit myself to around 20g of almonds or pecans per day (~120cal).

Exercise

If you’ve been going to the gym for ages, and not seeing any results, it’s likely your nutrition is off/wrong – but genetics also play a significant role.

The body is a highly efficient machine, basically meaning that exercise is mostly useless for weight loss, unless you really know what you are doing. To burn off the equivalent of a small meal, you need to either walk for 1.5 hours, or run 5km/3 miles in less than 30 minutes.

Nevertheless, I still recommend incorporating running, walking every, or going to the gym every second day (always with a day of rest!) – if only because it’s fun, and it gives you a few additional calories that you can add to a meal. I.e., don’t look at exercise as a means to lose weight, more as a means of getting more calories.

Sleep

Sleep is so critical to weightless that it needs to be mentioned up front. It’s much more critical than exercise. As anyone that’s weighed themselves at night, and then weighed themselves again in the morning knows, weight loss happens while you sleep.

Thus, good quality sleep is absolutely critical to weight loss. Basically, the more you sleep, and the better you sleep, the quicker you lose weight.

Aim for at least 7 hours. If you are like me, I tend to wake up after 4 hours. I then do my sleeping in 2 blocks, with 1 hour in between. For example, I go to bed at 2am, wake at 6am because my cat likes to eat then. I then generally try to go back to sleep at before 7am until 10am.

On the weekend, I try to cram in 9-12 hours if I can. So, again, 2am, get up at 6am for a bit, then go back to sleep until, if I can, 1pm.

Typical day

Finally, this is typical day for me:

  1. Sleep 7-8 hours – usually in 2 x 4 hour sessions.
  2. Have either 3 eggs for breakfast or protein shake.
  3. A coffee, made with 80g of soy milk.
  4. Lunch: 100g of salad leaves, a can of tuna, ~150g of mixed vegetables.
  5. Another coffee, with another 80g of soy or cow’s milk.
  6. If I’m going to gym: another protein shake (whey protein + a banana).
  7. Go for a 5km run (30mins) or 1.5 hour walk.
  8. Dinner: either 200g of fish or skinless chicken, or 100g of beef or lamb. 60g of salad, 100g of broccolini or other steamed vegetables, such a green beans.
  9. Desert: 1/2 a mango.
  10. If I’m still hungry, a tea made with ~80 ml of milk.
  11. Snacks: 10-20g of nuts, fruits: peach, apple, or pear, etc.

That’s usually just around 1400Cal.

Putting down event infrastructure in Gecko

Implementing simple DOM Events in Gecko is fairly straight forward. A number of C/C++ macros have been written over the years to take away some of the pain.

In this post, I’ll explain how “window.onappinstalled” is implemented.

Web IDL

In this case, I’m interested in implementing the “appinstalled” event handler on the Window object. To do that, we start by defining the WebIDL in Window.webidl:


partial interface Window {
  // Pref'ed - see how to pref things in Gecko.
  [Pref="dom.manifest.onappinstalled"]
  attribute EventHandler onappinstalled;
};

Window only events

The events in Gecko are defined in the EventNameList.h header file. This allows you to define a variety of different event types.

For our case, we are interested in a “window only” event, so we can use the “WINDOW_ONLY_EVENT” macro.

As stated in EventNameList.h, each event entry in this file consists of 4 pieces of information:

The name of the event
This needs to match a GkAtom in nsGkAtomList.h
The event message
This is also generated with a macro, but needs to be defined via EventMessageList.h
The event type
See the EventNameType enum in nsContentUtils.h)
The event struct type for this event.

so, basically, for “window.onappinstall”, we define:


// Install events as per W3C Manifest spec
WINDOW_ONLY_EVENT(appinstalled, // nsGkAtomList.h
                  eAppInstalled, // EventMessageList.h
                  EventNameType_None,
                  eBasicEventClass) 

Event Message (EventMessageList.h)

As stated in the file, an event message must be defined as follows:

  1. Starting with “e” prefix and use camelcase.
  2. Basically, use same name as the DOM name which is fired at dispatching the event.
  3. If the event message name becomes too generic, e.g., “eInvalid”, that may conflict with another enum’s item name, append something after the “e”
    prefix, e.g., “eFormInvalid”.

So, in our case, we just want “eAppInstalled” as the message:


NS_EVENT_MESSAGE(eAppInstalled)

That should do it.

Putting APIs behind a pref in Gecko

Putting WebIDL APIs behind a flag in Gecko is surprisingly easy. Gecko supports an extended WebIDL attribute called “Pref”. You can use it on either interfaces or individual attributes, like so:

[NoInterfaceObject, Exposed=(Window)]
interface AppInstallEventHandlersMixin {
  [Pref="dom.manifest.oninstall"]
  attribute EventHandler oninstall;
};

You can see other examples in this dxr search for Pref= throughout Gecko’s tree.

Where it gets a little more tricky is testing, which I cover below.

Setting the preference

Normally, if you want something behind a preference, you want to have it disabled. The place to declare the preferences is in the modules/libpref/init/all.js file.

For example:

// Whether window.oninstall from "W3C Web Manifest" is enabled
pref("dom.manifest.oninstall", false);

Testing

Once you’ve added Pref= extended attribute, and disabled your feature, you will naturally want to test it using Mochitests.

Browser test

Creating a browser test for something like the above is fairly straight forward. Just Cu.import Services and set the pref type. In my case, I just had a boolean, so we can create a simple promise wrapper for SpecialPowers.pushPrefEnv():


// Enable window.oninstall, so we can fire events at it.
function enableOnInstallPref() {
  const prefs = new Map([
    ["dom.manifest.oninstall", true]
  ]);
  const ops = {
    "set": [...prefs.entries()],
  };
  return new Promise(resolve => SpecialPowers.pushPrefEnv(ops, resolve));
}

add_task(function*(){
  yield enableOnInstallPref();
  // do the rest of the test.
});

You could synchronously set the preference here using Services.prefs. API, but Boris Zbarsky warns: “Yes, but what unsets it so you don’t pollute the environment for later tests? pushPrefEnv handles this for you.”

Content tests

Content tests are a little more tricky, because you need to asynchronously set the preference, and then create an iframe. As Boris explains:

WebIDL conditional annotations for an interface are evaluated once per global: when the interface prototype object is created. The right way to write tests that toggle such prefs is to set the pref (via pushPrefEnv, please, not setBoolPref!) then once the pref is set create a new global to test in: either window.open or creating an iframe.

So, let’s now let’s pretend you have a file called “test_window_oninstall_event.html”. We can create a enableOnInstallPref() function that returns a Promise. Once the promise resolves, we create the iframe and again resolve with Window object. We can then run:


"use strict";
SimpleTest.waitForExplicitFinish();
function enableOnInstallPref() {
  const prefs = new Map([
    ["dom.manifest.oninstall", true]
  ]);
  const ops = {
    "set": [...prefs.entries()],
  };
  return new Promise(resolve => SpecialPowers.pushPrefEnv(ops, resolve));
}

function createIframe() {
  return new Promise((resolve) => {
    const iframe = document.createElement("iframe");
    iframe.src = "about:blank";
    iframe.onload = () => resolve(iframe.contentWindow);
    document.body.appendChild(iframe);
  });
}

function firstTest(ifrWindow){
  return new Promise(()=>{
    const hasOnInstallProp = ifrWindow.hasOwnProperty("oninstall");
    ok(hasOnInstallProp, "window has own oninstall property");

    // no point in continuing
    if (!hasOnInstallProp) {
      const err = new Error("No 'oninstall' IDL attribute. Aborting early.");
      return reject(err);
    }
    // do other tests
  }); 
}

function secondTest(ifrWindow){/* other test */}

// We can now do everything in order
const finish = SimpleTest.finish.bind(SimpleTest);
enableOnInstallPref()
  .then(createIframe)
  .then(firstTest)
  .then(secondTest)
  .then(finish)
  .catch(err => {
    dump(`${err}: ${err.stack}`);
    finish();
  });

If you would like to see the full code that this example is based on, please take a look at the attachments in Gecko Bug 1280777 – put window.oninstall behind a pref.