新聞中心
1.寫在前面
2.框架設(shè)計里到處都體現(xiàn)了權(quán)衡的藝術(shù)
作者在文章中寫到『框架設(shè)計里到處都體現(xiàn)了權(quán)衡的藝術(shù)』,的確在進行設(shè)計模式和技術(shù)選型的時候,我們都會去綜合考慮性能和開發(fā)效率,去權(quán)衡各方面因素從而得到盡可能完善的框架。

讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:申請域名、虛擬主機、營銷軟件、網(wǎng)站建設(shè)、余江網(wǎng)站維護、網(wǎng)站推廣。
框架是由各個模塊組成的,彼此關(guān)聯(lián)又相互獨立,要做到實現(xiàn)當(dāng)前的功能,又要考慮到后續(xù)的模塊拆分和拓展。作為框架的設(shè)計者,需要站在全局的角度去思考和設(shè)計,需要對整體的設(shè)計思路有著清晰的掌控。實現(xiàn)細節(jié)是在設(shè)計的時候不用太過于在意的視點,不要囿于高山的霧層,畢竟它只是整個框架的冰山一角。
在Vue框架的設(shè)計中,最能體現(xiàn)這種權(quán)衡思想的可能是『命令式和聲明式』、『編譯時和運行時』等之間的權(quán)衡,需要了解彼此的差異、汲取兩者的優(yōu)點。
3.命令式和聲明式
正如你所知道的,在計算機編程范式中有三種:命令式編程,聲明式編程和函數(shù)式編程。
命令式編程:是關(guān)注計算機執(zhí)行的步驟,即一步一步告訴計算機先做什么再做什么。
聲明式編程:以數(shù)據(jù)結(jié)構(gòu)的形式來表達程序執(zhí)行的邏輯。它的主要思想是告訴計算機應(yīng)該做什么,但不指定具體要怎么做。
函數(shù)式編程:是與聲明式編程關(guān)聯(lián)的,只關(guān)注做什么而不是怎么做。但函數(shù)式編程不僅僅局限于聲明式編程。
命令式
對于前端開發(fā)從業(yè)者而言,JQuery框架并不會陌生,它其實就是最經(jīng)典的命令式的框架設(shè)計,它關(guān)注計算機執(zhí)行的步驟,即關(guān)注過程。命令式編程其實就是寫給計算機看的,讓我們的自然語言能與代碼進行一一對應(yīng),更符合我們做事邏輯。
$("#app")//獲取id為app的標簽元素
.text("hello pingping")//設(shè)置標簽的文本內(nèi)容
.on("click",()=>console.log("hello onechuan"));//給id為app的便簽綁定事件等價于原生js的代碼:
const div = document.querySelector("#app");
div.innerText = "hello pingping";
div.addEventListener("click",()=>console.log("hello onechuan"))
聲明式
而聲明式更關(guān)注實現(xiàn)結(jié)果,具體的實現(xiàn)過程并不是使用者所在意的,這也很大程度地降低了認知成本,關(guān)注表層邏輯提升使用效率。
事實上,Vue.js的設(shè)計并不是簡單使用純粹的命令式或是聲明式編程,而是結(jié)合兩者的優(yōu)點。在內(nèi)部實現(xiàn)使用命令式告知計算機如何運行,對外暴露的API等則是采用的聲明式編程,能夠用人話讓使用者讀懂結(jié)果。
console.log('hello onechuan')">hello pingping性能和可維護性
在《編譯原理》書中,了解到命令式代碼的性能優(yōu)于聲明式代碼,這是因為聲明式代碼需要經(jīng)過編譯成計算機能夠讀懂的命令式代碼。但是呢,聲明式代碼更像是人類能夠讀懂的人話,在盡可能犧牲少量性能的同時降低代碼的維護成本。
Vue.js框架就是結(jié)合兩者的優(yōu)點,對命令式代碼進行了封裝,對使用者提供可維護性更高的聲明式代碼。
4.真實DOM和虛擬DOM
對于聲明式代碼的更新性能消耗而言:聲明式代碼的更新性能消耗 = 找出差異的性能消耗 + 直接修改的性能消耗,如果我們找到能夠讓找出差異的性能消耗最小化的算法,那么就能夠?qū)⒙暶魇酱a的性能消耗無限趨近于命令式代碼性能消耗。
我們分別從創(chuàng)建頁面和更新頁面兩方面,對真實DOM和虛擬DOM操作的性能消耗進行分析:
狀態(tài)
虛擬DOM(純JS創(chuàng)建VNODE)
真實DOM(渲染HTML字符串)
創(chuàng)建頁面
新建所有的DOM對象
新建所有的DOM對象
更新頁面
必要的DOM更新
-銷毀所有的舊DOM,新建所有的新DOM
關(guān)于性能:真實DOM<虛擬DOM<原生JS。
此處簡要的進行總結(jié),后續(xù)文章將會有更詳細的數(shù)據(jù)分析。
5.編譯時和運行時
在框架設(shè)計時還要考慮是選擇:純運行時、純編譯時還是運行時+編譯時,這需要結(jié)合你所期望的待設(shè)計框架的特征做出合適的決策。
運行時
所謂運行時,就是計算機所運行時的代碼,不需要經(jīng)歷額外的處理,便能夠?qū)崿F(xiàn)我們所期許的結(jié)果。
例如,我們需要將提供的樹形結(jié)構(gòu)的數(shù)據(jù)對象,渲染到渲染成dom樹,那么我們需要設(shè)計一個Render函數(shù)直接進行渲染,這樣就能得到我們想要的結(jié)果:
const obj = {
tag:"div",
children:[{
tag:"span",
children:"hello world"
}]
}
Render(obj, document.body)
function Render(obj, root){
const el = document.createElement(obj.tag);
if(typeof obj.children === "string"){
const text = document.createTextNode(obj.children);
el.appendChild(text)
}else if(obj.children){
// 如果是數(shù)組,就進行遞歸調(diào)用render,使用el作為root參數(shù)
obj.children.forEach(child=>Render(child, el))
}
// 最后將元素添加到根元素
root.appendChild(el)
}瀏覽器顯示如下:
編譯時
那么,編譯就是一種轉(zhuǎn)換技術(shù),將高級語言轉(zhuǎn)換低級語言,Vue.js將HTML標簽通過編譯轉(zhuǎn)換成樹形結(jié)構(gòu)的數(shù)據(jù)對象。
這樣我們需要編寫一個Compiler函數(shù),用于將HTML標簽通過編譯換成樹形結(jié)構(gòu)的數(shù)據(jù)對象。如下:
const html = ``
hello world
const obj = compoler(html)
Render(obj, document.body)這樣就能將:
hello pingping編譯成:
const obj = {
tag: 'div',
children: [
{tag: 'span', children: 'hello world'}
]
}結(jié)合Render函數(shù)進行渲染,這樣我們就初步設(shè)計了一個運行時+編譯時的框架了。
運行時+編譯時
所謂在Vue.js是運行時+編譯時框架,其實指的是:
支持運行時:使用者可以直接提供樹形結(jié)構(gòu)的數(shù)據(jù)對象而無需編譯;
支持編譯時:使用者可以提供HTML字符串,將其編譯成樹形結(jié)構(gòu)的數(shù)據(jù)對象后再交給運行時處理。
為什么Vue.js要設(shè)計成運行時+編譯時框架?
這所以這樣設(shè)計也是開源團隊進行權(quán)衡的結(jié)果,運行時無法分析用戶提供的內(nèi)容,而加入編譯后就可以對用戶內(nèi)容進行分析和編譯。在編譯的時候提取這些用戶內(nèi)容的信息,再通過Render函數(shù)進行渲染。
當(dāng)然,將框架設(shè)計成純編譯時,可以分析用戶內(nèi)容直接編譯成可執(zhí)行的JS代碼,在保證性能的同時犧牲了框架的靈活性和可維護性,對用戶而言必須對內(nèi)容編譯后才能使用。
對此,Vue.js的設(shè)計是綜合考量,才用的運行時+編譯時的框架設(shè)計,在保留運行時的靈活性的同時,盡可能不犧牲性能。
6.寫在最后
在本文中,了解到開源團隊對于命令式和聲明式、真實DOM和虛擬DOM、運行時和編譯時的權(quán)衡選擇,在盡可能減少性能損耗的同時提供最好的用戶體驗和可維護性、靈活性。
網(wǎng)站標題:Vue.js設(shè)計與實現(xiàn)之權(quán)衡的藝術(shù)
文章分享:http://m.5511xx.com/article/cogejoo.html


咨詢
建站咨詢
