Общо показвания

декември 17, 2016

Малко истини в книгите за лични финанси

Да започна с това какво мотивира този пост.

Преди няколко седмици попаднах на профила на млад български предприемач. Зарадвах се на успеха на един съвсем съвсем млад човек и доста време прекарах разглеждайки какво е споделил за себе си и пътя си.

Направи ми впечатление, че в една от статиите си споделя няколко книги, които са му помогнали да се развие като личност и да извърви по-бързо пътя към успеха. Една от тези книги беше "The richest man in Babylon" на Джордж Клейсън. Не бях чел книгата и реших да отделя време и да видя какво пък толкова може да помогне една книга.

Самият Даниел споделя, че посланието на книгата е простичко: харчи по-малко от колкото изкарваш.

В книгата обаче навсякъде се натъртва на още две неща: 1) отделяй една десета от онова което изкарваш и го инвестирай разумно и 2) ако имаш вече натрупани дългове отделяй 2/10 от онова което изкарваш за да погасяваш дълговете.

Стана ми интересно, какво всъщност наистина може да се постигне ако се следва този съвет буквално, по начинът по който е предаден, включително и с примери от началото на 20-ти век (предполагаме че фантастичното действие представляващо по-големия обем в книгата се развива няколко хиляди години преди новата ера).

Бидейки един виден прагматик, направих табличката, която може да бъде видяна по-долу (Линк към табличката за по-удобно разглеждане). В нея са заложени няколко интересни неща:


  • данните са от 2000 година насам, за да избегнем труса с деноминацията
  • използвали сме средната работна заплата така, както е докладвана от националния статистически институт
  • разработени са и двата варианта (с дългове и без такива)


Разяснения:

  • ако сме следвали логиката посочена в книгата и сме спестявали 1/10 от заплатата си, към днешна дата би следвало да имаме спестени 10,868.40 лв. 
  • също по съвет в книгата, ако сме спестявали така посочената 1/10 и сме инвестирали разумно (заложил съм 5% дивидент на годишна база при месечни вноски 1/10 от заработеното) днес бихме разполагали 15,320.00 лв
  • ако приемем че сме задлъжняли и през цялото време отделяме 2/10 от доходите за разплащане към тези задължения, то за периода бихме "върнали" 21,736.80 лв.
  • ако през целия период отделяме 3/10 от парите (защото нямаме задължения, но се чувствае някак мотивирани да пестим повече) бихме имали 32,605.20 лв, а ако сме ги инвестирали разумно* - 45,959.99 лв





В "най-добрия" вариант (спестяваме 3/10 или 30% и инвестираме) сумата не изглежда голяма наистина, особено на фона на инфлацията, която се шири из нашите краища от доста време. От друга страна обаче кумулативното инвестиране на 30% от припечеленото за 16 години резултира в 42%, грубо погледнато за 16 години имаме една разлика от 12%.

Струва ли си?

За да преценим дали нещо си "струва" е необходимо да го сравним с алтернативни варианти. Един такъв вариант е да сме харчили всичко, което изкараме и да имаме 0.00 лв или минус някаква сума.

Друг вариант би било да ползваме кредитна услуга (например ипотечен кредит, фирмен кредит и тн) при който вариант нещата разчитаме така, че приходите възникващи на база инвестирания заем да покриват разходите по същия този заем и да генерират достатъчно разлика, за да има остатък (печалба).

Оставям на будния читател да си състави табличка за алтернативен подход, например "покупка на жилище за отдаване под наем през 2000 година", като цените на жилищата, кактои цените на наемите можете да получите като справка от всяка агенция, която оперира все още и е оперирала и тогава.

Истината е много проста: това, което изглежда като решение и може би е работило в древен Вавилон, днес е по-скоро консервативен вариант по няколко причини.

Вече знаем, че спестяващите биват наказвани от монетарната система след 1974 година (тоест необвъзразността на валутата с материална стойност), знаем също така, че ако искаме да имаме повече трябва да увеличаваме постоянно приходите си, най-добре по пасивен начин, защото в крайна сметка силите ни за работа не се увеличават с годините. Знаем и че монополизацията на кредитните системи е извършена с цел от една страна контрол над мнозинството и от друга поддържане на икономиката активна.

