22 Angular Development Board. Part 2

https://medium.freecodecamp.org/best-practices-for-a-clean-and-performant-angular-application-288e7b39eb6f
  • Transfer
Today we publish the second part of the translation of the article, which contains a set of recommendations for Angular-developers. In the previous part 11 councils were presented, in this we will look at the same number.



1. Small components suitable for reuse


Find fragments in the components that can be reused and create new components based on them. Make the components as stupid as possible, as this will allow them to be used in more scenarios. A “stupid” component is one that does not contain any specific logic, whose work depends solely on the input data provided to it.

When working with components, you should adhere to the following general rule: the deepest embedded component in the component tree should also be the most “stupid”.

▍ Explanations


Reuse of components reduces duplication of code, which simplifies project support and changes to it.

“Stupid” components are simpler than others, so it’s less likely that there will be errors in them. Using such components makes the developer think better about the open API of the component and helps to solve problems.

2. About tasks solved by components


Whenever possible, avoid components of logic different from that used to visualize data.

▍ Explanations


Components are created as a means to present information and to control how interfaces should work. Any business logic should be extracted from components and placed, when possible, in separate methods or services, thus separating business logic from information presentation logic.

Business logic, when presented as separate services, is usually easier to unit test. With this approach, it can be reused by different components that need the same features.

3. About big methods


If the code of the method is very long, it usually indicates that such a module solves too many problems. Such a method, as an independent entity, probably solves only one task, but inside it there can be a code that performs several different operations. Such code can be arranged in the form of separate methods, each of which, again, should solve any one problem, after which these methods should be used instead of the corresponding code fragments in the original method.

▍ Explanations


Long code methods are hard to read, understand, and maintain. In addition, such methods are error prone, since changing one thing can affect many other mechanisms of the method. Long code means complication of refactoring, and this operation is very important in any application.

In this regard, we can mention such an indicator as the cyclomatic complexity of the program . There are TSLint rules for identifying cyclomatic complexity that can be used in a project in order to avoid errors that may appear in too complex code. With their help, you can evaluate the quality of the code and prevent possible problems with its support.

4. DRY principle


DRY (Do not Repeat Yorself, do not repeat) is a principle, following which you should strive to ensure that in different places of the project there are no copies of the same code fragments. Such code fragments should be arranged in the form of independent entities, methods, for example, and use their calls where previously repeated code was used.

▍ Explanations


If the same code is used in different places of the application, this leads to the fact that if you need to make changes to this code, it will have to be done in many places. As a result, the program will be harder to maintain, it will be prone to errors, for example, due to the fact that not all fragments of the same code have been correctly edited. It also increases the time needed to make changes to the code and to test it.

If you are confronted with something similar, issue the repeating code as an independent entity and use it instead of repeating fragments. This will lead to the fact that in order to make changes, changes will have to be made only in one place, and during testing you will need to test only one piece of code, and not a few. In addition, the less duplicate code in an application, the faster it will be loaded by users.

5. Caching mechanisms


When executing calls to various APIs, it can be noted that the responses from some of them almost never change. In such cases, you can add data caching tools to the program and store in cache what similar APIs return. When executing the next query, you can access the cache, and if it already has what you need, you can use this data, and if you don’t need it, you can execute the current query and place a response to it in the cache.

If the data obtained from certain APIs change with a certain periodicity, you can cache them for a certain time. As a result, by performing a request to such an API, it will be possible to decide where to get the necessary data.

▍ Explanations


Having a caching mechanism allows you to avoid making unnecessary requests to the API. If applications in the API are executed only when absolutely necessary, and the data that the application has already received, is not requested again, the performance of the solution improves, in particular, due to the fact that it does not have to constantly wait for responses from certain network services. This approach also allows you to save traffic, since the same data is not loaded again and again.

6. Logic in patterns


If your templates have at least some logic, even a simple expression &&, this logic should be extracted and placed in the appropriate component.

▍ Explanations


If there is logic in the template, this means that such a template cannot be subjected to unit testing, and thus the likelihood of errors increases when the template code changes.

▍To


// шаблон
<p *ngIf="role==='developer'"> Status: Developer </p>
// компонентpublicngOnInit (): void {
    this.role = 'developer';
}

