Progressive Web Apps With QCObjects
Tags: qcobjects, javascript, beginners
Published: 2019-06-09 06:57:47

Web apps development is in huge demand. Learning curve is becoming too steep. Developers are facing the challenge to be faster than ever producing good quality code. 

And even now, despite of the growth of device native apps itself, a conventional thinking that a web app "must be like" a native app had become more and more accepted by the community. That's why progressive web apps do exist.

QCObjects integrates many tools in a securer, faster and easier to learn runtime components scope, so why not use it to make a compelling progressive web app that also can be designed into an N-Tier architecture, and all of this using pure javascript?

Look, if you want to make a professional web application, you need to first think about these three basic concerns:

- Performance 
- Accessibility 
- Best Practices

So, let's talk about performance:

Browser engineers recommend pages contain fewer than ~1,500 DOM nodes. The sweet spot is a tree depth < 32 elements and fewer than 60 children/parent element. A large DOM can increase memory usage, cause longer style calculations, and produce costly layout reflows. Learn more about this [here](https://developers.google.com/web/tools/lighthouse/audits/dom-size).
QCObjects was designed thinking in this. That's why you can append an object into the DOM tree making possible to rebuild nested components on the fly. This will reduce considerably the depth of DOM nodes in your PWA.

To increase performance, you can code a service worker that uses the cache api to work offline instead of fetching the content again and again. QCObjects makes the service worker registration at the load of the PWA, you only need to specify the service worker uri by typing the corresponding CONFIG set. 

To increase the performance even more, QCObjects has a Complex Cache Control that allows you to save any object "stringified" to the localStorage and get it back. Components had a built-in cache control based on that complex cache control so you can either leave QCObjects to use cache for all components (Components.cached=true), or set cached property independently for every single component instance.


What about accessibility?

To make your professional PWA accessible, sometimes you need to repeat a lot of code. With QCObjects you can organise your code into components that are loaded in your PWA in runtime. Every component has an isolated building behavior, so you can build and load a component outside the DOM, but even after you do that, you can append the body of a component into the DOM using the append method that QCObjects has injected  into the DOM prototype. For example: by this way, you can make a component that contains the PWA information meta tags once filling it with dynamic data. This will make you happy when you want to save the meta information in a server to make changes to a bunch of apps that are already published and you don't want to make a new version only to change the app description.

OK, let's go ahead an do the best practices: 

1.- Using a good layout. 

With QCObjects you can use any of the most famous CSS3 frameworks to bootstrap your web design. But then, you want to make your own customisations. For that, you can use SourceCSS QCObjects class, that is very useful to import a CSS file in the head of the document "dynamically".

1.- Creating your first application

To make your first PWA application using QCObjects you only need to type this in your console: 

```shell 
> npm i qcobjects-cli
```

Then, create a directory for your app and enter it:

```shell
> mkdir mynewapp && cd mynewapp 
```

Finally, generate the new app template using the cli tool

```shell
> sudo qcobjects create mynewapp --pwa
```

Done.

2.- Serving over HTTP2

Once you've created your application, you can serve it using the qcobjects-server tool installed with the cli tool. Go to the app directory and type:


```shell
> qcobjects-server 
```

and press enter.

Then, go to a web browser and navigate to: 


https://localhost 



3.- Registering a service worker:


To register a service worker using QCObjects you only need to specify the CONFIG setting. In your init.js , put the following line:



```javascript
        CONFIG.set('serviceWorkerURI','/sw.js');
```


This means QCObjects will look for /sw.js in the root directory of your app and will register as a service worker. You can use navigator.serviceWorker.ready.then(...) to attach any code after the service worker is loaded.


```javascript
navigator.serviceWorker.ready.then(function (){
   logger.info('service worker is done');
})
```


5.- Adding push notifications:

Adapting the official code of [Mozilla](https://developer.mozilla.org/en-US/docs/Web/API/PushManager#Example)


```javascript
  Class('PushNotifications',InheritClass,{
    _new_:function (){
      window.onpush = function(event) {
        console.log(event.data);
        // From here we can write the data to IndexedDB, send it to any open
        // windows, display a notification, etc.
      }

      navigator.serviceWorker.ready.then(
        function(serviceWorkerRegistration) {
          serviceWorkerRegistration.pushManager.subscribe().then(
            function(pushSubscription) {
              console.log(pushSubscription.endpoint);
              // The push subscription details needed by the application
              // server are now available, and can be sent to it using,
              // for example, an XMLHttpRequest.
            }, function(error) {
              // During development it often helps to log errors to the
              // console. In a production environment it might make sense to
              // also report information about errors back to the
              // application server.
              console.log(error);
            }
          );
        });
    }
  })
```

To activate this class, use the following:

```javascript
let pushNotifications = New(PushNotifications);
```

Please let me know how to improve this article in a comment!

Cheers!