Взимайки предвид всички тези неща, моето мнение е, че съветите дадени в книгата е по-скоро неприложими ако търсеният ефект е онзи, който подобни съвети са дадени преди 4-6 хиляди години по-рано.

Дали ще изберете да ги следвате зависи само от Вас самите.

Послеслов: един много интересен съвет има даден в същата тази книга: не доверявай парите си на съвета на жената на месаря или на грънчаря. Съвет искай и взимай само от онези, които се занимават с правенето/наптрупването на пари.

декември 07, 2016

Web worker, RAF, nextTick - what is there to it?

Let's start with the premise: we want to know the details on how a combination of a web worker (i.e. event based communication with a separate thread in JS) can be used to process data and communicate with the main thread in regards of asynchronous job scheduling.

What is what

Request Animation Frame - from MDN

nextTick - an API for scheduling work after the event loop is emptied. We use an emulation using iframes so basically we get message broker in frames covered instead of the actual setImmediate as it only works in IE10+.

Web worker - single threaded JS execution environment that is a separate process from the main thread (i.e. it does not share anything with it and scheduling execution in it is not related to the scope of async programming from JS developer's perspective - we cannot influence when things are happening there but we have the guarantee that those things that happen follow the same rules: async, single thread)

So what are test results showing


  • responses from web worker always come in order (assuming no async programming is done there)
  • the timing of the responses varies (i.e. run the test several times and see how sometimes 1, 2 or 3 responses arrive before the RAF or nextTick execution kicks in)
  • nextTick kicks in after the first RAF


If you want to review the results make sure to: a) run the test several times and b) test in different browsers.

The code is here.

Conclusion: it is not trivial to drive animations and data processing from a worker instance if you depend on input for it.

януари 15, 2016

Reducing time to first paint

This post is about the new techniques recently discussed on events related to web app for mobile: how to make our web application behave more like a native one and reduce friction for our users and meet their greatest expectation.

In this post I will discuss how we managed to reduce the time to first paint in an app we already had developed. We will be measuring several things:


  • time to first meaningful paint
  • time to app readiness
  • time to first paint on first visit
  • time to app readiness on first visit
Why there is a difference? First visit is important for several reasons: even with service workers being readily available in Android one still needs to consider those first visits to the app which can happen at any time and any network condition, forcing the user to wait is not going to be very good for any conversion strategy.

Secondary visits, especially for devices that to not have the service worker enabled (or in case we decided to not use it for our app for some reason) can also be potentially problematic for several reasons: busted browser cache, new version of the app etc.

Lets start with some numbers!

The app is consisting of a single html file, a processed (built) css file and a javascript (also built).

index.html - 566 bytes
app.build.css - 50702 bytes
app.build.js - 188824 bytes

What were the measurements on load time with this initial state:
First visit:
  • time to first paint: 850ms
  • time to readiness: 1000ms
Secondary visit:
  • time to first paint: 15ms
  • time to readiness: 1000ms
Its not that bad, but this is a relatively small application and also we use landline network to load the app.

The one problem is that in first visit the user is staring at blank screen for almost a second, loading on slower networks would only exaggerate that and can make the user give up on our app.

How can be possibly reduce this time to first paint on first visit?

We can attempt and utilize a technique described as 'fake' first paint: provide only a skeleton on the actual app view and how it would be looking like when ready and provide it as soon as possible (possibly in the initial HTML with CSS only for it). 

This sounds okay, but the fact is we already have the application built and we did not wanted to invest too much, also the additional markup and styling would have to be maintained separately and updated every once in a while as the application evolves. 

We decided to go with another approach: separate the code that is responsible for the initial html structure into a module to be loaded first, let it execute (i.e. unblock the event loop) and only then load the rest of that app that will 'decorate' the pre-rendered html and make the application ready for the user.

How does this look like in the context of a mid-sized closure tool driven application?

