[Angular] USING ZONES IN ANGULAR FOR BETTER PERFORMANCE

Link to the artical.

Zone detects any async opreations. Once an async oprations happens in Angular, Zone will notify change detection to kick in.

Images we have 5000 svg box displaying on the screen.

And each svg elements and three event listener on it:

@Component({
  ...
  template: `
    <svg (mousedown)="mouseDown($event)"
         (mouseup)="mouseUp($event)"
         (mousemove)="mouseMove($event)">

      <svg:g box *ngFor="let box of boxes" [box]="box">
      </svg:g>

    </svg>
  `
})
class AppComponent {
  ...
}

Three (3) event handlers are bound to the outer SVG element. When any of these events fire and their handlers have been executed then change detection is performed. In fact, this means that Angular will run change detection, even when we just move the mouse over the boxes without actually dragging a single box!

Since ‘mousemove‘ is the event cause the change detection which is not necessary. So we simple remove it from the HTML:

<svg (mousedown)="mouseDown($event)"
      (mouseup)="mouseUp($event)">

  <svg:g box *ngFor="let box of boxes" [box]="box">
  </svg:g>

</svg>

So now we need a way to attach ‘mousemove‘ event for only the selected svg box. We can do this inside ‘mousedown‘ event:

  constructor(private zone: NgZone) {}

  mouseDown(event) {
    ...
    this.element = event.target;

    this.zone.runOutsideAngular(() => {
      window.document.addEventListener(‘mousemove‘, this.mouseMove.bind(this));
    });
  }

We inject NgZone and call runOutsideAngular() inside our mouseDown() event handler, in which we attach an event handler for the mousemove event. This ensures that the mousemove event handler is really only attached to the document when a box is being selected.

  mouseMove(event) {
    event.preventDefault();
    this.element.setAttribute(‘x‘, event.clientX + this.clientX + ‘px‘);
    this.element.setAttribute(‘y‘, event.clientX + this.clientY + ‘px‘);
  }

In addition, we save a reference to the underlying DOM element of the clicked box so we can update its x and y attributes in the mouseMove() method. We’re working with the DOM element instead of a box object with bindings for x and y, because bindings won’t be change detected since we’re running the code outside Angular’s Zone. In other words, we do update the DOM, so we can see the box is moving, but we aren’t actually updating the box model (yet).

In the next step, we want to make sure that, whenever we release a box (mouseUp), we update the box model, plus, we want to perform change detection so that the model is in sync with the view again. The cool thing about NgZone is not only that it allows us to run code outside Angular’s Zone, it also comes with APIs to run code inside the Angular Zone, which ultimately will cause Angular to perform change detection again. All we have to do is to call NgZone.run() and give it the code that should be executed.

Here’s the our updated mouseUp() event handler:

@Component(...)
export class AppComponent {
  ...
  mouseUp(event) {
    // Run this code inside Angular‘s Zone and perform change detection
    this.zone.run(() => {
      this.updateBox(this.currentId, event.clientX + this.offsetX, event.clientY + this.offsetY);
      this.currentId = null;
    });

    window.document.removeEventListener(‘mousemove‘, this.mouseMove);
  }
}

Also notice that we’re removing the event listener for the mousemove event on every mouseUp. Otherwise, the event handler would still be executed on every mouse move. In other words, the box would keep moving even after the finger was lifted, essentially taking the drop part out of drag and drop. In addition to that, we would pile up event handlers, which could not only cause weird side effects but also blows up our runtime memory.

Notice:

However, we shouldn’t forget that this solution also comes with a couple (probably fixable) downsides. For example, we’re relying on DOM APIs and the global window object, which is something we should always try to avoid. If we wanted to use this code with on the server-side then direct access of the window variable would be problematic. We will discus these server-side specific issues in a future article. For the sake of this demo, this isn’t a big deal though.

时间: 2024-10-12 14:27:11

[Angular] USING ZONES IN ANGULAR FOR BETTER PERFORMANCE的相关文章

Angular 1.0演变Angular 2.0的简单优势列举

