From d28a8adcff2d0c9601b718450afb2ed0f251e5fa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=A1=E8=89=B2?= <cipchk@qq.com>
Date: Thu, 14 Nov 2024 02:13:02 +0800
Subject: [PATCH] perf: optimizing `@let` (#1849)

---
 packages/abc/cell/cell.component.ts     |  7 ++--
 packages/abc/hotkey/hotkey.directive.ts |  4 +--
 packages/abc/hotkey/index.en-US.md      |  2 +-
 packages/abc/hotkey/index.zh-CN.md      |  2 +-
 packages/abc/st/st-td.component.html    | 47 ++++++++++++-------------
 packages/abc/st/st.component.html       |  9 ++---
 packages/abc/st/st.module.ts            |  2 --
 packages/form/src/sf.component.html     | 20 ++++++-----
 8 files changed, 47 insertions(+), 46 deletions(-)

diff --git a/packages/abc/cell/cell.component.ts b/packages/abc/cell/cell.component.ts
index 4e8e96bbf4..724b8fea47 100644
--- a/packages/abc/cell/cell.component.ts
+++ b/packages/abc/cell/cell.component.ts
@@ -68,13 +68,14 @@ import type { CellDefaultText, CellOptions, CellTextResult, CellValue } from './
         }
         @case ('img') {
           @for (i of $any(_text); track $index) {
+            @let img = safeOpt.img;
             <img
               [attr.src]="i"
-              [attr.height]="safeOpt.img?.size"
-              [attr.width]="safeOpt.img?.size"
+              [attr.height]="img?.size"
+              [attr.width]="img?.size"
               (click)="_showImg(i)"
               class="img"
-              [class.point]="safeOpt.img?.big"
+              [class.point]="img?.big"
             />
           }
         }
