Debugging PWA’s locally – or how to get a angular 100% Lighthouse score

Yesterday at the @NgStuttgart Meetup, we had a really good time with two talks:

  • “What’s new in Angular 8” (David Muellerchen – GDE – @webdave_de – webdave.de)
  • “Improving UX by performance with Angular” (Steffen Stähle & Florian Tischler – @Steffen_Staehle & @floriantischler)

During the talks we came across a little node tool called local-web-server it helped me a lot when debugging Angular PWA’s locally. It offers

Build a angular PWA

First of all I’ve created a simple angular application (including the new ivy rendering engine, because I can):

➜  npm i -g @angular/cli
➜  ng new pwa --routing false --style css

And added PWA support afterwards:

➜  ng add @angular/pwa

Now we need to prepare some small additions to our application code.

In our index.html add the following two lines between to the head of our html document:

<meta name="Description" content="Put your description here.">
<link rel="apple-touch-icon" href="/assets/icons/icon-192x192.png"/>

In our tsconfig.app.json add the following part, to enable rending with the new Ivy render engine:

"angularCompilerOptions": {
  "enableIvy": true
}

And finally build our PWA:

➜  ng build --prod

Now let’s go and get that Highscore.

Setup the local web server

I’ve installed the package local-web-server globally:

➜  npm i -g local-web-server

This gives us a new CLI command “ws”, which serves the current folder on port 8000. It supports HTTPS and HTTP/2 out of the box. But to get a green pad icon in our browsers, some more preparation steps have to be done.

They have an awesome wiki on GitHub:

https://github.com/lwsjs/local-web-server/wiki

I decided to go with the “How to get the “green padlock” using the built-in certificate” way on my development MacBook.

These where the steps I did (have a look at the wiki for more details).

➜  open /usr/local/lib/node_modules/local-web-server/node_modules/lws/ssl/
  1. Open Keychain Assistant
  2. Import the certificate “lws-cert.pem”
  3. Open it and select “Always trust”

Now we are ready to rock!

Lighthouse that thing…

Now we fire up the server with http2 and spa support

➜  cd dist/pwa
➜  ws --spa index.html --http2 -z --port 443

Now fire up your browser of choice (still chrome for me :) and open and see the our app.

https://localhost

Lighthouse

Now let’s check what we got, using lighthouse.

➜   npx lighthouse https://localhost --view

Looks good, but what happened to the PWA part?

Runtime error encountered: Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Details: net::ERR_CONNECTION_REFUSED)

I do not know if this is a Lighthouse or ws bug. But I’ve found a way to get around this issue. When we go to the details we see, that there is a line saying:

Redirects HTTP traffic to HTTPS Error!

So let’s setup a HTTP to HTTPS Redirect using local-web-server, following these steps:

https://github.com/lwsjs/local-web-server/issues/86

Open a new shell and create a file called redirect-everything.js:

module.exports = MiddlewareBase => class Redirector extends MiddlewareBase {
    optionDefinitions() {
        return [
            { name: 'redirectPort', type: Number, description: 'Port which is used to redirect to https' }
        ]
    }
    middleware(options) {
        if (!options.redirectPort) {
            console.warn('\x1b[33m%s\x1b[0m', 'redirectPort parameter is not set, defaulting to 4443');
            options.redirectPort = 4443;
        }

        return (ctx, next) => {
            // Check if protocol is http
            if (ctx.protocol === 'http') {
                // Replacing url with https parameter
                const httpsUrl = ctx.request.href
                    .replace('http', 'https')
                    .replace(options.port, options.redirectPort);

                // Enforcing redirect
                ctx.redirect(httpsUrl);
            }
        }
    }
}

And run the server with:

➜  ws --stack ./redirect-everything.js --redirectPort 443 --port 80

So let’s run another lighthouse test:

➜   npx lighthouse https://localhost --view

Finally all the bits and pieces come together and we get a perfect lighthouse score in an angular ivy app.

Fully interactive after ~1s with 65,7 KB on the first load and a 100% lighthouse score. I would say this is a very good start for your next project.

64,2 KB!
That thing is interactive, BEFORE the browser is trying to get the favicon =)

And finally … it is installable. Good Bye App Stores, you’ve always been that unwanted friend at the party ;)

GTA V Self-driving car

I’m currently half-way through my Udacity Self Driving Car Nanodegree and this clip is amazing.

We are building the future of mobility here at Bosch and I’m really looking forward to the world of autonomous cars (where accidents are solely produced, by “human” drivers like we see in the clip @4:13).

[email protected] – add API proxy

Create a file like “proxy.json” in your [email protected] projects’ root.

{
  "/api": "http://localhost:1337"
}

start your development server with:

🍰  $ ng serve –proxy-config proxy.json

All request to

http://localhost:4200/api/v1/endpoint

will now be proxied to

http://localhost:1337/api/v1/endpoint

 

Pro Tip:

add

"start": "ng serve --proxy-config proxy.json",

to the scripts section inside of your package.json and use the following command for development: ;-)

npm start

Delete a remote Git tag

Because i have to look it up all the time (and WS has no UI support AFAIK)…

If you created a tag like ‘mytag’ you can delete it by running:

git tag -d mytag
git push origin :refs/tags/mytag

That will remove ‘mytag’ from your local and the remote repository.

Your Lead Architect Doesn’t Really Understand Microservices

http://thenewstack.io/genius-techie-doesnt-really-understand-cloud

There is no doubt that hype trumps learning, and that’s just a fact; we have a wealth of available and immediate information now in the Internet age. It takes time for experts to discern what matters and what does not. But in the end, following the leader may be the best approach of all.

I’ve seen this exact same story so many times in the wild. Many companies (mostly enterprises) still don’t get their mind shifted from the old “this-is-my-application” (monolithic) to a new service oriented “cloud” architecture.

Developers still tend to think about it like the SOA approach they learned in a training (or at university) many years ago… but just inside their own world. So at the end, they often come up with a largely decoupled monolith, that still heavily depends on that one database or a “special” system configuration to make that application work.