[Tutorial]: Ionic Tutorials (Improving performance using the domController)

in utopian-io •  6 months ago

ionic.jpg
image source
Repository: Ionic Github Repository

Software Requirements:
Visual Studio Code(Or any preferred code editor)

What you will learn:
In this tutorial you would learn to how to

  • Build better animated effects in you ionic application
  • Understand and use the domWrite in you application.

Difficulty: Intermediate

Tutorial
In this tutorial, i would be trying to help you understand what causes a lag in ionic applications when you try anything involving an animated effect.
In Ionic 3, a new function was introduced which is called domWrite. When modifying components live in ionic(In other terms, making animations). You are changing the root elements within your webview and on a device which does not provide much graphic memory for the webview of an application, it is very common to see a laggy effect in your application.
In the last expandable header bar i build, i was dissatisfied with the output on my device because it was extremely laggy and was making my GUI very scrappy. I did some research and found out the reasons for this and found ways to reduce, if not eliminate the lag depending on what device you are running your application on.

So firstly i would try to explain why hybrid applications lag
Reason
A hybrid application will lag whenever you try to recolor(change the color or opacity) of an element and will lag even more when you try to reflow(rescale a component). Ionic found a partial remedy to this which was the domWrite which optimizes how this reflow or recoloring happens and makes the gui flow smoothly. Regardless of this, no matter how much it tries, this will still lag on devices with little rams and processing speed that dont give a lot of graphic memory to the webview in applications.

For example
This is the code for my laggy header bar.
Follow through the code to see the areas i commented on

import { Component, Input, ElementRef, NgZone, Renderer2 } from '@angular/core';

@Component({
  selector: 'expandable',
  templateUrl: 'expandable.html'
})
export class ExpandableComponent {
 
  @Input('scrollArea') scrollArea: any;//This references to the ion content within whatever component you choose to use this custom component in
  @Input('headerHeight') headerHeight: number;//This sets the height you would choose to use
 
  newHeaderHeight: any;//This is a variable for the new header height you would like to give whenever there is a scroll event
 
  constructor(public element: ElementRef, public renderer: Renderer2, public zone: NgZone) {
 
  }
 
  ngOnInit(){
 
    this.renderer.setStyle(this.element.nativeElement, 'height', this.headerHeight + 'px');//This sets the header height at the startup. We aren't using domWrite because this is when the application loads
 
    this.scrollArea.ionScroll.subscribe((ev) => {
      this.resizeHeader(ev);
      this.scrollArea.resize();
    });
 
  }
 
  resizeHeader(ev){
 
    ev.domWrite(() => {
 
       this.newHeaderHeight = this.headerHeight - ev.scrollTop;//Whenever there is a scroll event, the header height changes.
 
      if(this.newHeaderHeight < 0){
        this.newHeaderHeight = 0;
      }  
 
      this.renderer.setStyle(this.element.nativeElement, 'height', this.newHeaderHeight + 'px');
      
 
    });
 
  }
}

Why does this lag? and how can we change it
The reason for the lag can be summarized in this line of code

this.newHeaderHeight = this.headerHeight - ev.scrollTop;

Scroll events give of responses on the slightest motion within the scroll area. Meaning that a simple flick may give up to 10 or more scroll event. So talk more of a scroll event that goes in opposite areas rapidly. For a browser on a laptop. This would be smooth because the ram can take way more and even on devices with rams more than 4gigg and nice processors we will not see a lag but what of other devices. The browser simply cant compute this fast enough and render the template in enough time.

How to fix it
As much as possible create less logic involving your view. In other words look for landmarks, look for events that are triggered at certain points and use if block of code to change the view whenever these events are triggered. Below is a fix to this header bar.

import { Component, Input, ElementRef, NgZone, Renderer2 } from '@angular/core';

@Component({
  selector: 'expandable',
  templateUrl: 'expandable.html'
})
export class ExpandableComponent {
 
  @Input('scrollArea') scrollArea: any;
  @Input('headerHeight') headerHeight: number;
 
  newHeaderHeight: any;
 
  constructor(public element: ElementRef, public renderer: Renderer2, public zone: NgZone) {
 
  }
 
  ngOnInit(){
 
    this.renderer.setStyle(this.element.nativeElement, 'height', this.headerHeight + 'px');
 
    this.scrollArea.ionScroll.subscribe((ev) => {
      this.resizeHeader(ev);
      this.scrollArea.resize();
    });
 
  }
 
  resizeHeader(ev){
 
    ev.domWrite(() => {
 
      // this.newHeaderHeight = this.headerHeight - ev.scrollTop;
 
      if(ev.deltaY > 0){//Use Delta events rather than scroll events to detect the direction of scroll
        this.newHeaderHeight -= 20;
      }
      if(ev.deltaY > 20){
        this.newHeaderHeight = 0
      }
      if(ev.deltaY < 0){
        this.newHeaderHeight = (this.headerHeight/2);
      }
      if(ev.deltaY < -20){
        this.newHeaderHeight = this.headerHeight;
      }
      if(this.newHeaderHeight < 0){
        this.newHeaderHeight = 0;
      }  
 
      this.renderer.setStyle(this.element.nativeElement, 'height', this.newHeaderHeight + 'px');
 
    });
 
  }
}

In this fix, we are using deltaY which is an event that simply detects changes in the direction of the scroll event and not the exact position which the page is being scrolled to. This in turn would make the bar retract regardless of where the scroll position is but you could still use a combination of both the scroll position and the direction of change if you're a bit more ambitious like this

if(deltaY > 0 && scrollTop > 180){
    this.newHeaderheight = 0
}

This is a gif but show how the header is actually working in realtime
Webp.net-gifmaker.gif

This would create a way better animated effect without any lag.
If you're lost on how i created this animated header. Here is a detailed seperate tutorial by joshMorony. Which should get you back on track.

You could see the code for this in my Github Page

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Thank you for your contribution @yalzeee.
We suggest the following points below:

  • Comments are essential in the code to facilitate the best interpretation of what you are developing. We suggest you put more comments in your code.

  • Put more images in your tutorial, so it breaks your extensive text a bit and shows what you are developing.

Thank you for your work in making this contribution. We are waiting for more tutorials.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

·

Thank you for your review, @portugalcoin! Keep up the good work!

Hello! Your post has been resteemed and upvoted by @ilovecoding because we love coding! Keep up good work! Consider upvoting this comment to support the @ilovecoding and increase your future rewards! ^_^ Steem On!

Reply !stop to disable the comment. Thanks!

Hello! I find your post valuable for the wafrica community! Thanks for the great post! We encourage and support quality contents and projects from the West African region.
Do you have a suggestion, concern or want to appear as a guest author on WAfrica, join our discord server and discuss with a member of our curation team.
Don't forget to join us every Sunday by 20:30GMT for our Sunday WAFRO party on our discord channel. Thank you.

Hi @yalzeee!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Hey, @yalzeee!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!