成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

你不知道的Virtual DOM(一):Virtual Dom介紹

lavor / 2620人閱讀

摘要:不同的框架對(duì)這三個(gè)屬性的命名會(huì)有點(diǎn)差別,但表達(dá)的意思是一致的。它們分別是標(biāo)簽名屬性和子元素對(duì)象。我們先來看下頁面的更新一般會(huì)經(jīng)過幾個(gè)階段。元素有可能是數(shù)組的形式,需要將數(shù)組解構(gòu)一層。

歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:

一、前言

目前最流行的兩大前端框架,React和Vue,都不約而同的借助Virtual DOM技術(shù)提高頁面的渲染效率。那么,什么是Virtual DOM?它是通過什么方式去提升頁面渲染效率的呢?本系列文章會(huì)詳細(xì)講解Virtual DOM的創(chuàng)建過程,并實(shí)現(xiàn)一個(gè)簡單的Diff算法來更新頁面。本文的內(nèi)容脫離于任何的前端框架,只講最純粹的Virtual DOM。敲單詞太累了,下文Virtual DOM一律用VD表示。

這是VD系列文章的開篇,以下是本系列其它文章的傳送門:
你不知道的Virtual DOM(一):Virtual Dom介紹
你不知道的Virtual DOM(二):Virtual Dom的更新
你不知道的Virtual DOM(三):Virtual Dom更新優(yōu)化
你不知道的Virtual DOM(四):key的作用
你不知道的Virtual DOM(五):自定義組件
你不知道的Virtual DOM(六):事件處理&異步更新

二、VD是什么

本質(zhì)上來說,VD只是一個(gè)簡單的JS對(duì)象,并且最少包含tag、props和children三個(gè)屬性。不同的框架對(duì)這三個(gè)屬性的命名會(huì)有點(diǎn)差別,但表達(dá)的意思是一致的。它們分別是標(biāo)簽名(tag)、屬性(props)和子元素對(duì)象(children)。下面是一個(gè)典型的VD對(duì)象例子:

{
    tag: "div",
    props: {},
    children: [
        "Hello World", 
        {
            tag: "ul",
            props: {},
            children: [{
                tag: "li",
                props: {
                    id: 1,
                    class: "li-1"
                },
                children: ["第", 1]
            }]
        }
    ]
}

VD跟dom對(duì)象有一一對(duì)應(yīng)的關(guān)系,上面的VD是由以下的HTML生成的

Hello World
  • 第1

一個(gè)dom對(duì)象,比如li,由tag(li), props({id: 1, class: "li-1"})children(["第", 1])三個(gè)屬性來描述。

三、為什么需要VD

VD 最大的特點(diǎn)是將頁面的狀態(tài)抽象為 JS 對(duì)象的形式,配合不同的渲染工具,使跨平臺(tái)渲染成為可能。如 React 就借助 VD 實(shí)現(xiàn)了服務(wù)端渲染、瀏覽器渲染和移動(dòng)端渲染等功能。

此外,在進(jìn)行頁面更新的時(shí)候,借助VD,DOM 元素的改變可以在內(nèi)存中進(jìn)行比較,再結(jié)合框架的事務(wù)機(jī)制將多次比較的結(jié)果合并后一次性更新到頁面,從而有效地減少頁面渲染的次數(shù),提高渲染效率。我們先來看下頁面的更新一般會(huì)經(jīng)過幾個(gè)階段。

從上面的例子中,可以看出頁面的呈現(xiàn)會(huì)分以下3個(gè)階段:

JS計(jì)算

生成渲染樹

繪制頁面

這個(gè)例子里面,JS計(jì)算用了691毫秒,生成渲染樹578毫秒,繪制73毫秒。如果能有效的減少生成渲染樹和繪制所花的時(shí)間,更新頁面的效率也會(huì)隨之提高。
通過VD的比較,我們可以將多個(gè)操作合并成一個(gè)批量的操作,從而減少dom重排的次數(shù),進(jìn)而縮短了生成渲染樹和繪制所花的時(shí)間。至于如何基于VD更有效率的更新dom,是一個(gè)很有趣的話題,日后有機(jī)會(huì)將另寫一篇文章介紹。

四、如何實(shí)現(xiàn)VD與真實(shí)DOM的映射

我們先從如何生成VD說起。借助JSX編譯器,可以將文件中的HTML轉(zhuǎn)化成函數(shù)的形式,然后再利用這個(gè)函數(shù)生成VD??聪旅孢@個(gè)例子:

function render() {
    return (
        
Hello World
  • 第1
); }

這個(gè)函數(shù)經(jīng)過JSX編譯后,會(huì)輸出下面的內(nèi)容:

function render() {
    return h(
        "div",
        null,
        "Hello World",
        h(
            "ul",
            null,
            h(
                "li",
                { id: "1", "class": "li-1" },
                "u7B2C1"
            )
        )
    );
}

這里的h是一個(gè)函數(shù),可以起任意的名字。這個(gè)名字通過babel進(jìn)行配置:

// .babelrc文件
{
  "plugins": [
    ["transform-react-jsx", {
      "pragma": "h"    // 這里可配置任意的名稱
    }]
  ]
}

接下來,我們只需要定義h函數(shù),就能構(gòu)造出VD

function flatten(arr) {
    return [].concat.apply([], arr);
}

function h(tag, props, ...children) {
    return {
        tag, 
        props: props || {}, 
        children: flatten(children) || []
    };
}

h函數(shù)會(huì)傳入三個(gè)或以上的參數(shù),前兩個(gè)參數(shù)一個(gè)是標(biāo)簽名,一個(gè)是屬性對(duì)象,從第三個(gè)參數(shù)開始的其它參數(shù)都是children。children元素有可能是數(shù)組的形式,需要將數(shù)組解構(gòu)一層。比如:

function render() {
    return (
        
  • 0
  • { [1, 2, 3].map( i => (
  • {i}
  • )) }
); } // JSX編譯后 function render() { return h( "ul", null, h( "li", null, "0" ), /* * 需要將下面這個(gè)數(shù)組解構(gòu)出來再放到children數(shù)組中 */ [1, 2, 3].map(i => h( "li", null, i )) ); }

繼續(xù)之前的例子。執(zhí)行h函數(shù)后,最終會(huì)得到如下的VD對(duì)象:

{
    tag: "div",
    props: {},
    children: [
        "Hello World", 
        {
            tag: "ul",
            props: {},
            children: [{
                tag: "li",
                props: {
                    id: 1,
                    class: "li-1"
                },
                children: ["第", 1]
            }]
        }
    ]
}

下一步,通過遍歷VD對(duì)象,生成真實(shí)的dom

// 創(chuàng)建dom元素
function createElement(vdom) {
    // 如果vdom是字符串或者數(shù)字類型,則創(chuàng)建文本節(jié)點(diǎn),比如“Hello World”
    if (typeof vdom === "string" || typeof vdom === "number") {
        return doc.createTextNode(vdom);
    }

    const {tag, props, children} = vdom;

    // 1. 創(chuàng)建元素
    const element = doc.createElement(tag);

    // 2. 屬性賦值
    setProps(element, props);

    // 3. 創(chuàng)建子元素
    // appendChild在執(zhí)行的時(shí)候,會(huì)檢查當(dāng)前的this是不是dom對(duì)象,因此要bind一下
    children.map(createElement)
            .forEach(element.appendChild.bind(element));

    return element;
}

// 屬性賦值
function setProps(element, props) {
    for (let key in props) {
        element.setAttribute(key, props[key]);
    }
}

createElement函數(shù)執(zhí)行完后,dom元素就創(chuàng)建完并展示到頁面上了(頁面比較丑,不要介意...)。

五、總結(jié)

本文介紹了VD的基本概念,并講解了如何利用JSX編譯HTML標(biāo)簽,然后生成VD,進(jìn)而創(chuàng)建真實(shí)dom的過程。下一篇文章將會(huì)實(shí)現(xiàn)一個(gè)簡單的VD Diff算法,找出2個(gè)VD的差異并將更新的元素映射到dom中去:你不知道的Virtual DOM(二):Virtual Dom的更新

P.S.: 想看完整代碼見這里,如果有必要建一個(gè)倉庫的話請(qǐng)留言給我:代碼

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96981.html

相關(guān)文章

  • 你不知道Virtual DOM(二):Virtual Dom更新

    摘要:變化的只有種更新和刪除。頁面的元素的數(shù)量隨著而變。四總結(jié)本文詳細(xì)介紹如何實(shí)現(xiàn)一個(gè)簡單的算法,再根據(jù)計(jì)算出的差異去更新真實(shí)的。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 目前最流行的兩大前端框架,React 和 Vue,都不約而同的借助 Virtual DOM 技術(shù)提高頁面的渲染...

    testbird 評(píng)論0 收藏0
  • 你不知道Virtual DOM(四):key作用

    摘要:最后里面沒有第四個(gè)元素了,才會(huì)把蘋果從移除。四總結(jié)本文基于上一個(gè)版本的代碼,加入了對(duì)唯一標(biāo)識(shí)的支持,很好的提高了更新數(shù)組元素的效率。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 目前最流行的兩大前端框架,React和Vue,都不約而同的借助Virtual DOM技術(shù)提高頁面的渲染...

    DirtyMind 評(píng)論0 收藏0
  • 你不知道Virtual DOM(六):事件處理&異步更新

    摘要:如果列表是空的,則存入組件后將異步刷新任務(wù)加入到事件循環(huán)當(dāng)中。四總結(jié)本文基于上一個(gè)版本的代碼,加入了事件處理功能,同時(shí)通過異步刷新的方法提高了渲染效率。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 目前最流行的兩大前端框架,React和Vue,都不約而同的借助Virtual DO...

    caozhijian 評(píng)論0 收藏0
  • 你不知道Virtual DOM(五):自定義組件

    摘要:現(xiàn)在流行的前端框架都支持自定義組件,組件化開發(fā)已經(jīng)成為提高前端開發(fā)效率的銀彈。二對(duì)自定義組件的支持要想正確的渲染組件,第一步就是要告訴某個(gè)標(biāo)簽是自定義組件。下面的例子里,就是一個(gè)自定義組件。解決了識(shí)別自定義標(biāo)簽的問題,下一步就是定義標(biāo)簽了。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、...

    lk20150415 評(píng)論0 收藏0
  • 你不知道Virtual DOM(三):Virtual Dom更新優(yōu)化

    摘要:經(jīng)過這次優(yōu)化,計(jì)算的時(shí)間快了那么幾毫秒。基于當(dāng)前這個(gè)版本的代碼還能做怎樣的優(yōu)化呢,請(qǐng)看下一篇的內(nèi)容你不知道的四的作用。 歡迎關(guān)注我的公眾號(hào)睿Talk,獲取我最新的文章:showImg(https://segmentfault.com/img/bVbmYjo); 一、前言 目前最流行的兩大前端框架,React和Vue,都不約而同的借助Virtual DOM技術(shù)提高頁面的渲染效率。那么,什...

    xiongzenghui 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<