漸進式

漸進式是指根據應用程式的需求下載程式碼,而不是急切地下載整個程式碼庫。

這與 Qwik 的 核心原則 相呼應,該原則側重於盡可能延遲 JavaScript 的載入和執行。為實現此目標,Qwik 需要將應用程式分解成許多可延遲載入的區塊。

現狀

現有框架存在兩個問題:

  • 延遲載入邊界完全委託給開發人員
  • 框架只能延遲載入當前渲染樹中不存在的組件。

問題在於框架需要將其內部狀態與 DOM 協調一致。這意味著應用程式中至少會發生一次 注水。框架必須能夠執行完整渲染以重建框架的內部狀態。在第一次渲染之後,框架可以更加精確地進行更新,但損害已經造成,程式碼已經被下載。因此,現在出現了兩個問題

  • 框架需要下載和執行組件以在啟動時重建渲染樹。(參見 注水是純粹的開銷)這會強制立即下載和執行渲染樹中的所有組件。
  • 事件處理常式隨組件一起提供,即使在渲染時不需要它們。包含事件處理常式會強制下載不必要的程式碼。

解決方案

Qwik 的架構充分利用了現代工具來自動化入口點生成的過程。開發人員可以正常編寫組件,而 Qwik 優化器會將組件拆分為多個區塊,並在需要時下載它們。

此外,即使組件是渲染樹的一部分,框架執行時也不需要下載互動性不需要的程式碼。

優化器

優化器 是一種程式碼轉換,它將函數提取到頂級可導入符號中,這使得 Qwik 執行時能夠在需要時延遲載入 JavaScript。

優化器和 Qwik 執行時協同工作,以實現所需的細粒度延遲載入結果。

如果沒有優化器,則

  • 程式碼必須由開發人員分解成可導入的部分。這對於編寫應用程式來說是不自然的,會導致糟糕的開發體驗。
  • 應用程式將不得不載入大量不必要的程式碼,因為沒有延遲載入邊界。

Qwik 執行時必須理解優化器的輸出。這裡需要理解的是,通過將組件分解成可延遲載入的區塊,延遲載入需求將異步程式碼引入了框架中。必須以不同的方式編寫框架以考慮異步性。現有框架假設所有程式碼都是同步可用的。這種假設阻礙了將延遲載入輕鬆插入現有框架中。(例如,當創建一個新組件時,框架假設可以同步調用其初始化程式碼。如果這是第一次引用組件,則需要延遲載入其程式碼,因此框架必須考慮到這一點)。

延遲載入

延遲載入是異步的。Qwik 是一個異步框架。Qwik 理解在任何時候,它都可能沒有對回調的引用,因此,它可能需要延遲載入它。(相比之下,大多數現有框架都假設所有程式碼都是同步可用的,這使得延遲載入變得不那麼容易)。

在 Qwik 中,所有東西都是可以延遲載入的

  • 渲染時的組件 - 初始化塊和渲染塊
  • 組件任務 - 副作用,僅在輸入更改時下載
  • 監聽器 - 僅在互動時下載
  • 樣式 - 僅在伺服器尚未提供時下載

延遲加載是框架的核心屬性,而不是事後才想到的。

優化器和 $

再看一下這個例子

// the `$` suffix for `component` indicates that the component should be
// lazy-loaded.
export const Counter = component$(() => {
  const count = useSignal(0);
 
  // the `$` suffix for `onClick` indicates that the implementation for
  // the handler should be lazy-loaded.
  return <button onClick$={() => count.value++}>{count.value}</button>;
});

請注意程式碼中 $ 的存在。$ 是一個標記,告訴優化器它後面的函數應該被延遲加載。$ 是一個單一字元,用於提示優化器和開發人員,讓他們知道這裡發生了非同步延遲加載。

貢獻者

感謝所有幫助改進此文檔的貢獻者!

  • adamdbradley
  • RATIU5
  • manucorporat
  • fleish80
  • msssk
  • mhevery
  • mrhoodz
  • thejackshelton
  • moinulmoin