成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

前端框架的JIT與AOT,傻傻分不清楚

開發 前端
本文會聊聊兩者的區別,及前端框架中AOT的應用。Angular同時提供這兩種編譯方案,下面我們用Angular舉例說明兩者的區別。

[[433991]]

大家好,我卡頌。

現代前端框架都需要“編譯”這一步驟,用于:

  • 將框架中描述的UI轉換為宿主環境可識別的代碼
  • 代碼轉化,比如將ts編譯為js、實現polyfill等
  • 執行一些編譯時優化
  • 代碼打包、壓縮、混淆

編譯可以選擇放在兩個時機執行:

  • 代碼構建時,被稱為AOT(Ahead Of Time,提前編譯或預編譯),宿主環境獲得的是編譯后的代碼
  • 代碼在宿主環境執行時,被稱為JIT(Just In Time,即時編譯),代碼在宿主環境編譯并執行

本文會聊聊兩者的區別,及前端框架中AOT的應用。

AOT和JIT的區別

Angular同時提供這兩種編譯方案,下面我們用Angular舉例說明兩者的區別。

考慮如下Angular代碼:

  1. import { Component } from "@angular/core"
  2.  
  3. @Component({ 
  4.   selector: "app-root"
  5.   template: "<h3>{{getTitle()}}</h3>" 
  6. }) 
  7. export class AppComponent { 
  8.   public getTitle() { 
  9.     return 'Hello World'
  10.   } 

定義AppComponent,最終瀏覽器(作為宿主環境)渲染的結果為:

現在將模版中使用的getTitle方法修改為未定義的getTitleXXX:

  1. // 從 
  2. template: "<h3>{{getTitle()}}</h3>" 
  3. // 修改為 
  4. template: "<h3>{{getTitleXXX()}}</h3>" 

 如果使用AOT,編譯后會立刻報錯:

ERROR occurs in the template of component AppComponent.

如果使用JIT,編譯后不會報錯,代碼在瀏覽器中執行時會報錯:

ERROR TypeError: _co.getTitleXXX is not a function

造成以上區別的原因是:當使用JIT時,構建階段僅僅使用tsc將ts編譯為js并將代碼打包。

打包后的代碼在瀏覽器運行后,執行到Decorator(上例中的@Component語句)時,Angular的模版編譯器才開始編譯template字段包含的模版語法,并報錯。

當使用AOT時,tsc、Angular的模版編譯器都會在構建階段進行編譯,所以會立刻發現template字段包含的錯誤。

除了以上區別外,JIT與AOT的區別還包括:

  • 使用JIT的應用在首次加載時慢于AOT,因為其需要先編譯代碼,而使用AOT的應用已經在構建時完成編譯,可以直接執行代碼
  • 使用JIT的應用代碼體積普遍大于使用AOT的應用,因為在運行時會多出編譯器代碼

基于以上原因,在Angular中一般在開發環境使用JIT,在生產環境使用AOT。

從前端框架的角度看AOT可以用兩個步驟描述前端框架的工作原理:

  1. 根據組件狀態變化找到變化的UI
  2. 將UI變化渲染為宿主環境的真實UI

借助AOT對模版語法編譯時的優化,就能減少步驟1的開銷。

這是大部分采用模版語法描述UI的前端框架都會進行的優化,比如Vue3、Angular、Svelte。

其本質原因在于模版語法的寫法是固定的,固定意味著「可分析」。

「可分析」意味著在編譯時可以標記模版語法中的靜態部分(不變的部分)與動態部分(包含自變量,可變的部分),使步驟1在尋找變化的UI時可以跳過靜態部分。

甚至Svelte、Solid.js直接利用AOT在編譯時建立了「組件狀態與UI中動態部分的關系」,在運行時,組件狀態變化后,可以直接執行步驟2。

AOT與JSX

而采用JSX描述UI的前端框架則很難從AOT中受益。

原因在于JSX是ES的語法糖,作為JS語句只有執行后才能知道結果,所以很難被靜態分析。

為了讓使用JSX描述UI的前端框架在AOT中受益,有兩個思路:

  • 使用新的AOT思路
  • 約束JSX的靈活性

React嘗試過第一種思路。prepack是meta(原Facebook)推出的一款React編譯器,用來實現AOT優化。

[[433994]]

他的思路是:在保持運行結果一致的情況下,改變源代碼的運行邏輯,輸出性能更高的代碼。

即:代碼在編譯時將計算結果保留在編譯后代碼中,而不是在運行時才去求值。

比如,如下代碼:

  1. (function () { 
  2.   function hello() { return 'hello'; } 
  3.   function world() { return 'world'; } 
  4.   global.s = hello() + ' ' + world(); 
  5. })(); 

經由prepack編譯后輸出:

  1. s = "hello world"

遺憾的是,由于復雜度以及人力成本考慮,prepack項目已于三年前暫停了。

Solid.js同樣使用JSX描述視圖,他實現了幾個內置組件用于描述UI的邏輯,從而減少JSX的靈活性,使AOT成為可能。比如:

For替代數組的map方法:

  1. <For each={state.list} fallback={<div>Loading...</div>}> 
  2.   {(item) => <div>{item}</div>} 
  3. </For

 Show替代if條件語句:

  1. <Show when={state.count > 0} fallback={<div>Loading...</div>}> 
  2.   <div>My Content</div> 
  3. </Show> 

總結

總結一下,前端框架可以從AOT中收獲很多益處,其中最主要的一條是:

減少“根據組件狀態變化找到變化的UI”這一步驟的工作量

要實現AOT的前提是:組件代碼易于分析。

 

責任編輯:姜華 來源: 魔術師卡頌
相關推薦

2021-03-10 08:56:37

Zookeeper

2022-05-15 21:52:04

typeTypeScriptinterface

2021-07-27 07:31:16

JavaArrayList數組

2024-02-29 09:08:56

Encoding算法加密

2020-10-30 08:20:04

SD卡TF卡存儲

2018-12-17 12:30:05

Kubernetes存儲存儲卷

2018-05-22 16:24:20

HashMapJavaJDK

2025-05-12 08:40:00

前端監控DOM

2024-11-04 00:00:03

viewportDOMSPA

2020-03-03 17:35:09

Full GCMinor

2023-02-27 15:46:19

數據元元數據

2023-09-03 21:18:07

Python編程語言

2021-02-08 23:47:51

文件存儲塊存儲對象存儲

2016-11-04 12:51:46

Unix網絡IO 模型

2022-02-25 09:14:33

類變量共享實例變量

2020-11-11 07:32:18

MySQL InnoDB 存儲

2023-04-11 15:57:49

JavaScriptCSSHTML

2021-01-13 08:10:26

接口IEnumeratorIEnumerable

2021-02-14 22:33:23

Java字符字段

2021-12-29 07:34:40

Filter CSS backdrop-fi
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美极品在线播放 | 久久久免费电影 | 在线视频一区二区三区 | 91五月天| 成人精品久久日伦片大全免费 | 亚洲精品一区二区网址 | 伊人精品国产 | 在线免费观看欧美 | 日本精品一区二区三区在线观看视频 | 亚洲午夜精品久久久久久app | 国产精品伦理一区 | 亚洲精品在线免费观看视频 | 综合色久 | 成人精品视频 | 91看片网| 国产一级视频免费播放 | 欧美国产亚洲一区二区 | 91最新在线视频 | 操皮视频| 国产精品毛片一区二区三区 | 欧美人妇做爰xxxⅹ性高电影 | 久久久久久九九九九九九 | 成人午夜精品 | 久久成人精品一区二区三区 | 欧美精品在线播放 | 亚洲色图在线观看 | 国产激情免费视频 | 国产91一区 | 国产日韩一区二区三区 | 98久久| 亚洲第一av| 国产精品免费视频一区 | 国产高清免费视频 | 国产精品福利在线观看 | 中文字幕 在线观看 | 国产欧美在线播放 | 成人精品国产一区二区4080 | 日韩精品成人在线 | 91资源在线 | 日韩欧美一级片 | 久久久久久久久久一区二区 |