diff --git a/packages/abc/hotkey/hotkey.directive.ts b/packages/abc/hotkey/hotkey.directive.ts
index 487a0c686c..0d256c9222 100644
--- a/packages/abc/hotkey/hotkey.directive.ts
+++ b/packages/abc/hotkey/hotkey.directive.ts
@@ -10,9 +10,9 @@ export class HotkeyDirective implements OnDestroy {
   private readonly platform = inject(Platform);
 
   /**
-   * Specify [hotkey format](https://github.com/github/hotkey#hotkey-string-format)
+   * Specify [hotkey format](https://github.com/github/hotkey#hotkey-string-format), you can get the code through [Hotkey Code](https://github.github.com/hotkey/hotkey_mapper.html)
    *
-   * 指定[热键格式](https://github.com/github/hotkey#hotkey-string-format)
+   * 指定[热键格式](https://github.com/github/hotkey#hotkey-string-format),可以通过 [Hotkey Code](https://github.github.com/hotkey/hotkey_mapper.html) 来获取代码。
    */
   @Input('hotkey')
   set hotkey(key: string) {
diff --git a/packages/abc/hotkey/index.en-US.md b/packages/abc/hotkey/index.en-US.md
index 49891134d0..6cb52abbdc 100644
--- a/packages/abc/hotkey/index.en-US.md
+++ b/packages/abc/hotkey/index.en-US.md
@@ -9,7 +9,7 @@ module: import { HotkeyModule } from '@delon/abc/hotkey';
 
 Based on the [@github/hotke](https://github.com/github/hotkey) hotkey library.
 
-> If you don't know the hotkey value, you can get it through [Hotkey Code](https://github.github.io/hotkey/hotkey_mapper.html).
+> If you don't know the hotkey value, you can get it through [Hotkey Code](https://github.github.com/hotkey/hotkey_mapper.html).
 
 ## API
 
diff --git a/packages/abc/hotkey/index.zh-CN.md b/packages/abc/hotkey/index.zh-CN.md
index b015854e54..2fc532b53c 100644
--- a/packages/abc/hotkey/index.zh-CN.md
+++ b/packages/abc/hotkey/index.zh-CN.md
@@ -9,7 +9,7 @@ module: import { HotkeyModule } from '@delon/abc/hotkey';
 
 基于 [@github/hotke](https://github.com/github/hotkey) 热键库。
 
-> 如果不清楚热键值,可通过[热键代码](https://github.github.io/hotkey/hotkey_mapper.html)来获取。
+> 如果不清楚热键值,可通过[热键代码](https://github.github.com/hotkey/hotkey_mapper.html)来获取。
 
 ## API
 
diff --git a/packages/abc/st/st-td.component.html b/packages/abc/st/st-td.component.html
index 0d9f60fb7b..7589610d4a 100644
--- a/packages/abc/st/st-td.component.html
+++ b/packages/abc/st/st-td.component.html
@@ -9,14 +9,15 @@
 </ng-template>
 <ng-template #btnItemTpl let-i>
   @if (i.pop) {
+    @let pop = i.pop;
     <a
       nz-popconfirm
-      [nzPopconfirmTitle]="i.pop.title"
-      [nzIcon]="i.pop.icon"
-      [nzCondition]="i.pop.condition(i)"
-      [nzCancelText]="i.pop.cancelText"
-      [nzOkText]="i.pop.okText"
-      [nzOkType]="i.pop.okType"
+      [nzPopconfirmTitle]="pop.title"
+      [nzIcon]="pop.icon"
+      [nzCondition]="pop.condition(i)"
+      [nzCancelText]="pop.cancelText"
+      [nzOkText]="pop.okText"
+      [nzOkType]="pop.okType"
       (nzOnConfirm)="_btn(i)"
       class="st__btn-text"
       [ngClass]="i._className"
@@ -32,15 +33,16 @@
 </ng-template>
 <ng-template #btnTextTpl let-i>
   @if (i._icon) {
-    @if (i._icon.iconfont) {
-      <i nz-icon [nzIconfont]="i._icon.iconfont"></i>
+    @let icon = i._icon;
+    @if (icon.iconfont) {
+      <i nz-icon [nzIconfont]="icon.iconfont"></i>
     } @else {
       <i
         nz-icon
-        [nzType]="i._icon.type"
-        [nzTheme]="i._icon.theme"
-        [nzSpin]="i._icon.spin"
-        [nzTwotoneColor]="i._icon.twoToneColor"
+        [nzType]="icon.type"
+        [nzTheme]="icon.theme"
+        [nzSpin]="icon.spin"
+        [nzTwotoneColor]="icon.twoToneColor"
       ></i>
     }
   }
@@ -49,6 +51,7 @@
 @if (c.__render) {
   <ng-template [ngTemplateOutlet]="c.__render!" [ngTemplateOutletContext]="{ $implicit: i, index: index, column: c }" />
 } @else {
+  @let col = i._values[cIdx];
   @switch (c.type) {
     @case ('checkbox') {
       <label nz-checkbox [nzDisabled]="i.disabled" [ngModel]="i.checked" (ngModelChange)="_checkbox($event)"></label>
@@ -57,35 +60,31 @@
       <label nz-radio [nzDisabled]="i.disabled" [ngModel]="i.checked" (ngModelChange)="_radio()"></label>
     }
     @case ('link') {
-      <a (click)="_link($event)" [innerHTML]="i._values[cIdx]._text" [attr.title]="i._values[cIdx].text"></a>
+      <a (click)="_link($event)" [innerHTML]="col._text" [attr.title]="col.text"></a>
     }
     @case ('tag') {
-      <nz-tag [nzColor]="i._values[cIdx].color" [nz-tooltip]="i._values[cIdx].tooltip">
-        <span [innerHTML]="i._values[cIdx]._text"></span>
+      <nz-tag [nzColor]="col.color" [nz-tooltip]="col.tooltip">
+        <span [innerHTML]="col._text"></span>
       </nz-tag>
     }
     @case ('badge') {
-      <nz-badge
-        [nzStatus]="i._values[cIdx].color"
-        [nzText]="i._values[cIdx].text"
-        [nz-tooltip]="i._values[cIdx].tooltip"
-      />
+      <nz-badge [nzStatus]="col.color" [nzText]="col.text" [nz-tooltip]="col.tooltip" />
     }
     @case ('cell') {
-      <cell [value]="i._values[cIdx].text" [options]="i._values[cIdx].cell ?? c.cell" />
+      <cell [value]="col.text" [options]="col.cell ?? c.cell" />
     }
     @case ('widget') {
       <ng-template st-widget-host [record]="i" [column]="c" />
     }
     @default {
       @if (c.safeType === 'text') {
-        <span [innerText]="i._values[cIdx]._text" [attr.title]="c._isTruncate ? i._values[cIdx].text : null"></span>
+        <span [innerText]="col._text" [attr.title]="c._isTruncate ? col.text : null"></span>
       } @else {
-        <span [innerHTML]="i._values[cIdx]._text" [attr.title]="c._isTruncate ? i._values[cIdx].text : null"></span>
+        <span [innerHTML]="col._text" [attr.title]="c._isTruncate ? col.text : null"></span>
       }
     }
   }
-  @for (btn of i._values[cIdx].buttons; track $index) {
+  @for (btn of col.buttons; track $index) {
     @if (btn.children!.length > 0) {
       <a nz-dropdown [nzDropdownMenu]="btnMenu" nzOverlayClassName="st__btn-sub">
         <span [innerHTML]="btn._text"></span>
diff --git a/packages/abc/st/st.component.html b/packages/abc/st/st.component.html
index 1f0b3f7fa5..e943156b70 100644
--- a/packages/abc/st/st.component.html
+++ b/packages/abc/st/st.component.html
@@ -61,8 +61,8 @@
             <th nzWidth="50px" [rowSpan]="_headers.length"></th>
           }
           @for (h of row; track h; let index = $index; let last = $last) {
+            @let _c = h.column;
             <th
-              *let="h.column as _c"
               [colSpan]="h.colSpan"
               [rowSpan]="h.rowSpan"
               [nzWidth]="$any(_c).width"
@@ -172,14 +172,15 @@
           </ng-template>
         }
         @for (c of _columns; track cIdx; let cIdx = $index) {
-          @if (i._values[cIdx].props?.colSpan > 0 && i._values[cIdx].props?.rowSpan > 0) {
+          @let props = i._values[cIdx].props;
+          @if (props?.colSpan > 0 && props?.rowSpan > 0) {
             <td
               [nzLeft]="!!c._left"
               [nzRight]="!!c._right"
               [attr.data-col-index]="cIdx"
               [ngClass]="c._className"
-              [attr.colspan]="i._values[cIdx].props?.colSpan === 1 ? null : i._values[cIdx].props?.colSpan"
-              [attr.rowspan]="i._values[cIdx].props?.rowSpan === 1 ? null : i._values[cIdx].props?.rowSpan"
+              [attr.colspan]="props?.colSpan === 1 ? null : props?.colSpan"
+              [attr.rowspan]="props?.rowSpan === 1 ? null : props?.rowSpan"
             >
               @if (responsive) {
                 <span class="ant-table-rep__title">
diff --git a/packages/abc/st/st.module.ts b/packages/abc/st/st.module.ts
index f74d37cc4f..d7cc671683 100644
--- a/packages/abc/st/st.module.ts
+++ b/packages/abc/st/st.module.ts
@@ -3,7 +3,6 @@ import { NgModule } from '@angular/core';
 import { FormsModule } from '@angular/forms';
 
 import { CellModule } from '@delon/abc/cell';
-import { LetModule } from '@delon/abc/let';
 import { DelonACLModule } from '@delon/acl';
 import { NzBadgeModule } from 'ng-zorro-antd/badge';
 import { NzCheckboxModule } from 'ng-zorro-antd/checkbox';
@@ -33,7 +32,6 @@ const COMPONENTS = [STComponent, STRowDirective, STWidgetHostDirective];
     CommonModule,
     FormsModule,
     DelonACLModule,
-    LetModule,
     CellModule,
     NzPopconfirmModule,
     NzTableModule,
diff --git a/packages/form/src/sf.component.html b/packages/form/src/sf.component.html
index b69d1457ce..876618ae3d 100644
--- a/packages/form/src/sf.component.html
+++ b/packages/form/src/sf.component.html
@@ -3,8 +3,9 @@
 </ng-template>
 <ng-template #btnTpl>
   @if (button !== 'none') {
-    @if (_btn && _btn.render) {
-      <nz-form-item [ngClass]="_btn.render!.class!" class="sf-btns" [fixed-label]="_btn.render!.spanLabelFixed!">
+    @let btnRender = _btn.render;
+    @if (btnRender) {
+      <nz-form-item [ngClass]="btnRender.class!" class="sf-btns" [fixed-label]="btnRender.spanLabelFixed!">
         <div
           nz-col
           class="ant-form-item-control"
@@ -25,7 +26,7 @@
                   nz-button
                   data-type="submit"
                   [nzType]="_btn.submit_type!"
-                  [nzSize]="_btn.render!.size!"
+                  [nzSize]="btnRender.size!"
                   [nzLoading]="loading"
                   [disabled]="liveValidate && !valid"
                 >
@@ -46,17 +47,18 @@
                     nz-button
                     data-type="reset"
                     [nzType]="_btn.reset_type!"
-                    [nzSize]="_btn.render!.size!"
+                    [nzSize]="btnRender.size!"
                     [disabled]="loading"
                     (click)="reset(true)"
                   >
-                    @if (_btn.reset_icon) {
+                    @let resetIcon = _btn.reset_icon;
+                    @if (resetIcon) {
                       <i
                         nz-icon
-                        [nzType]="_btn.reset_icon.type!"
-                        [nzTheme]="_btn.reset_icon.theme!"
-                        [nzTwotoneColor]="_btn.reset_icon.twoToneColor!"
-                        [nzIconfont]="_btn.reset_icon.iconfont!"
+                        [nzType]="resetIcon.type!"
+                        [nzTheme]="resetIcon.theme!"
+                        [nzTwotoneColor]="resetIcon.twoToneColor!"
+                        [nzIconfont]="resetIcon.iconfont!"
                       ></i>
                     }
                     {{ _btn.reset }}