React Js Redux

This is basic my note for learning and understand what exact Redux doing

If you had play with Flux, then yes you had pretty much get 80% concept

If you don’t , like me has no clue about Flux , then we could try to learn the concepts step by step:

Concept:

According to the Auther: Dan Abramov

Redux is a library to range states more easier, less API, but more predictable behaviours, it could be practice logging, hot reloading, time travel and universal application, recording and repeating

If you knew about Flux, it was came from the problem of showing message tab box from Facebook messenger by user read or not read, and mean time show different states in the same time, the core is fix this feature problem by Virtual DOM to make user better experience:
1. Improve data consistancy

2. Point root of a bug

3. More meaning unit test

so this was birth of dispatch and action part:

From view to trigger update data even, action send ddata to dispatcher, and dispatcher send payload to all stores, final View ask Store to get state

Point of Redux:

Make state changes more predictable

Reduc 3 pricipales:
1. Single source of truth ( the only data source from ):
states will all wrapped in one store, where has to dispatch the actions

2. State is read only
you could only change state by action

and action is dispatch by store:

3.  Changes are made with pure functions

pure functions == reducer,  action will send the request to reducer, reducer will received older state and return new state, keep reducer is pure and return value to be predictable, follow has 2 reducer, one is for filter and the other is for todos reducer, then use reducer to create store :

function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}

import { combineReducers, createStore } from 'redux'
let reducer = combineReducers({ visibilityFilter, todos })
let store = createStore(reducer)

This part is still abstract? follow has the concept diagram:

Process of Redux:
Look upper  diagram, as you could see,  view == components, as user has some operation to trigger action from view ( components) , store.dispatch need to change event content, pass to store for reducer to return next state, state tree has update, trigger view re-render

Redux ==> compositions of store, actions , reducer

Some points in Redux:

As you look some sample code upper in Reducer , do you notice that all the function return directly argument value ? which means in Redux it only accept Pure function, so if your function has re-calculate method like Math.random() , date now() or mapping etc it will not be allowed cause it has to stay simple, less side-effect ( well, that’s why it is called reducer)

Reducer that calculates the next state tree based on the previous state tree and the action being dispatched :

this is important because once you understand this is the key procedure in Reducer then it will make you easily to start to code

Learn more? this link is good to learn the basic concept by photo application
or by the Auther which has videos to show more

Docker: Installation

Installation

First you had to decide which version you need to install, like Windows or Mac

Here I will install Mac version:

1 go to docker.com and get the Stable version: https://docs.docker.com/docker-for-mac/install/#download-docker-for-mac

 

2. once download, go to Application, and click docker.dmg, then you will be start running installation

3. Once you see your docker has show on the right top menu bar, yes, that’s how easy it is, you had installed it already

 

4 open terminal, type

$docker –version

 

Once you see the version has been record, yes you are done

5 then go to top right menu Docker, right click to search Preference, here you could have further setting like start Docker as you log in or File Sharing path etc, but with Mac basically you could just leave as default setting

 

6 (Optional but recommend ) Install Kitematic, which is GUI interface allowed you easy to use Docker without typing lots command code

 

login your account docker hub

 

Then you all set, wow you have great interface to get any Docker image, container

 

So you are all done, you could use those command to check your images or containers:

$ docker images

$ docker ps -a

7 Create your first image

go to Kitematic, choice one of your image, here I tried hello-world-nginx

once created, Kitematic will pop to runing page, click web preview part

voila, how easy it is you had create your first page in your localhost:

8 Modified your first container page

stick on Kitematic, under volumes block , click right it will show the file path to running this image:

 

modified your index.html file

<p>Ok, so try out if it is working</p>

Once your process, Docker will stop running, so you just had to restart

then go to the browser check, it is had modified

 

Then type:

$ docker images

REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE

kitematic/hello-world-nginx   latest              03b4557ad7b9        2 years ago         7.91MB

You will see you had a Repository hello-world-nginx

Next, play how to install nginx web server

 

 

 

Docker introduction

As sometime we need to run the project over the Virtual Machines (server), there’s has VMware, Microsoft or any other cloud VM, for VM introduction you could see more details here, or about what use virtuabox 

And this is our founder Alex who build the dev env for php environment, you could download here and install to play with

So Docker == VM ? yes you could say so, but ! Docker === VM

Why? compare other VM container, Docker could be:

A adapte any environment, either in Windows or MAC ( this is the key point, how many developers sacrificed huge time to play around with !!!), or in cloud, dedicated or any virtue server, so it’s easy to move your project from dedicated to cloud

B Faster deployed, developer could work under the container and it is very faster and easy to deployer your project

C Easy Management, compare traditional vm, for updating job it will take lots of time and configuration, for Docker it become more easier

 

Here is funny image but quick for you to get understand :

