偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

震驚,使用imba框架,得到比 vue 快50倍的性能基準(zhǔn)

開(kāi)發(fā) 前端
imba 是一種新的編程語(yǔ)言,可以編譯為高性能的 JavaScript??梢灾苯佑糜?Web 編程(服務(wù)端與客戶端)開(kāi)發(fā)。

 我是標(biāo)題黨嗎?是,但也不是。以圖為證。

上圖表示了vue, react 以及 imba 在 todo 這個(gè)項(xiàng)目中擁有60個(gè) todoItem 不同進(jìn)行 crud 操作的表現(xiàn)??梢钥吹?imba 達(dá)到了每秒操作5w次以上。如果你也想試一試該測(cè)試,可以訪問(wèn) Todos Bench。測(cè)試使用的是 Benchmark.js。

imba 簡(jiǎn)單介紹

imba 是一種新的編程語(yǔ)言,可以編譯為高性能的 JavaScript??梢灾苯佑糜?Web 編程(服務(wù)端與客戶端)開(kāi)發(fā)。

下面是語(yǔ)法: 

  1. // 自定義標(biāo)簽  
  2. tag App  
  3.     // 屬性  
  4.     prop items  
  5.     // 方法定義  
  6.     def addItem  
  7.         if @input.value  
  8.             items.push(title: @input.value)  
  9.             @input.value = ""  
  10.     def toggleItem item  
  11.         item:completed = !item:completed  
  12. // 掛載 Imba.mount(element, into)   
  13. // 如果沒(méi)有第二個(gè)參數(shù),默認(rèn)掛載到 document.body 上面  
  14. Imba.mount <App.vbox items=[] ->  
  15.     <form.bar :submit.prevent.addItem>  
  16.         <input@input>  
  17.         <button> 'add'  
  18.     <ul> for item in items  
  19.         <li .done=item:completed :tap.toggleItem(item)> item:title 

可以看出作者喜歡 ruby 以及 pug,偏向于縮進(jìn)類風(fēng)格(個(gè)人并不是很喜歡這種語(yǔ)法風(fēng)格)。具體語(yǔ)法可以參考 imba 文檔。當(dāng)然了,因?yàn)榭梢跃幾g成js,所以服務(wù)端編譯成 js 進(jìn)行node開(kāi)發(fā)也是可以實(shí)現(xiàn)的。

imba 框架極速的性能基礎(chǔ)

任何一個(gè)實(shí)現(xiàn)的性能優(yōu)化都有其理論基礎(chǔ),那么 imba 性能那么快的基礎(chǔ)究竟是什么呢?答案也就是 memoized DOM(記憶DOM)。

理論基礎(chǔ)

瀏覽器的 DOM 操作可以說(shuō)是瀏覽器最終要的功能,無(wú)論框架是基于虛擬 DOM 或者是真實(shí) DOM,最終離不開(kāi)操作 DOM 對(duì)象。

HTML DOM 是瀏覽器定義了訪問(wèn)和操作 HTML 文檔的標(biāo)準(zhǔn)方法。但是操作 DOM 的接口是 JavaScript。但是瀏覽器通常會(huì)把 js 引擎和渲染引擎分開(kāi)實(shí)現(xiàn)。也就是頁(yè)面實(shí)際渲染部分是和解析js部分分開(kāi)的。 借著《高性能的 JavaScript》話說(shuō),如果把 DOM 和 js 各自想象為島嶼。他們需要一座橋進(jìn)行溝通。所以每一次執(zhí)行 DOM 操作就過(guò)橋一次。

那我們先談?wù)勌摂MDOM,虛擬DOM 的性能提升在于是將 DOM 的對(duì)比放在了js層。進(jìn)而通過(guò)對(duì)比不同之處來(lái)進(jìn)行實(shí)際的 DOM 渲染。也就是說(shuō),其實(shí)虛擬DOM 并沒(méi)有“實(shí)際”的性能收益,橋仍舊還在那邊。僅僅在 js引擎需要過(guò)橋的那邊找到了一位聰明睿智的大叔,對(duì)過(guò)橋的人和過(guò)橋的貨物進(jìn)行優(yōu)化和限制(虛擬DOM 高性能的diff算法,狀態(tài)批量更新)。

