フロントエンドフレームワークの設計の重要性

この記事は、「Vue.jsの設計と実装」の「Artof Balance」の章の研究に加えて、個人的な理解に基づいており、本のコードとテキストを完全にコピーしているわけではありません。ディープラーニングには、本物の「Vue.jsDesignandImplementation」を購入することをお勧めします。

命令型および宣言型

命令型プログラミングは、典型的な命令型プログラミングライブラリjQueryであるプロセスに焦点を当てています。

<div id="app"></div>

// 获取 id 为 app 的 div 标签
$('#app')
    // 设置文本类容为 hello world
    .text('hello world')
    // 点击时,内容修改为 hello jquery
    .on('click', function () {
        this.innerText = 'hello jquery'
    })
复制代码

命令型プログラミングは、DOMを直接操作するという通常の考え方に沿ったものであり、パフォーマンスが向上します。

宣言型プログラミングは、Vueのように結果に焦点を当てています。

<template>
    <!-- 定义 UI -->
    <div id="app">{{ content }}</div>
</template>

<script setup>
import { ref } from 'vue'

// 声明状态
const content = ref('hello world')
const changeContent = () => {
    // 修改状态
    content.value = 'hello vue'
}
</script>
复制代码

宣言型プログラミングは、データ駆動型ビューUI = f(x)の機能的なアイデアに準拠しており、UIの変更プロセスはフレームワークに渡されます。開発者は変数に注意を払うだけで、メンテナンス中の精神的な負担を軽減できます。

要約:宣言型プログラミングは保守性が高くなりますが、パフォーマンスは命令型よりも低くなります。Vueが行う必要があるのは、パフォーマンスの低下を最小限に抑えながら保守性を維持することです。

仮想DOMのパフォーマンス

Vueが初めてビューをレンダリングすると、VNodeが生成され、更新されると、新しいVNodeが生成されます。新しいVNodeと古いVNodeが比較されて、最小の変更の違いが検出され、変更されます。

宣言型コードのパフォーマンスコストの更新=違いを見つけるためのパフォーマンスコスト+DOMを変更するためのパフォーマンスコスト

理論的には、ネイティブJavaScriptを使用してDOMを直接操作するパフォーマンスは優れていますが、これには開発者の能力に対する要件が高くなります。jQueryの時代には、多くのinnerHTMLブルートフォースがました。

最初のレンダリングでのパフォーマンスの比較

時間のかかる仮想DOM=JavaScriptオブジェクト(VNode)の作成+完全なDOMレンダリング

時間がかかるinnerHTML=JavaScript文字列のスプライシング+完全なDOMレンダリング

更新時のパフォーマンス比較

時間のかかる仮想DOM=新しいJavaScriptオブジェクト(VNode)の作成+差分+部分的なDOMレンダリング

時間がかかるinnerHTML=JavaScript文字列のスプライシング+完全なDOMレンダリング

まとめ

操作虚拟 DOM 和操作原生 DOM 谁的性能更好,不能简单下结论。因为这跟如何操作 DOM,何时操作 DOM,修改量多少都有关。

虚拟 DOM 是保证运行性能、代码可维护性、降低心智负担的综合选择

运行时与编译时

纯运行时

手写 DOM 对象,运行时直接遍历对象进行渲染,但书写麻烦。

var vnode = {
    tag: 'div',
    children: [
        {
            tag: 'span',
            children: 'hello '
        },
        {
            tag: 'span',
            children: 'vue'
        }
    ]
}
function render(vnode, parent) {
    const el = document.createElement(vnode.tag)
    const children = vnode.children
    if (typeof children === 'string') {
        el.innerHTML = vnode.children
    }
    if (Array.isArray(children) && children.length !== 0) {
        children.forEach(child => {
            render(child, el)
        })
    }
    parent.appendChild(el)
}
render(vnode, document.body)
复制代码

编译时 + 运行时

开发时写普通 HTML 模板:

<div>
    <span>hello </span>
    <span>vue</span>
</div>
复制代码

构建时通过 compiler 进行编译:

const htmlString = '<div>...</div>'
const content = compile(htmlString)
复制代码

运行时渲染:

render(content, document.body)
复制代码

纯编译时

我们可以将模板编译成渲染函数或者 VNode,那同样也可以直接编译成原生 DOM 操作:

const htmlString = '<div>...</div>'
const content = compile(htmlString)

// 编译生成
const div = document.createElement('div')
const hello = document.createElement('span')
hello.innerHTML = 'hello '
div.appendChild(hello)
// ...
复制代码

小结

纯运行时以及编译时 + 运行时的方式都可以通过不同的渲染器实现跨平台渲染,灵活性高。

但是纯运行时书写麻烦,如果想做静态优化需要手动标记,而编译时 + 运行时可以交给 compiler 去做。

纯编译时 理论上能获得最好的性能,但灵活性相对较弱。

综上

Vue 是一个编译时 + 运行时声明式 UI 框架,利用虚拟 DOM 进行更新渲染。保证其拥有良好的可维护性和灵活性,同时加上静态优化,尽可能接近原生的性能。

おすすめ

転載: juejin.im/post/7086735709247275015