▍After


// template
<p * ngIf = "showDeveloperStatus"> Status: Developer
// компонентpublicngOnInit (): void {
    this.role = 'developer';
    this.showDeveloperStatus = true;
}

7. Work with strings


If you have a string type variable that can have values ​​from a limited set, then instead of declaring it as a regular string, specify when you declare it a list of possible values.

▍ Explanations


The thoughtful description of the type of a variable allows to simplify the detection and elimination of errors, since with this approach they are revealed at the stage of compiling the program and not during the execution of the code.

▍To


private myStringValue: string;
if (itShouldHaveFirstValue) {
   myStringValue = 'First';
} else {
   myStringValue = 'Second'
}

▍After


private myStringValue: 'First' | 'Second';
if (itShouldHaveFirstValue) {
   myStringValue = 'First';
} else {
   myStringValue = 'Other'
}
// тут появится следующая ошибка
Type'"Other"'isnot assignable totype'"First" | "Second"'
(property) AppComponent.myValue: "First" | "Second"

8. About application state management


Consider using @ ngrx / store to manage the state of your application and @ ngrx / effects to implement side effects. State changes are described by actions and performed by pure functions called reducers.

▍ Explanations


@ ngrx / store isolates logic related to the state of the application in one place and makes it uniform throughout the project. Here, in addition, there is a memoization mechanism that operates when working with the repository, which improves application performance. The @ ngrx / store mechanism, combined with Angular's change detection strategy, leads to faster applications.

9. About the immunity of the application state


When using @ ngrx / store, consider using the ngrx-store-freeze library to make the state of the application immune. This library prevents state mutations by throwing exceptions. This avoids accidental changes in application state that lead to unpredictable consequences.

▍ Explanations


Changing the state of the application in the components leads to the fact that the behavior of the application varies depending on the order of loading components. This violates the mental model of the template redux. As a result, changes can be overridden if the state of the storage changes and the subsequent work with it is carried out using the new state. Here we apply the principle of shared responsibility, according to which the components are at the presentation level and they should not be aware of how to change the state of the application.

10. Application Testing Tools


Use specialized tools to test applications. Among them are Jest and Karma .

▍ Explanations


Jest is a unit testing framework developed by Facebook. It supports mechanisms for parallel execution of tests, which speeds up the work. Due to the fact that he is able to take into account changes in the code base, in the next test session only tests related to the modified code are performed. This improves the ability to analyze test results. In addition, Jest provides code coverage metrics with tests and is supported by the VS Code editor and IDE WebStorm.

The Karma test run tool is developed by the AngularJS team. He needs a real browser and DOM to run tests. Karma allows you to perform tests in various browsers. Jest, in turn, does not need, for example, the Chrome browser without a user interface or phantom.js, since this framework requires only the Node.js platform.

11. Server rendering


If you are not yet using Angular Universal technology , now is the time to try it. It allows you to organize server-side rendering of Angular-applications. As a result, static, pre-rendered HTML pages are transmitted to the user. This makes applications incredibly fast, as their content appears in browsers almost instantly due to the fact that the browser does not have to download and parse the JS-bundles and waste time on ensuring the work of the Angular mechanisms.

In addition, Angular-applications, rendered on the server, have advantages over conventional applications in terms of CEO. Angular Universal creates static pages, and this makes it easier for search engines to index these pages, since they don’t have to execute JavaScript code to generate pages.

▍ Explanations


By using Angular Universal, you can dramatically improve application performance. We recently updated our application to add server rendering capabilities. This led to a reduction in site load time from a few seconds to tens of milliseconds.

In addition, thanks to this approach, the pages are correctly displayed in the preview areas of the content used in social networks. The time of the first meaningful display of the page (First Meaningful Paint) is very short, which saves users from unnecessary waiting.

Results


Application development is the way in which the programmer constantly finds opportunities to improve what he creates. Going along this path, you can use the tips on optimizing Angular applications listed here. We are confident that their consistent use will benefit any development team, and users will like what happens as a result, because, from their point of view, this will lead to the fact that they will work with more stable and productive applications.

Dear readers! If you can share with the Angular-developer community useful tips for improving applications - please do so.


Also popular now: