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

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


咨詢(xún)
建站咨詢(xún)