那么 memoized DOM 又是怎么做的呢?把 DOM 節(jié)點(diǎn)的控制直接放入內(nèi)存之中。類似于此類優(yōu)化。 

  1. function getEls(sel) {  
  2.     // 設(shè)置緩存  
  3.     if (!getEls.cache) getEls.cache = {};    
  4.     // 如果緩存中存在 el,直接返回   
  5.     if (getEls.cache[sel]) {  
  6.         return getEls.cache[sel];  
  7.     }  
  8.     // 沒(méi)有去通過(guò) DOM 查詢  
  9.     const r = document.querySelectorAll(sel || '☺'),  
  10.         length = r.length;    
  11.     // 緩存并返回元素節(jié)點(diǎn)  
  12.     return getEls.cache[sel] = (length == 1) ? r[0] : r;  

我們可以測(cè)試一下。這里我寫一個(gè) getElsByDocument 以及 simplePerTest。 

  1. // 直接通過(guò) querySelectorAll 獲取節(jié)點(diǎn)  
  2. function getElsByDocument(sel) {  
  3.     const r = document.querySelectorAll(sel || '☺'),  
  4.         length = r.length;  
  5.     return length == 1 ? r[0] : r;  
  6.  
  7. // 簡(jiǎn)單性能測(cè)試  
  8. function simplePerTest(fn, el) {  
  9.     const fnfnName = fn.name  
  10.     console.time(fnName)    
  11.     // 2000 次操作  
  12.     for(let i = 0,len = 2000; i < len; i++) {  
  13.         fn(el)  
  14.     }  
  15.     console.timeEnd(fnName)  

這個(gè)緩存的節(jié)點(diǎn)查詢可要比 querySelectorAll 快了 140倍以上啊,隨著 img 節(jié)點(diǎn)越多,得到的性能提升也越高啊。如果imba 框架中所有的節(jié)點(diǎn)都在內(nèi)存中呢?同時(shí),我們還會(huì)得到一個(gè) js 運(yùn)行時(shí)優(yōu)化( GC 的大量減少),因?yàn)樘摂MDOM 要維護(hù)一個(gè)樹(shù),在進(jìn)行多次 crud 之后就會(huì)產(chǎn)生大量無(wú)用對(duì)象從而導(dǎo)致瀏覽器進(jìn)行 GC,而 memoized DOM 在多次 crud 不會(huì)進(jìn)行多次 GC。(可能會(huì)在渲染引擎中 GC?但我感覺(jué)渲染引擎中GC 要比JS 中影響要小很多。挖個(gè)坑,研究完渲染引擎再來(lái)探討一下)

框架實(shí)踐

實(shí)例如下所示: 

  1. tag Component  
  2.     def render  
  3.         <self>  
  4.             <h1.title> "Welcome"  
  5.             <p.desc> "I am a component" 

上面的自定義組件會(huì)編譯成下面的js: 

  1. var Component = Imba.defineTag('Component', function(tag){  
  2.     tag.prototype.render = function (){  
  3.         var $ = this.$;  
  4.         // 返回dom  
  5.         return this.setChildren($.$ = $.$ || [  
  6.             createElement('h1',$,0,this).flag('title').setText("Welcome"),  
  7.             createElement('p',$,1,this).flag('desc').setText("I am a component")  
  8.         ]).synced();  
  9.     };  
  10. }); 

仔細(xì)觀察一下這里的函數(shù),你會(huì)看到該組件在***次調(diào)用渲染時(shí),將使用 createElement 創(chuàng)建兩個(gè)子節(jié)點(diǎn),并設(shè)置它們的屬性并且緩存。第二次或者***萬(wàn)次調(diào)用時(shí),children-array將被緩存,不會(huì)發(fā)生任何調(diào)用。 

  1. // 在***次調(diào)用時(shí)候 $.$不存在  $.$會(huì)等于 后面的數(shù)組  
  2. // 第二次調(diào)用 $.$ 是存在的,無(wú)運(yùn)行時(shí)消耗  
  3. $.$ = $.$ || 數(shù)組 

其中查看源碼,我們可以看到 setChildren 函數(shù)都是對(duì)真實(shí)DOM 進(jìn)行了操作。獲取之前的DOM節(jié)點(diǎn)進(jìn)行一系列操作后將當(dāng)前節(jié)點(diǎn)返回并緩存。 

  1. tag.prototype.setChildren = function (new$,typ){  
  2.     var old = this._tree_;    
  3.     if (new$ === old && (!(new$) || new$.taglen == undefined)) {  
  4.         return this;  
  5.     };  
  6.     if (!old && typ != 3) {  
  7.         this.removeAllChildren();  
  8.         appendNested(this,new$);  
  9.     } else if (typ == 1) {  
  10.         var caret = null 
  11.         for (var i = 0items = iter$(new$), len = items.length; i < len; i++) {  
  12.             caret = reconcileNested(this,items[i],old[i],caret);  
  13.         };  
  14.     } else if (typ == 2) {  
  15.         return this;  
  16.     } else if (typ == 3) {  
  17.         var ntyp = typeof new$;         
  18.          if (ntyp != 'object') {  
  19.             return this.setText(new$);  
  20.         };           
  21.          if (new$ && new$._dom) {  
  22.             this.removeAllChildren();  
  23.             this.appendChild(new$);  
  24.         } else if (new$ instanceof Array) {  
  25.             if (new$._type == 5 && old && old._type == 5) {  
  26.                 reconcileLoop(this,new$,old,null);  
  27.             } else if (old instanceof Array) {  
  28.                 reconcileNested(this,new$,old,null);  
  29.             } else {  
  30.                 this.removeAllChildren();  
  31.                 appendNested(this,new$);  
  32.             };  
  33.         } else {  
  34.             return this.setText(new$);  
  35.         };  
  36.     } else if (typ == 4) {  
  37.         reconcileIndexedArray(this,new$,old,null);  
  38.     } else if (typ == 5) {  
  39.         reconcileLoop(this,new$,old,null);  
  40.     } else if ((new$ instanceof Array) && (old instanceof Array)) {  
  41.         reconcileNested(this,new$,old,null);  
  42.     } else {  
  43.         // what if text?  
  44.         this.removeAllChildren();  
  45.         appendNested(this,new$);  
  46.     };    
  47.     this._tree_ = new$;  
  48.     return this;  
  49. }; 

如果我們使用了動(dòng)態(tài)屬性。代碼如下: 

  1. tag Component  
  2.     def render  
  3.         <self>  
  4.             <h1.title> "Welcome"  
  5.             # 有 50% 幾率 擁有 red class  
  6.             <p.desc .red=(Math.random > 0.5)> "IMBA" 

可以得到如下代碼,詳細(xì)查看可以看出,imba 提取了可變量,放入了 synced 函數(shù)中,每次渲染中只會(huì)執(zhí)行 synced 里面的數(shù)據(jù),所以依然會(huì)得到極高的渲染速度。 

  1. var Component = Imba.defineTag('Component', function(tag){  
  2.     tag.prototype.render = function (){  
  3.         var $ = this.$;  
  4.         return this.setChildren($.$ = $.$ || [  
  5.             _1('h1',$,0,this).flag('title').setText("Welcome"),  
  6.             _1('p',$,1,this).flag('desc').setText("Roulette")  
  7.         ],2).synced((  
  8.             $[1].flagIf('red',Math.random() > 0.5)  
  9.         ,true));  
  10.     };  
  11. }); 

精確的抽取不可變量,然后無(wú)需虛擬DOM 計(jì)算,同時(shí)對(duì)于真實(shí)DOM 還進(jìn)行了緩存,我們可以看出 memoized DOM 與 虛擬DOM 不同,memoized DOM 是具有實(shí)際的性能收益。

imba 框架“虛假”的性能測(cè)試

我們?cè)谏厦婵吹搅?imba 框架的理論基礎(chǔ),那么他是否真的比vue快50倍?當(dāng)然不是,這也就是在上面說(shuō)我是標(biāo)題黨的原因。

瀏覽器的運(yùn)行機(jī)制

瀏覽器本身只能達(dá)到 60 fps( 1 秒刷新了60次 )。當(dāng)然了,其實(shí)對(duì)于體驗(yàn)而言,60fps的體驗(yàn)已經(jīng)差不多夠用了,也就是瀏覽器渲染上大概需要 17ms 去渲染一次。事實(shí)上無(wú)論是每秒操作dom 5w次還是 1000次,瀏覽器渲染引擎也只會(huì)記錄當(dāng)前的臟數(shù)據(jù)。然后在需要渲染時(shí)候再進(jìn)行重繪與重排。

真實(shí)世界的內(nèi)存限制

面對(duì) memoized DOM 的緩存優(yōu)化以及更少 GC 帶來(lái)的運(yùn)行時(shí)提升,我們需要更多內(nèi)存來(lái)對(duì)每一個(gè) dom節(jié)點(diǎn)進(jìn)行緩存。這個(gè)在初始化渲染時(shí)有大量的消耗。同時(shí)我們的瀏覽器執(zhí)行速度和渲染速度已經(jīng)足夠快了,虛擬DOM已經(jīng)完全夠用了。

imba 框架與瀏覽器的暢想

Google io 大會(huì) chorme Portals 技術(shù)

單頁(yè)應(yīng)用程序(Single Page Applications,SPA)提供了很好的頁(yè)面交互,但代價(jià)是構(gòu)建的復(fù)雜性更高,多頁(yè)面應(yīng)用程序(Multi-page Applications,MPA)更容易構(gòu)建,但最終會(huì)在頁(yè)面之間出現(xiàn)空白屏幕。

Portals 結(jié)合了這兩者的優(yōu)勢(shì),主要用于改進(jìn)網(wǎng)頁(yè)交互體驗(yàn),目標(biāo)是無(wú)縫導(dǎo)航。它類似于 iframe ,內(nèi)嵌在網(wǎng)頁(yè)上,但可以導(dǎo)航到頁(yè)面內(nèi)容上。用戶在一個(gè)頁(yè)面跳轉(zhuǎn)另一個(gè)內(nèi)容時(shí),雖然 URL 相應(yīng)地發(fā)生變化,但是不需要打開(kāi)另一個(gè)窗口,此時(shí)該內(nèi)容標(biāo)記的 Portals 會(huì)變成原來(lái)頁(yè)面的***頁(yè)面,同時(shí)原來(lái)頁(yè)面在其后保持主進(jìn)程地位?,F(xiàn)場(chǎng)演示了這對(duì)于購(gòu)物體驗(yàn)的極大便利,此外還有對(duì)漫畫這類單頁(yè)面應(yīng)用的演示。

[[268439]]

js引擎 與 渲染引擎的關(guān)聯(lián)

在之前,瀏覽器 js引擎和渲染引擎是沒(méi)有任何關(guān)聯(lián)的,我們?nèi)憚?dòng)畫只能通過(guò) setTimeout 或者 setInterval,更加沒(méi)有辦法知道瀏覽器什么時(shí)候處于空閑狀態(tài),但是隨著時(shí)間的發(fā)展,我們可以通過(guò) requestAnimationFrame 和 requestIdleCallback。requestAnimationFrame 要求瀏覽器在下次重繪之前調(diào)用指定的回調(diào)函數(shù)更新動(dòng)畫。requestIdleCallback方法將在瀏覽器的空閑時(shí)段期間對(duì)要調(diào)用的隊(duì)列函數(shù)進(jìn)行執(zhí)行。

