日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Angular 2 JIT vs AOT

發布時間:2023/12/31 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Angular 2 JIT vs AOT 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載于:https://segmentfault.com/a/1190000008739157

在 Angular 應用程序中,包含了我們通過 Angular 提供的 API 實現的自定義指令。這些自定義指令對瀏覽器來說,都是無法識別的,因此每個 Angular 應用程序在運行前,都需要經歷一個編譯的階段。

在 Angular 2 中有兩種編譯模式:

  • JIT - Just-In-Time

  • AOT - Ahead-Of-Time

JIT - Just-In-Time

?

Just-in-Time 編譯模式開發流程

  • 使用 TypeScript 開發 Angular 應用

  • 運行 tsc 編譯 TypeScript 代碼

  • 使用 Webpack 或 Gulp 等其他工具構建項目,如代碼壓縮、合并等

  • 部署應用

應用部署后,當用戶通過瀏覽器訪問我們應用的時候,她將經歷以下步驟(非嚴格?CSP):

  • 下載應用相關的資源,如 JavaScript 文件、圖片、樣式資源

  • Angular 啟動

  • Angular 進入 JiT 編譯模式,開始編譯我們應用中的指令或組件,生成相應的 JavaScript 代碼

  • 應用完成渲染

AOT - Ahead-Of-Time

Ahead-Of-Time 編譯模式開發流程

  • 使用 TypeScript 開發 Angular 應用

  • 運行 ngc 編譯應用程序

    • 使用 Angular Compiler 編譯模板,一般輸出 TypeScript 代碼

    • 運行 tsc 編譯 TypeScript 代碼

  • 使用 Webpack 或 Gulp 等其他工具構建項目,如代碼壓縮、合并等

  • 部署應用

應用部署后,相比于 JIT 編譯模式,在 AOT 模式下用戶訪問我們的應用,只需經歷以下步驟:

  • 下載應用相關的資源,如 JavaScript 文件、圖片、樣式資源

  • Angular 啟動

  • 應用完成渲染

JIT vs AOT

Just-In-Time (JIT) compilation

Ahead-Of-Time (AOT) compilation

特性JITAOT
編譯平臺(Browser) 瀏覽器(Server) 服務器
編譯時機Runtime (運行時)Build (構建階段)
包大小較大較小
執行性能-更好
啟動時間-更短

除此之外 AOT 還有以下優點:

  • 在客戶端我們不需要導入體積龐大的 angular 編譯器,這樣可以減少我們 JS 腳本庫的大小

  • 使用 AOT 編譯后的應用,不再包含任何 HTML 片段,取而代之的是編譯生成的 TypeScript 代碼,這樣的話 TypeScript 編譯器就能提前發現錯誤。總而言之,采用 AOT 編譯模式,我們的模板是類型安全的。

另外感興趣的讀者,可以使用?source-map-explorer?工具查看不同模式下生成的?bundle?JS 文件中各種 JS 資源的占比。

AOT詳解

app.component.html

<button (click)="toggleHeading()">Toggle Heading</button> <h1 *ngIf="showHeading">Hello {{name}}</h1><h3>List of Heroes</h3> <div *ngFor="let hero of heroes">{{hero}}</div>

app.component.ts

import { Component } from '@angular/core';@Component({moduleId: module.id,selector: 'my-app',templateUrl: './app.component.html' }) export class AppComponent {name: string = 'Angular';showHeading = true;heroes = ['Magneta', 'Bombasto', 'Magma', 'Tornado'];toggleHeading() {this.showHeading = !this.showHeading;} }

安裝 npm 依賴:

npm?install @angular/compiler-cli @angular/platform-server --save

在項目根目錄新增?tsconfig-aot.json?配置文件,內容如下:

{"compilerOptions": {"target": "es5","module": "es2015","moduleResolution": "node","sourceMap": true,"emitDecoratorMetadata": true,"experimentalDecorators": true,"lib": ["es2015", "dom"],"noImplicitAny": true,"suppressImplicitAnyIndexErrors": true},"files": ["src/app/app.module.ts","src/main.ts"],"angularCompilerOptions": {"genDir": "aot","skipMetadataEmit" : true} }

執行 AoT 編譯:

  • node_modules/.bin/ngc -p tsconfig-aot.json

  • "node_modules/.bin/ngc" -p tsconfig-aot.json # Windows 用戶

