Skip to content

Latest commit

 

History

History
202 lines (123 loc) · 5.31 KB

scheduling-chunk-work.md

File metadata and controls

202 lines (123 loc) · 5.31 KB

Scheduling Exercise: Split Template Work

We learned about how we can use scheduling techniques in order to split up hard work in smaller pieces. Let's go ahead and split a piece of work into a new chunk!

This exercise is about getting to know how to analyze the work executed by our application. You will use the dev tools Performance Tab in order to search for long tasks and measure the outcome of your applied changes. By using the directives provided by the @rx-angular/template package, you will have an easy time splicing up the rendering work of your application.

1. Improve AppShell

1.1: Analyze the bootstrap phase

Go ahead and do an analysis of the bootstrap performance of the application.

Serve the movies app and open your browser on the served host:port.

ng serve

# or

npm run start

Also open the Performance Tab of the devtools.

Show Help

open-perfomance-tab

Now run Start profiling and reload page (Ctrl + Shift + E) and inspect the recording.

Show Help

start-profiling-and-reload

You should notice a huge long task in the beginning of the bootstrap phase, connected to AppShellComponent

Show Help

long-task-bootstrap

This looks awful! Let's try to improve the bootstrap time (TBT (Total Blocking Time)) of our application by reducing the work of the initial chunk of work.

1.2: Introduce rxLet

We can do so by literally just adding a simple structural directive to the app-shell.component.html.

Introduce the rxLet directive on the ui-side-drawer element with an empty [] as input.

Show Help
<!-- app-shell.component.html -->

<ui-side-drawer
  [opened]="sideDrawerOpen"
  (openedChange)="sideDrawerOpen = $event"
  *rxLet="[]"
>
</ui-side-drawer>

<!-- other template -->

After applying the changes, run Start profiling and reload page (Ctrl + Shift + E) again and inspect the new recording.

Search for a task named performWorkUntilDeadline which now should include parts of the AppShellComponents work.

You should also notice the reduced workload on the first long task you've detected earlier.

Show Result

app-shell-chunk

1.3: Bonus: move more work

If you like you can also just create an empty ng-container around the whole template of the app-shell.component.html. This will result in a bigger chunk moved from the bootstrap phase of the application. Make sure to measure the outcome!

Show Help
<!-- app-shell.component.html -->
<ng-container *rxLet="[]">

  <ui-side-drawer
    [opened]="sideDrawerOpen"
    (openedChange)="sideDrawerOpen = $event"
  >
  </ui-side-drawer>
  
  <!-- other template -->
  
</ng-container>

Great job!! You have successfully detected a long task and reduced its workload by splicing up the work. Btw. you've also improved the bootstrap time of your application. Love it :-)

Let's level up a bit and apply more improvements!

2. Chunked List Rendering

Open the dev tools again and do a new performance recording. You don't need to run Start profiling and reload page this time, it is sufficient to simply start a recording and navigate around the application.

After doing one of the approaches before, search for the task where ngFor creates the nodes for the movie-cards in the flamecharts.

It is probably connected to an XHR Load event and causes lots of refreshView calls.

Show Help

ng-for-chunk

With your knowledge about scheduling the identified pattern should already trigger some thoughts about what we want to do with this one here :). You should notice that there is a lot of repeated work done in a single task which could easily be split up.

Let's do so by switching from @for to *rxFor in the movie-list.component.html template.

Show Help
<!--movie-list.component.html-->

<div class="movie-list">
  <movie-card
    [movie]="movie"
    *rxFor="let movie of movies; trackBy: 'id'">

  </movie-card>
</div>

The rxFor directive should make sure to render list items by keeping the frame budget of 60 fps in mind.

Do another performance recording of the movie-list and search for the chunked list rendering pattern.

Depending on your hardware, you maybe need to turn on CPU throttling

CPU Throttling

activate-cpu-throttle

Rx For Chunks

rx-for-chunking

Well done! You have successfully mastered the single-thread :-)

3. Bonus: Introduce rxFor to genre list

Just as you did before, replace ngFor with the rxFor directive in the app-shell.component.html template at the place where the genre$ data is rendered.

Make sure to measure the result!