那么內(nèi)置DOM 操作是否能夠在js引擎中,是否能夠減少過(guò)橋的性能消耗或者完全把橋打通。讓我們拭目以待。

鼓勵(lì)一下

如果你覺(jué)得這篇文章不錯(cuò),希望可以給與我一些鼓勵(lì),在我的 github 博客下幫忙 star 一下。 博客地址:https://github.com/wsafight/personBlog

 

責(zé)任編輯:龐桂玉 來(lái)源: 中國(guó)IDC圈
相關(guān)推薦

2022-06-08 09:20:58

Python基準(zhǔn)測(cè)試編程語(yǔ)言

2022-10-27 08:31:31

架構(gòu)

2021-05-06 10:52:09

Java Spring Bo框架

2024-03-26 10:13:54

日志引擎SigLens

2021-08-03 06:57:36

Protocol Bu平臺(tái)Json

2023-04-07 08:17:39

fasthttp場(chǎng)景設(shè)計(jì)HTTP

2022-04-26 15:24:03

開(kāi)源框架

2012-07-31 09:02:49

Apworks

2021-01-04 09:58:46

5G6G運(yùn)營(yíng)商

2019-10-14 09:50:52

KeyDBRedis中間件

2021-07-28 14:20:13

正則PythonFlashText

2022-11-02 08:12:47

TurbopackVite

2015-11-25 14:39:51

LiFiWiFi

2021-06-11 09:21:20

開(kāi)源SQL Parser詞法語(yǔ)法分析器

2019-08-06 17:19:22

開(kāi)源技術(shù) 趨勢(shì)

2022-12-05 14:50:53

2024-03-08 07:58:13

QPShttpsync

2022-03-19 10:26:48

Linuxapt 命令

2020-02-09 16:18:45

Redis快 5 倍中間件

2011-06-29 09:31:58

3G4G5G
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)