Conception of Docker

  • Image:  like vm’s Guest OS or any env like ubuntu ( which includ Apache or any other applications), image could build Docker container

image is R\O, read only

  • Container:  create by image, each image could create serveral different containers , container could be run, start, stop and delete, when container running it will build by container layer and with R\W mode, you could take container as simple Linux env

  • Registry: it is like github, stock images as each repositories, so you could install image from pull or you could make your own image to push

 

next Installation

Cliche but important: optimise your website

Bits busy for those couple days, specially for optimise the E-commerce site which had order row over 450,000 and 6 years customers orders, it is time to optimise the site (opps, would it be too late?)

So today I will try to go through how to optimise a website(E-commerce)

For performance part, I think you guys pretty much know that you could go through follow:
1. Reduced image size, by base64, spirit Image or compressing image

2. Try minify the css, js part, if your site css using Less, Scss, Sass then you could ignore minify part, for Js it will more
be complex, try minify js, or if you write TypeScript or Babel then awesome you could ignore this part

3. Use Cachable for your page files, and the catch html content by desktop or mobile version, there’s some way to do those

4. using optimization rules in .htaccess file
The .htaccess file handles the way your web servers process your site with a lot of rules to improve your site speed
and with ETag, Expires headers, AddOutputFilterByType DEFLATE etc, follow is the simple:

########## Begin - ETag Optimization
## This rule will create an ETag for files based only on the modification
## timestamp and their size. 
## Note: It may cause problems on your server and you may need to remove it
FileETag MTime Size
# AddOutputFilterByType is now deprecated by Apache. Use mod_filter in the future.
AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript
# Enable expiration control
ExpiresActive On
# Default expiration: 1 hour after request
ExpiresDefault "now plus 1 hour"
# CSS and JS expiration: 1 week after request
ExpiresByType text/css "now plus 1 week"
ExpiresByType application/javascript "now plus 1 week"
ExpiresByType application/x-javascript "now plus 1 week"
 
# Image files expiration: 1 month after request
ExpiresByType image/bmp "now plus 1 month"
ExpiresByType image/gif "now plus 1 month"
ExpiresByType image/jpeg "now plus 1 month"
ExpiresByType image/jp2 "now plus 1 month"
ExpiresByType image/pipeg "now plus 1 month"
ExpiresByType image/png "now plus 1 month"
ExpiresByType image/svg+xml "now plus 1 month"
ExpiresByType image/tiff "now plus 1 month"
ExpiresByType image/vnd.microsoft.icon "now plus 1 month"
ExpiresByType image/x-icon "now plus 1 month"
ExpiresByType image/ico "now plus 1 month"
ExpiresByType image/icon "now plus 1 month"
ExpiresByType text/ico "now plus 1 month"
ExpiresByType application/ico "now plus 1 month"
ExpiresByType image/vnd.wap.wbmp "now plus 1 month"
ExpiresByType application/vnd.wap.wbxml "now plus 1 month"
 
ExpiresByType application/smil "now plus 1 month"
# Audio files expiration: 1 month after request
ExpiresByType audio/basic "now plus 1 month"
ExpiresByType audio/mid "now plus 1 month"
ExpiresByType audio/midi "now plus 1 month"
ExpiresByType audio/mpeg "now plus 1 month"
ExpiresByType audio/x-aiff "now plus 1 month"
ExpiresByType audio/x-mpegurl "now plus 1 month"
ExpiresByType audio/x-pn-realaudio "now plus 1 month"
ExpiresByType audio/x-wav "now plus 1 month"
 
# Movie files expiration: 1 month after request
ExpiresByType application/x-shockwave-flash "now plus 1 month"
ExpiresByType x-world/x-vrml "now plus 1 month"
ExpiresByType video/x-msvideo "now plus 1 month"
ExpiresByType video/mpeg "now plus 1 month"
ExpiresByType video/mp4 "now plus 1 month"
ExpiresByType video/quicktime "now plus 1 month"
ExpiresByType video/x-la-asf "now plus 1 month"
ExpiresByType video/x-ms-asf "now plus 1 month"

5. use CDN to load media:
CDN stands for content delivery network, it is an interconnected system of cache servers that use geographical proximity as a criteria for delivering Web content.
CDN is especially well suited for delivering media such as: video, audio, images, etc. So instead of loading those media from server, it loads from CDN, it’s more efficient and reliable.
For CDN, you could apply from your host server or of you have CMS website there’s nice plugin to help you quickly

6. choosing good web hosting

There’s lot choice and here has list you could take reference, for my cas I’m using Dedicated server CentOS Linux which has memory 63 Go, and I use Plesk allow setting your customise php configuration and that could be more flexible then web hosting

Also if you need to reduced Mysql resource running in memory rather than disk (which will run query faster), if you have dedicated serveur then this is the part you could do it

