# 第 1 章 权衡的艺术

# 1. 命令式和声明式

视图层框架按范式分为:

  • 命令式:关注过程,与自然语音一一对应
  • 声明式:关注结果,由框架来实现过程

# 2. 性能和可维护性

框架封装了命令式代码,以实现面向用户的命令式

声明式代码的性能不优于命令式代码的性能

# 3. 虚拟 DOM 的性能到底如何

声明式代码的更新性能消耗 = 找出差异的性能消耗 + 直接修改的性能消耗

虚拟 DOM 就是为了最小化找出差异才出现的

新建页面:

运算 innerHTML(模板) 虚拟DOM
JS运算 渲染 HTML 字符串 创建JS对象(虚拟DOM)
DOM运算 新建所有新 DOM 元素 新建所有新 DOM 元素

更新页面:

运算 innerHTML(模板) 虚拟DOM
JS运算 渲染 HTML 字符串 创建新的虚拟DOM对象 + diff
DOM运算 销毁所有旧 DOM 元素,新建所有新 DOM 元素 必要的 DOM 更新

# 4. 运行时和编译时

纯 运行时 框架:

  • 源码:

    // obj -> DOM 
    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) {
        obj.children.forEach((child) => render(child, el));
      }
    
      root.appendChild(el);
    }
    
  • 使用:

    const obj = {
      tag: 'div',
      children: [
        { tag: 'span', children: 'hello world' },
      ]
    }
    
    render(obj, document.body);
    

编译时 + 运行时 框架:

  • 源码

    // htmlStr -> obj
    function compile(htmlStr): obj;
    
    // obj -> DOM 
    function render(obj, root);
    
  • 使用

    const htmlStr = `
      <div>
        <span>hello world</span>
      </div>
    `
    const obj = compile(htmlStr);
    
    render(obj, document.body);
    

纯 编译时 框架:

  • 源码

    // htmlStr -> DOM
    function compile(htmlStr): DOM;
    
  • 使用

    const htmlStr = `
      <div>
        <span>hello world</span>
      </div>
    `
    const dom = compile(htmlStr);
    
    document.body.appendChild(dom);
    
本章目录