この記事は、「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
进行更新渲染。保证其拥有良好的可维护性和灵活性,同时加上静态优化,尽可能接近原生的性能。