命令成功運行后,在根目錄下會自動生成?aot?目錄,接下來我們來研究一下目錄中生成的文件:

*.component.ngfactory.ts

此類文件內包含以下定義:

  • View_{COMPONENT}_Host{COUNTER}?- 內部宿主組件

  • View_{COMPONENT}{COUNTER}?- 內部組件

上面的 {COMPONENT} 表示組件關聯的類名稱,{COUNTER} 是一個無符號整數。

它們都繼承于 AppView 并實現以下方法:

  • createInternal - 用于渲染組件

  • destroyInternal - 用于執行清理操作,如移除事件監聽、銷毀內嵌視圖

  • detectChangesInternal - 用于執行變化檢測

其中 detectChangesInternal 方法中包含了 JavaScript VM Friendly 的代碼,現在我們來看一下具體示例:

<h1?*ngIf="showHeading">Hello {{name}}</h1>

該模板編譯后,detectChangesInternal 方法中的代碼如下:

detectChangesInternal(throwOnChange:boolean):void {// 計算h1標簽中文本元素的內容const currVal_2:any = import3.inlineInterpolate(1,'Hello ' ,this.parentView.context.name,'');// 判斷新值與舊值是否相等,若不相等則更新文本的內容,同時設置舊值為當前值if (import3.checkBinding(throwOnChange,this._expr_2,currVal_2)) {this.renderer.setText(this._text_1,currVal_2);this._expr_2 = currVal_2;}}

接下來我們來看一下 Angular 1.x 中簡易版 $digest?:

// $scope.$watch('name', function(newValue, oldValue) {}) Scope.prototype.$watch = function (exp, fn) {'use strict';this.$$watchers.push({exp: exp,fn: fn,last: Utils.clone(this.$eval(exp))}); };Scope.prototype.$digest = function () {'use strict';var dirty, watcher, current, i;do {dirty = false; for (i = 0; i < this.$$watchers.length; i += 1) {watcher = this.$$watchers[i]; current = this.$eval(watcher.exp); // 計算新值if (!Utils.equals(watcher.last, current)) { // 比較新值和舊值watcher.last = Utils.clone(current); // 保存新值,用于下一次比較dirty = true;watcher.fn(current);}}} while (dirty); // 在Angular1.x的源碼中會有TTL值控制最大的檢測次數,避免出現死循環for (i = 0; i < this.$$children.length; i += 1) {this.$$children[i].$digest();} };

從上面的代碼可以看出,Angular 1.x 中變化檢測涉及循環遍歷比 Angular 2 的變化檢測邏輯復雜很多。此外 Angular 2 的變化檢測是單向的,從根組件開始執行,具體如下圖:

更令人興奮的是,我們還可以靈活地設置 ChangeDetectionStrategy (變化檢測策略) 來進一步提供應用的性能。

AOT實戰

1.使用?ngc?命令行工具

示例項目:

  • ngc + Webpack

  • ngc + Rollup

  • ngc + library generation

2.使用?@ngtools/webpack?Webpack 2 插件

webpack.config.js 配置:

'use strict'; let path = require('path'); let AotPlugin = require('@ngtools/webpack').AotPlugin;module.exports = {module: {rules: [{ test: /\.ts/, use: '@ngtools/webpack' }]},plugins: [new AotPlugin({tsConfigPath: path.join(process.cwd(), 'tsconfig.json'),entryModule: path.join(process.cwd(), 'src/app/modules/main.module#MainModule')})] };

示例項目:

  • Webpack 2 + plugin

  • Angular CLI

3.使用?@ultimate/aot-loader?Webpack 2 插件

webpack.config.js 配置:

'use strict'; let path = require('path'); let AotPlugin = require('@ultimate/aot-loader').AotPlugin;module.exports = {module: {rules: [{ test: /\.ts/, use: '@ultimate/aot-loader' }]},plugins: [new AotPlugin({tsConfig: path.join(process.cwd(), 'tsconfig.json'),entryModule: path.join(process.cwd(), 'src/app/modules/main.module#MainModule')})] };

示例項目:

  • Webpack 2 + plugin

參考資源

  • angular cookbook aot-compiler

  • Ahead-of-Time Compilation in Angular

  • Multiple solutions for Angular Ahead of Time (AOT) Compilation

總結

以上是生活随笔為你收集整理的Angular 2 JIT vs AOT的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。