首先,Angular最核心的4大特性分别是: 1.模块化 2.MVC 3.双向数据绑定 4.指令 Angular 1.0演变Angular 2.0的简单优势列举: 1.性能限制上的优化 说明:随着时间的推移,各种特性被加入进去以适应不同场景下的应用开发,在最初的架构受到了限制,而Angular 2.0很好的解决了这些问题. 2.仿照WEB后端的结构模式来编写前端 说明:支持模块.类.lambda表达式. generator等新的特性 3.支持移动端开发 说明:Angular1.x没有针对移动 应

精通 Angular JS 第一天——Angular 之禅

简介 Angular JS是采用JavaScript语言编写的客户端MVC框架,它为业界带了重大的变化,包括对模板化的创新实现,以及数据的双向绑定,这些特性使得它强大而易用.它可以用来帮助开发者编写单页面应用,尤其适合编写有大量CRUD操作的,具有Ajax风格的富客户端应用.大多数开发者认为,与其它框架相比,AngularJS明显缩减了项目所需的代码量. 2012年6月,Angular JS正式发布1.0版,在各种客户端MVC框架中,属于后起之秀.AngularJS主页(http://www.a

Angular05 angular架构、搭建angular开发环境、组件必备三要素、angular启动过程

1 angular架构 1.1 组件:是angular应用的基本构建模块,可以理解为一段带有业务逻辑和数据的HTML 1.2 服务:用来封装可重用的业务逻辑 1.3 指令:允许你想HTML元素添加自定义功能 1.4 模块:将应用中的不同部分组织成一个angular框架可以理解的单元 1.5 组件+服务+指令 = 模块 组件+服务+指令 是用来完成业务功能的:模块 是用来打包和分发的 2 开发环境搭建 2.1 安装node.js 很简单,百度即可 安装完后在我们的命令窗口中就可以使用 npm 命令

[Angular 2] ROUTING IN ANGULAR 2 REVISITED

Let's say we have a list of contacts, click each contact, we can render a new route to get the detail. Define the routers: //contact-list.router.ts import {ContactListComponent} from "./contact-list-component.component"; import {ContactDetailCom

[Angular 2] Create Angular 2 Porject with Angular CLI

Install: npm i -g angular-cli Create a project: ng new hello-angular2 Run the project: cd hello-angular2 ng serve Change the port: ng serve --port 4201 --live-reload-port 49153 Create a component: ng g component contact-list-component The component w

Angular基础(四) 创建Angular应用

应用(Application)是由组件构成的树.树的根部是最顶层的组件即应用本身,启动的时候,浏览器会最先渲染顶层组件,然后根据树形结构,迭代渲染子组件.组件是可装配的,可以互相组合以构成更大的组件.本篇作者介绍了创建一个Angular应用的思路和过程. 一.介绍 要编写Angular应用是一个产品列表界面,先要从组件树的角度分析页面构成: 包含导航条.面包屑.产品列表三部分,产品列表又可进一步分割成单个产品->产品图片.价格.分类等.最终组件的树形结构为: 二.创建过程 a) 首先在app文件

angular学习笔记02 angular指令大全

第一步 先要引入angular, 第二步  在 html 标签中<html  ng-app>  加入ng-app(这是个必须的,不然会报错) 接下来就可以去使用angular的各种指令了. //js文件  js语法需要注意 在网上的写法有很多,最好是按标准的写法来写,不然js代码经过压缩就不能使用了(很重要) 压缩代码会出错,不压缩的话还是能运行的,原因是压缩代码会把关键字替换,因此 angular 在定义的时候需要这样. angular.module('antsins.controllers

angular CLI 快速搭建angular 项目

1. 首先确保你的电脑上安装了Node.js®和npm 2.打开终端/或命令窗,安装全局 angular CLI npm install -g @angular/cli 3. 创建新项目 //运行下列命令来生成一个新项目以及应用的骨架代码: ng new project-name // 请耐心等待. 创建新项目需要花费很多时间,大多数时候都是在安装那些npm包. 4. 启动开发服务器 // 进入项目目录 cd my-app //启动服务 ng serve --open 5. 文件结构如下 src

angular js模块,angular js控制器

AngularJS 模块 var app = angular.module('myApp', []); AngularJS 控制器 app.controller('myCtrl', function($scope) { $scope.firstName= "John"; $scope.lastName= "Doe"; }); AngularJS 实例 <div ng-app="myApp" ng-controller="myCtr