Several steps were taken:
  • create a new namespace and render the main app template in it, it should be doing only that - requiring only the template and dom utilities
  • create the HTML loading module that invokes the namespace from previous step and asynchronously wait for the next event loop tick to start loading the application logic module
  • create the application logic module which should simply invoke your app (basically your main entry point from static (non modular) version
  • make sure your main app logic accepts a new option to tell it that it should decorate a preexisting html structure as opposite of rendering itself
An example:

//Step 1
app.html.rootElement = goog.dom.htmlToDocumentFragment(
    app.template.App({
      user: app.settings.RUN_AS_USER
    }).getContent());

//Step 2
html_init = function() {
  // Add thr whole view to the document.
  document.body.appendChild(app.html.rootElement);

  // Wait for the rendering to kick off.
  setTimeout(function() {
    // Configure modules.
    var mm = goog.module.ModuleManager.getInstance();
    var ml = new goog.module.ModuleLoader();
    mm.setLoader(ml);
    mm.setAllModuleInfo(goog.global['MODULE_INFO']);
    mm.setModuleUris(goog.global['MODULE_URIS']);

    // Tell module manager that the html module is loaded
    goog.module.ModuleManager.getInstance().setLoaded('html');
    // start loading tha app module.
    goog.module.ModuleManager.getInstance().execOnLoad('app',
        goog.functions.NULL);
  }, 10);
};


// Fireoff things immediately.
html_init();

// Step 3
app_init = function() {
  // Instanciate the app controller.
  (new app.Main(true));
  // Tell the module manager that the app has been loaded.
  goog.module.ModuleManager.getInstance().setLoaded('app');
};

app_init();

// Step 4
app.Main = goog.defineClass(pstj.control.Control, {
  /**
   * @constructor
   * @param {boolean=} opt_useDecorate
   */
  constructor: function(opt_useDecorate) {
    pstj.control.Control.call(this);
    /**
     * @type {boolean}
     * @private
     */
    this.useDecorate = !!opt_useDecorate;
    this.init();
  },
...
});


As you can see the change is trivial, but it allows us to do two things: reuse the actual application template (might it be not functional yet, but it looks exactly like the final result) and thus its automatically kept in sync with the application as it evolves and two: reduce the initial load size (the size of bytes needed by the app to reach first paint that resembles the app view for the user).

What are the new results (after this change):

First visit:

  • time to first paint: 400ms
  • time to app readiness: 1100ms
Secondary visit:
  • time to first paint: 15ms
  • time to app readiness: 1100ms
Not that bad for 20 lines of code: we managed to reduce the time to paint on first visit (or cache miss) by a half with a simple change of order of execution. 

Now one question arises: why not simply do it inside the main build: render the view first as a template, then free the event loop and then decorate the application logic on top of it. 

Yes, this was initially the intent, that is why we went with the option to tell the main app entry point to use rendering or decoration (step 4 in the example), but since closure compiler is so good with modules we decided to start using this technique to be ready for the growth of the application and instead of adding feature after feature to the main build simply module-base new features and load them on demand, but not before the user needs them. This will allow us to have a 10 times bigger application but still keep the initial load size (and times) the same. 

As you might have notices the separation of the built JS binary to two modules had a cost: ~100ms delay until application readiness, you should b aware of that and carefully examine the trade-offs when deciding if you should use this approach or instead go for the one described in the beginning and simply use a dummy scaffold in the HTML. In our case we wanted to stay as close to the existing code as possible.

How does this change result in code size?

index.html - 782 bytes (because we included the module info in the html, it could be instead pre-pended to the first module)
app.build.css - 50702 bytes
module_html.js - 70231 bytes
modules_app.js - 118707 bytes 

As you can see the size impact is insignificant. Interesting side effect since the change we made for the modules is that the initial module (module_html.js) does not change significantly or all if the templates do not change (for example if we add new views but use the rendering path instead of decoration one the views logic and its structure will still be in the later loaded modules thus not impacting the initial load).

As a final though: working with modules in closure is fun but is not as intuitive as one might expect it. Also there is no guided module separation and for this reason the developer has to be an expert on how closure dependencies work and how to arrange the files in such a way as to avoid direct dependency and instead add dependencies and code indirectly. In more modern solutions (like Dart for example) requiring a piece of code (or a whole library that is) lazily / on demand is as simple as adding a modifier to the import and whenever you need make sure to load it first

import 'myasynccode.dart' deferred as myasync;
// later on in my code
main() {
  // Wait for user to request that piece of functionality
  await myasync.loadLibrary();
  // call code from library
  myasyncMethod();
}

Never the less closure can be used successfully to manage async code loading and thus help us with the task of greeting our newly come users as fast as possible with the best product we can offer.

Happy coding!