For request query part, this will be more complicated, you had to deal with your database Optimizing Queries with EXPLAIN or Indexes

As for myself understanding, Indexes is just like a book index, that tell you where you could find the chapter or some point articles, and in your database schema, there should be have some part point to help filtre more faster

For example if you do have more then 100,000 rows in table called #orders_list , it will be get very slow to request query to select (read) one of the order list, so you need index to separate those data structure of your table and help query to find out the right information more faster

sample to create index

As you need to find the table called user which has Name, age and address columns, there’s 2000 rows

and you are write a query to find a user name ‘Tess’:

SELECT * FROM User 
WHERE Name = 'Tess'

As there’s 2000 row, the query had to look at every single row and it will take long time, so now you could create a index to get faster:

CREATE INDEX name_index
ON User (Name)

So instead of search all columns Name, age and address, this will allow query search of User name by sorted alphabetically, in this case it will be more faster to get result

7 repaire or optimise your table database

If you use mysql, you could easily to optimise your table database just after selecting the table and click to choose optimise your table:

8. Try to test your web site through some site

https://tools.pingdom.com/

https://smallseotools.com/website-page-size-checker/

and there’s so many way to reduced your website size and get your performance better, it might take lots of work but it will really worth it cause every second as count by user

 

 

 

Symfony: service.yaml

In symfony package, you could find this file under : config directory

This file job is to figure out all of the services that should be in the container when symfony load

Services comes from external bundles, and also inject your own custom service,

Let’s look at service.yaml file:

services:
    # default configuration for services in *this* file
    _defaults:
        autowire: true      # Automatically injects dependencies in your services.
        autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
        public: false       # Allows optimizing the container by removing unused services; this also means
                            # fetching services directly from the container via $container->get() won't work.
                            # The best practice is to be explicit about your dependencies anyway.

the point here is autowire: true, which means that any services registered in this file should have the autowiring behavior turned on

And look the key point follow:

App\:
    resource: '../src/*'
    exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'

App\Controller\:
    resource: '../src/Controller'
    tags: ['controller.service_arguments']

look at App: resource, that’s means:
Make all classes inside src/ available as services in the container.

that’s why you could put any class inside the src and make it called by symfony

to verify, go to terminal:

$ php bin/console debug:autowiring

as you could see what we had add the controller class before, it has put in autowiring lists

and don’t worry, for better performance:

Services are only Instantiated Once

App\:
    resource: '../src/*'
    exclude: '../src/{Entity,Migrations,Tests,Kernel.php}'

exclude key: if you know that some classes don’t need to be in the container, you can exclude them for a small performance boost in the dev environment only.

And what happend if you need to configure one service ?

Let’s do it:

Step 1 found out your services Id

Services Ids = Class Name

go to your terminal:
$ php bin/console debug:container –show-private

you could find your service Id, for example, for markdown:

App\Service\MarkdownHelper App\Service\MarkdownHelper

Step 2 inject monolog logger service
and in order to inject this sevice and make it autowiring by service.yaml

track back $ php bin/console debug:autowiring

Psr\Log\LoggerInterface
alias to monolog.logger

go to src/ Service/ MarkdownHelper.php

add use Psr\Log\LoggerInterface;

and inject argument LoggerInterface

public function __construct(AdapterInterface $cache, MarkdownInterface $markdown, LoggerInterface $logger)
{
    $this->cache = $cache;
    $this->markdown = $markdown;
    $this->logger = $logger;
}

add this logger info in parse function :

if (stripos($source, 'Spicy') !== false) {
    $this->logger->info('They are talking about spicy again!');
}

Step 3 find your service Information

go to terminal

$ ./bin/console debug:container monolog.logger

here you find Service ID monolog.logger

Step 4 Creating a new Logger Channel

Go to config/ packages, add monolog.yaml:

monolog:
    channels: ['markdown']

once add, go to terminal to clean catch:

$ ./bin/console cache:clear

$ ./bin/console debug:container log

you could see:
[44] monolog.logger.markdown

then this is said you had a new logger service – monolog.logger.markdown!

Step 5 Fetching this non-standard service to service.yaml

go to service.yaml file

add follow

# setup special, global autowiring rules
bind:
    $markdownLogger: '@monolog.logger.markdown'

 

Step 5 Logger object to your controller

go to src/Service/MarkdownHelper.php

public function __construct(AdapterInterface $cache, MarkdownInterface $markdown, LoggerInterface $markdownLogger)
{
    $this->cache = $cache;
    $this->markdown = $markdown;
    $this->logger = $markdownLogger;
}

notice you made changed LoggerInterface $logger to LoggerInterface $markdownLogger

because you had add bind logger object in your service.yaml

because we added it to _defaults, it applies to all our services.

github commit here

*** Thanks to bind, we can define what values are passed to specific argument names. But, we can go further and control what value should be passed for a specific type hint ***