Key words: Angular performance optimization load JS file

1. The background

Recently, we found a performance problem with an Angular project that was slow to load and slow to run. As a follower of extreme performance, it is necessary to find problems and optimize performance. There are a number of problems, one of the typical problems is too many JS scripts directly external to index.html. You can imagine the source code looks like this.

<! doctypehtml>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Demo</title>
</head>
<body>
  <app-root></app-root>
  <script src="1.js" defer></script>
  <script src="2.js" defer></script>
  <script src="3.js" defer></script>
  <script src="4.js" defer></script>
  <script src="5.js" defer></script>
  <script src="6.js" defer></script>
  <script src="7.js" defer></script>
  <script src="8.js" defer></script>
  <script src="9.js" defer></script>
  <script src="10.js" defer></script>
</body>
</html>
Copy the code

PS: For those who can’t tell the difference between defer and async, please click on this blog to learn the difference between defer and async

  • From the perspective of the user scenario, many JS scripts are loaded but not actually used. This is equivalent to wasting page loading performance and page running memory
  • There are too many scripts loaded, especially defer. Once one of the middle scripts is blocked, all subsequent scripts will be affected
  • Loading scripts without using Angular’s scripts capability can result in uncompressed JS
  • . .

2. Optimize

2.1 Use webpack import functions

this.zone.run(() = > { 
     if (this.platform.IOS) {     // Load fastclick.js when the user device is aN iPhone
        import('.. /assets/js/fastclick.js').then(FastClick= > {  
            FastClick.attach(document.body); })}if (['local'].indexOf(environment.env) ! = = -1) { // VConsole is displayed when the environment matches
         import('.. /assets/js/vconsole.min.js').then(VConsole= > {   
           newVConsole.default(); })}})Copy the code

2.2 Using Script Tags

Encapsulation ScriptUtil

import {Observable, of, Subject} from 'rxjs';

export class ScriptUtil {
  private static CACHED_SCRIPTS = [];

  static asyncLoad(src: string): Observable<void> {
    if (ScriptLoadUtil.hasBeenLoaded(src)) {
      return of(null);
    }
    const result$ = new Subject<void> ();const scriptEl = document.createElement('script');
    scriptEl.src = src;
    document.body.appendChild(scriptEl);
    scriptEl.onload = () = > {
      ScriptLoadUtil.CACHED_SCRIPTS.push(src);
      result$.next();
    };
    return result$.asObservable();
  }

  static hasBeenLoaded(src: string) :boolean {
    returnScriptLoadUtil.CACHED_SCRIPTS.indexOf(src) ! = = -1; }}` `'** Loads JS script **'` `TypeScript
ScriptLoadUtil.load('assets/ckeditor/ckeditor.js')
    .subscribe(() = > {  console.log('load js sucess')});
Copy the code

2.3 Use angular.json scripts

Some JAVASCRIPT scripts must be loaded immediately. Instead of writing them directly to index.html, you can configure asynchronous loading of scripts in angular.json

{
    "projects": {"demo": {"architect": {"build": {"scripts":[
                        {  "input": "src/assets/js/browserCheck/browser-version.min.js"."bundleName": "browser"}]}}}}}Copy the code

conclusion

This article focuses on optimizing the loading and use of external JS scripts, not just for Angular, but for all kinds of projects. If you have some better practices, also hope to discuss learning together.