精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

簡單、好懂的Svelte實現原理

開發 前端
本文會圍繞一張流程圖和兩個Demo講解,正確的食用方式是用電腦打開本文,跟著流程圖、Demo一邊看、一邊敲、一邊學

[[434242]]

大家好,我卡頌。

Svelte問世很久了,一直想寫一篇好懂的原理分析文章,拖了這么久終于寫了。

本文會圍繞一張流程圖和兩個Demo講解,正確的食用方式是用電腦打開本文,跟著流程圖、Demo一邊看、一邊敲、一邊學。

讓我么開始吧。

Demo1

Svelte的實現原理如圖:

圖中Component是開發者編寫的組件,內部虛線部分是由Svelte編譯器編譯而成的。圖中的各個箭頭是運行時的工作流程。

首先來看編譯時,考慮如下App組件代碼:

  1. <h1>{count}</h1> 
  2.  
  3. <script> 
  4.   let count = 0; 
  5. </script> 

完整代碼見Demo1 repl[1]

瀏覽器會顯示:

這段代碼經由編譯器編譯后產生如下代碼,包括三部分:

  • create_fragment方法
  • count的聲明語句
  • class App的聲明語句
  1. // 省略部分代碼… 
  2. function create_fragment(ctx) { 
  3.   let h1; 
  4.  
  5.   return { 
  6.     c() { 
  7.       h1 = element("h1"); 
  8.       h1.textContent = `${count}`; 
  9.     }, 
  10.     m(target, anchor) { 
  11.       insert(target, h1, anchor); 
  12.     }, 
  13.     d(detaching) { 
  14.       if (detaching) detach(h1); 
  15.     } 
  16.   }; 
  17.  
  18. let count = 0; 
  19.  
  20. class App extends SvelteComponent { 
  21.   constructor(options) { 
  22.     super(); 
  23.     init(this, options, null, create_fragment, safe_not_equal, {}); 
  24.   } 
  25.  
  26. export default App; 

create_fragment

首先來看create_fragment方法,他是編譯器根據App的UI編譯而成,提供該組件與瀏覽器交互的方法,在上述編譯結果中,包含3個方法:

  • c,代表create,用于根據模版內容,創建對應DOM Element。例子中創建H1對應DOM Element:
  1. h1 = element("h1"); 
  2. h1.textContent = `${count}`; 
  • m,代表mount,用于將c創建的DOM Element插入頁面,完成組件首次渲染。例子中會將H1插入頁面:
  1. insert(target, h1, anchor); 

insert方法會調用target.insertBefore:

  1. function insert(target, node, anchor) { 
  2.   target.insertBefore(node, anchor || null); 
  • d,代表detach,用于將組件對應DOM Element從頁面中移除。例子中會移除H1:
  1. if (detaching) detach(h1); 

detach方法會調用parentNode.removeChild:

  1. function detach(node) { 
  2.   node.parentNode.removeChild(node); 

仔細觀察流程圖,會發現App組件編譯的產物沒有圖中fragment內的p方法。

這是因為App沒有「變化狀態」的邏輯,所以相應方法不會出現在編譯產物中。

可以發現,create_fragment返回的c、m方法用于組件首次渲染。那么是誰調用這些方法呢?

SvelteComponent

每個組件對應一個繼承自SvelteComponent的class,實例化時會調用init方法完成組件初始化,create_fragment會在init中調用:

  1. class App extends SvelteComponent { 
  2.   constructor(options) { 
  3.     super(); 
  4.     init(this, options, null, create_fragment, safe_not_equal, {}); 
  5.   } 

總結一下,流程圖中虛線部分在Demo1中的編譯結果為:

  • fragment:編譯為create_fragment方法的返回值
  • UI:create_fragment返回值中m方法的執行結果
  • ctx:代表組件的上下文,由于例子中只包含一個不會改變的狀態count,所以ctx就是count的聲明語句

可以改變狀態的Demo

現在修改Demo,增加update方法,為H1綁定點擊事件,點擊后count改變:

  1. <h1 on:click="{update}">{count}</h1> 
  2.  
  3. <script> 
  4.   let count = 0; 
  5.   function update() { 
  6.     count++; 
  7.   } 
  8. </script> 

完整代碼見Demo2 repl[2]

編譯產物發生變化,ctx的變化如下:

  1. // 從module頂層的聲明語句 
  2. let count = 0; 
  3.  
  4. // 變為instance方法 
  5. function instance($$self, $$props, $$invalidate) { 
  6.   let count = 0; 
  7.  
  8.   function update() { 
  9.     $$invalidate(0, count++, count); 
  10.   } 
  11.  
  12.   return [countupdate]; 

count從module頂層的聲明語句變為instance方法內的變量。之所以產生如此變化是因為App可以實例化多個:

  1. // 模版中定義3個App 
  2. <App/> 
  3. <App/> 
  4. <App/> 
  5.  
  6. // 當count不可變時,頁面渲染為:<h1>0</h1> 
  7. <h1>0</h1> 
  8. <h1>0</h1> 

當count不可變時,所有App可以復用同一個count。但是當count可變時,根據不同App被點擊次數不同,頁面可能渲染為:

  1. <h1>0</h1> 
  2. <h1>3</h1> 
  3. <h1>1</h1> 

所以每個App需要有獨立的上下文保存count,這就是instance方法的意義。推廣來說,Svelte編譯器會追蹤<script>內所有變量聲明:

  • 是否包含改變該變量的語句,比如count++
  • 是否包含重新賦值的語句,比如count = 1
  • 等等情況

一旦發現,就會將該變量提取到instance中,instance執行后的返回值就是組件對應ctx。

同時,如果執行如上操作的語句可以通過模版被引用,則該語句會被$$invalidate包裹。

在Demo2中,update方法滿足:

  • 包含改變count的語句 —— count++
  • 可以通過模版被引用 —— 作為點擊回調函數

所以編譯后的update內改變count的語句被$$invalidate方法包裹:

  1. // 源代碼中的update 
  2. function update() { 
  3.   count++; 
  4.  
  5. // 編譯后instance中的update 
  6. function update() { 
  7.   $$invalidate(0, count++, count); 

從流程圖可知,$$invalidate方法會執行如下操作:

  • 更新ctx中保存狀態的值,比如Demo2中count++
  • 標記dirty,即標記App UI中所有和count相關的部分將會發生變化
  • 調度更新,在microtask中調度本次更新,所有在同一個macrotask中執行的$$invalidate都會在該macrotask執行完成后被統一執行,最終會執行組件fragment中的p方法

p方法是Demo2中新的編譯產物,除了p之外,create_fragment已有的方法也產生相應變化:

  1. c() { 
  2.   h1 = element("h1"); 
  3.   // count的值變為從ctx中獲取 
  4.   t = text(/*count*/ ctx[0]); 
  5. }, 
  6. m(target, anchor) { 
  7.   insert(target, h1, anchor); 
  8.   append(h1, t); 
  9.   // 事件綁定 
  10.   dispose = listen(h1, "click", /*update*/ ctx[1]); 
  11. }, 
  12. p(ctx, [dirty]) { 
  13.   // set_data會更新t保存的文本節點 
  14.   if (dirty & /*count*/ 1) set_data(t, /*count*/ ctx[0]); 
  15. }, 
  16. d(detaching) { 
  17.   if (detaching) detach(h1); 
  18.   // 事件解綁 
  19.   dispose(); 

p方法會執行$$invalidate中標記為dirty的項對應的更新函數。

在Demo2中,App UI中只引用了狀態count,所以update方法中只有一個if語句,如果UI中引用了多個狀態,則p方法中也會包含多個if語句:

  1. // UI中引用多個狀態  
  2. <h1 on:click="{count0++}">{count0}</h1> 
  3. <h1 on:click="{count1++}">{count1}</h1> 
  4. <h1 on:click="{count2++}">{count2}</h1> 

 對應p方法包含多個if語句:

  1. p(new_ctx, [dirty]) { 
  2.   ctx = new_ctx; 
  3.   if (dirty & /*count*/ 1) set_data(t0, /*count*/ ctx[0]); 
  4.   if (dirty & /*count1*/ 2) set_data(t2, /*count1*/ ctx[1]); 
  5.   if (dirty & /*count2*/ 4) set_data(t4, /*count2*/ ctx[2]); 
  6. }, 

Demo2完整的更新步驟如下:

  1. 點擊H1觸發回調函數update
  2. update內調用$$invalidate,更新ctx中的count,標記count為dirty,調度更新
  3. 執行p方法,進入dirty的項(即count)對應if語句,執行更新對應DOM Element的方法

總結

Svelte的完整工作流程會復雜的多,但是核心實現便是如此。

我們可以直觀的感受到,借由模版語法的約束,經過編譯優化,可以直接建立「狀態與要改變的DOM節點的對應關系」。

在Demo2中,狀態count的變化直接對應p方法中一個if語句,使得Svelte執行「細粒度的更新」時對比使用虛擬DOM的框架更有性能優勢。

上述性能分析中第四行「select row」就是一個「細粒度的更新」。想比較之下,React(倒數第三列)性能就差很多。

參考資料

[1]Demo1 repl:

https://svelte.dev/repl/9945d189204a4168b4c23890f1d92a3a?version=3.19.1[2]Demo2 repl:

https://svelte.dev/repl/bf22a31a0eff4875b5b3084aa2b85fc3?version=3.19.1

 

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

2021-10-31 23:57:33

Eslint原理

2023-06-02 16:28:01

2016-12-26 18:05:00

單點登錄原理簡單實現

2022-05-06 09:22:25

Go泛型

2022-03-16 22:24:50

ReactstateHooks

2022-03-11 19:54:07

Svelte應用程序JavaScript

2023-06-13 18:24:26

TypeScriptJSDoc開發

2021-09-06 05:59:17

Svelte前端框架

2010-09-01 11:43:06

KickstartPXE無人值守

2024-10-28 00:01:00

2010-06-21 10:42:50

BitTorrent協

2009-11-06 09:22:46

WCF應用

2021-08-16 09:59:52

ReactSvelte開發

2023-06-24 22:14:23

2017-12-06 16:28:48

Synchronize實現原理

2014-06-06 09:01:07

DHCP

2024-12-23 15:05:29

2012-05-10 13:42:26

Java網絡爬蟲

2010-08-31 19:53:25

DHCP功能

2022-06-03 09:21:47

Svelte前端攜程
點贊
收藏

51CTO技術棧公眾號

国产91在线播放精品91| 亚洲国产精品va在线看黑人| 一区二区不卡在线观看| 国产视频第二页| 日韩午夜黄色| 中文字幕亚洲欧美在线| 久久久无码人妻精品无码| 午夜裸体女人视频网站在线观看| 中文文精品字幕一区二区| 99精品国产一区二区| 日韩精品一区二区亚洲av| 性欧美69xoxoxoxo| 亚洲精品一区中文| 一级片黄色免费| 亚洲天堂一区二区| 一区二区在线观看免费| 欧洲精品在线一区| 亚洲欧美高清视频| 久久99久久99精品免视看婷婷| 久久久久久这里只有精品| 九一在线免费观看| 日本午夜精品久久久| 91精品在线麻豆| 欧美私人情侣网站| 波多野结衣在线观看| 欧美高清在线视频| 久久综合九色欧美狠狠| www.国产三级| 国产资源精品在线观看| 日韩免费中文字幕| 男人的天堂一区二区| 一区二区日韩欧美| 中文字幕亚洲一区在线观看| 女人被狂躁c到高潮| 日韩三级不卡| 欧美高清视频不卡网| 国产又黄又猛视频| 色戒汤唯在线观看| 亚洲午夜视频在线观看| 国产对白在线播放| 日本最新在线视频| 欧美激情一区二区三区四区| 免费在线一区二区| 深爱激情五月婷婷| 成人高清在线视频| 不卡一区二区三区四区五区| 国产精品毛片久久久久久久av| 国产色综合网| 2019中文字幕免费视频| 国产 日韩 欧美 成人| 欧美 亚欧 日韩视频在线| 日韩亚洲第一页| 国产破处视频在线观看| 波多野结衣在线播放一区| 亚洲热线99精品视频| 性久久久久久久久久| 五月综合久久| 亚洲欧美综合v| 国产亚洲精品熟女国产成人| 精品美女视频| 中文字幕日韩电影| 国产黄a三级三级| 欧美电影免费观看高清| 久久久99免费视频| 成年人av电影| 欧美色123| 97碰在线观看| chinese国产精品| 日韩va亚洲va欧美va久久| 国产精品久久在线观看| 在线观看毛片网站| 狠狠网亚洲精品| 91超碰rencao97精品| 国产 欧美 精品| 久久综合av免费| 婷婷精品国产一区二区三区日韩| 欧美日韩欧美| 亚洲综合激情小说| 免费日韩中文字幕| 国产精品传媒麻豆hd| 欧美男同性恋视频网站| 国产精品偷伦视频免费观看了| 欧美成a人免费观看久久| 日韩毛片中文字幕| 国产精品综合激情| 欧美日韩一卡| 青青草成人在线| 在线免费观看av片| 高清国产一区二区| 日韩精品一区二区三区四区五区| 日本在线观看免费| 亚洲成av人影院| 国产精品视频黄色| 亚洲一区二区免费在线观看| 国产丝袜一区二区三区| 中文字幕精品亚洲| 亚洲国产日本| 国产一区二区在线免费视频| 狠狠综合久久av一区二区| 久久久久久亚洲综合影院红桃| 一区二区三区我不卡| 岛国在线视频网站| 欧美福利视频导航| 欧美亚一区二区三区| 久久精品青草| 国产精品91久久久久久| 精品人妻一区二区三区麻豆91| 久久综合国产精品| 欧美a级免费视频| 日韩国产网站| 亚洲护士老师的毛茸茸最新章节| 五月天免费网站| 亚洲一区二区网站| 99久久99| 成年人黄视频在线观看| 91久久香蕉国产日韩欧美9色| 91精产国品一二三| 欧美激情偷拍自拍| 热re91久久精品国99热蜜臀| a在线观看免费| 中文字幕欧美激情一区| 欧美在线观看成人| 1769国产精品视频| 不卡av电影院| 在线播放一级片| 久久久99免费| 免费成人午夜视频| 99ri日韩精品视频| 久热精品视频在线| 一本色道久久综合亚洲| 久久久久综合网| 99999精品视频| 欧美黑白配在线| 欧美黄色成人网| a天堂视频在线| 亚洲日本韩国一区| 性久久久久久久久久久久久久| 狠狠做深爱婷婷综合一区| 欧洲精品在线视频| 亚洲欧美日本在线观看| 亚洲第一搞黄网站| 国产艳妇疯狂做爰视频| 欧美日本久久| 999日本视频| 婷婷色在线资源| 日韩欧美你懂的| 麻豆精品一区二区三区视频| 国产精品一二一区| 粉嫩av一区二区三区天美传媒| 国产精品久久久久久久久久久久久久久 | 91porn在线视频| 国产在线日韩欧美| 久久av喷吹av高潮av| 国产一区二区三区免费观看在线 | 午夜精品久久久久久久久久蜜桃| 日韩经典中文字幕| 久久国产视频精品| 久久精品一区二区三区不卡| 免费看a级黄色片| 日韩欧美在线中字| 成人免费视频网| 青青草视频在线免费直播| 欧美成人精品二区三区99精品| 久久黄色小视频| 99久久婷婷国产综合精品电影 | 久草精品在线观看| 亚洲av综合色区| 中文无码日韩欧| 亚州国产精品久久久| 日本在线视频1区| 欧美在线小视频| 日韩欧美综合视频| 成人激情午夜影院| 无码精品国产一区二区三区免费| 欧美日韩一二| 亚洲在线免费观看| 久久久男人天堂| 色系列之999| www.天堂在线| 色婷婷av一区二区三区之一色屋| 久久午夜精品视频| 国产精品一区二区91| 亚洲自偷自拍熟女另类| 97久久夜色精品国产| 国产66精品久久久久999小说| 亚洲精品中文字幕| 最新日韩中文字幕| 天堂在线观看免费视频| 色乱码一区二区三区88| 四虎精品免费视频| 99久久精品一区| 天天色天天综合网| 销魂美女一区二区三区视频在线| 亚洲精品久久区二区三区蜜桃臀| 一区中文字幕电影| 国产精品扒开腿做| 色网在线观看| 中文字幕久久精品| 黄色片一区二区三区| 欧美性做爰猛烈叫床潮| 国产一级理论片| 国产精品福利影院| 亚洲制服丝袜在线播放| 另类成人小视频在线| 久久成人免费观看| 欧美成人69av| 亚洲日本精品| 一区二区美女| 国产成人成网站在线播放青青| 91大神在线观看线路一区| 久久久久久久亚洲精品| 黄色网页在线观看| 亚洲日韩第一页| 日本激情一区二区| 在线播放国产精品二区一二区四区| 天堂中文字幕在线观看| 亚洲自拍与偷拍| 日本黄色片免费观看| 国产无人区一区二区三区| 欧美做受高潮中文字幕| 国内成+人亚洲+欧美+综合在线| 99热成人精品热久久66| 亚洲激情女人| 国产天堂视频在线观看| 91tv精品福利国产在线观看| 日韩欧美激情一区二区| 少妇久久久久| 狠狠干一区二区| 99久热这里只有精品视频免费观看| 国产在线视频一区| 国产精品久久久久久久久免费高清 | 一区二区日本| 成人毛片在线| 欧美性xxxx69| 亚洲丝袜啪啪| 免费电影一区| 日韩高清三区| 久久天堂国产精品| 香蕉精品久久| 免费毛片一区二区三区久久久| 你懂的在线观看一区二区| 国产伦视频一区二区三区| 凹凸成人在线| 国产视频在线观看一区| 伦理一区二区| 久久久久久高清| 伊人久久大香线蕉| 日韩视频在线播放| 成人激情开心网| 亚洲日本japanese丝袜| 偷拍欧美精品| 青青在线视频免费观看| 狠狠爱成人网| 五月丁香综合缴情六月小说| 亚洲精品少妇| 黄色免费观看视频网站| 久久综合五月| 欧美大尺度做爰床戏| 久久se这里有精品| 超碰在线超碰在线| 成人精品视频一区| 国产精品边吃奶边做爽| 久久免费午夜影院| 色偷偷男人天堂| 亚洲免费在线视频| 日本午夜小视频| 色域天天综合网| 影音先锋国产在线| 日韩一区二区三区精品视频| 风流老熟女一区二区三区| 日韩精品免费在线视频| 成年人在线观看网站| 操91在线视频| 免费看男女www网站入口在线| 国产成人在线一区| 91成人app| 精品国产综合久久| 日本大胆欧美| 91亚洲精品国产| 天堂久久一区二区三区| 色偷偷中文字幕| 久久综合一区二区| 懂色av粉嫩av蜜臀av一区二区三区| 亚洲综合色区另类av| 无码人妻精品一区二区| 91麻豆精品国产自产在线观看一区| 风流老熟女一区二区三区| 亚洲性av在线| av影院在线| 成人福利视频网| 四虎5151久久欧美毛片| 一本—道久久a久久精品蜜桃| 99精品视频网| 色18美女社区| 久久一区二区三区四区| 无码人妻精品一区二区三区夜夜嗨| 欧美性少妇18aaaa视频| 中文字幕在线一| 亚洲高清在线观看| 看黄网站在线| 国产xxx69麻豆国语对白| 亚洲天堂中文字幕在线观看| 日韩中文一区| 亚洲深爱激情| 国模大尺度视频| 国产精品女上位| 六月丁香激情综合| 欧美成人三级在线| 啊v视频在线| 45www国产精品网站| 一区二区在线免费播放| 伊人久久青草| 久色成人在线| 日韩少妇一区二区| 亚洲免费三区一区二区| 性色av一区二区三区四区| 日韩精品视频三区| 国产精品186在线观看在线播放| 国产区精品在线观看| 国产一区二区亚洲| 国产精品50p| 成人激情小说乱人伦| 欧美爱爱小视频| 正在播放亚洲一区| 婷婷在线视频| 国产精品视频一区国模私拍 | 香蕉视频在线网址| 日韩av不卡一区二区| 成年人免费观看视频网站| 亚洲高清久久久| 亚洲va久久久噜噜噜无码久久| 日韩视频欧美视频| 日韩成人免费av| 日韩av高清在线播放| 国产视频一区三区| 国产精久久久久| 亚洲一区中文在线| 国产高清精品软件丝瓜软件| 久久亚洲国产成人| 24小时成人在线视频| 免费久久久久久| 精品一区二区三区久久| 国产7777777| 欧美美女直播网站| 黄网站免费在线播放| 成人激情视频在线播放| 色欧美自拍视频| 污污的视频免费观看| 亚洲三级久久久| 99国产精品一区二区三区| 欧美理论片在线观看| 99ri日韩精品视频| 国产视频九色蝌蚪| 91视频国产资源| 波多野结衣视频在线观看| 中文欧美日本在线资源| 综合欧美精品| 久久综合久久网| 26uuu色噜噜精品一区二区| 久久人妻免费视频| 中文字幕亚洲一区二区三区五十路| 亚洲欧美综合久久久久久v动漫| www亚洲国产| www.亚洲激情.com| 亚洲成人av影片| 精品国产一区二区三区四区在线观看 | 精品欧美一区二区三区| 免费在线性爱视频| 国产精品一区二区三区免费视频| 久久精品高清| 亚洲一二三四五| 一本大道久久a久久综合婷婷| 1769视频在线播放免费观看| 91视频免费网站| 亚洲激情午夜| 你懂得视频在线观看| 日韩欧美一区二区三区在线| av中文资源在线资源免费观看| 欧美三级电影在线播放| 国内一区二区在线| 日产亚洲一区二区三区| 中文字幕精品一区二区精品| 香蕉成人app| 国语对白做受xxxxx在线中国| 1000精品久久久久久久久| 欧美自拍偷拍第一页| 国产精品成熟老女人| 影视亚洲一区二区三区| 成人影视免费观看| 91精品国产91久久综合桃花| 亚洲精品福利电影| 亚洲爆乳无码精品aaa片蜜桃| 久久品道一品道久久精品| 国产白浆在线观看| 国产成人精品久久久| 欧美99在线视频观看| 韩国女同性做爰三级| 亚洲第一页中文字幕| 24小时成人在线视频| 日本www高清视频|