• 前端框架的运行时与编译时


    前端框架的运行时与编译时

    本文写于 2022 年 5 月 20 日。

    运行时与编译时是前端工程师常常听到的两个词。

    比如 Vue 运行时、Angular 运行时、React 运行时……

    又比如 svelte 框架,总听到他的宣传说的是“0 运行时”,所以他的工作其实就是在“编译时”了。

    这两个词到底是什么意思呢?

    虚拟 DOM 的渲染

    我们以虚拟 DOM 为例来讲解运行时与编译时。

    虚拟 DOM 是 React/Vue 都采用了的一种设计手段,简单来讲它就是将 HTML 的 DOM,用一套 JS 对象来表示。

    <div id="app">
      <h1>Hello World</h1>
    </div>
    

    可以简单的这么表示:

    const vDom = {
      tag: "div",
      id: "app",
      children: [
        {
          tag: "h1",
          children: ["Hello World"],
        },
      ],
    };
    

    那么我们如何渲染这个对象呢?

    可以提供一个 render 函数来做到。

    function render(vDom, container) {
      const el = document.createElement(vDom.tag);
      el.id = vDom.id;
      if (!vDom.children || vDom.children.length === 0) {
        container.append(el);
        return;
      }
    
      for (let i = 0; i < vDom.children.length; i++) render(vDom[i], el);
    }
    

    我们去遍历这个对象和他的 children 属性以渲染 DOM。(这个写法效率很低,只做示例用)

    这就叫做运行时。

    我们在代码跑起来之后,才进行的 DOM 渲染。

    虚拟 DOM 写起来太麻烦怎么办

    接下来问题来了,虚拟 DOM 实在是太难写了。我们这么去写 UI 会写到吐血的。

    能不能让我们写普通的 HTML,然后把它变成虚拟 DOM 呢?

    当然可以,我们的 Vue 和 React 都提供了这样的工具,所以我们才能愉快的书写 Vue template 和 JSX。

    假设这是一个函数名叫 complier

    const vDom = complier(htmlStr);
    render(vDom, document.querySelector("#app"));
    

    这样我们就能衔接上之前写的 render 方法。

    直到此时,我们依旧是纯运行时框架。但 complier 函数并没有必要放到运行时呀!

    我们可以写一个脚本把 complier 的结果直接硬编码到输出文件中。

    // 源文件
    <template>
      <div>
        <!-- ... -->
      </div>
    </template>
    
    <script>
    // do something here...
    </script>
    
    // 输出文件
    const vDom = {
      tag: "div",
      children: [
        // ...
      ],
    };
    render(vDom, app);
    

    在浏览器中我们无须源文件,只需要输出文件,就可以运行我们的 render 函数了。

    render 函数也能编译?

    既然我们可以把 jsx/Vue template 编译成 vDom,那我们能不能直接把 render 函数也给干掉呢?

    要知道 render 现在需要进行递归操作,效率是比较差的。

    我们要时能把所有的递归操作都干掉,直接编译成一连串的 DOM 操作,岂不美哉?

    没错,这样做是可以的。

    如果我们把源代码直接编译成一连串的 DOM 操作,那么我们做的就叫做 “纯编译时”框架。因为在代码运行过程中,我们的框架没有做任何操作。

    (完)

  • 相关阅读:
    关于掌握C#的内存堆栈概念
    sqlserver 跨服务器查询
    写单元测试的知识结构(2)——单元测试工具的选用(找个顺手的)
    写单元测试的知识结构(1) —— 单元测试用处
    如何能保证自己的功能代码不出纰漏
    Mysql查询架构信息
    Mysql 分组查询最高分
    Mysql按照字段值做分组行转列查询
    软件测试学习笔记:主路径测试
    软件测试学习笔记:Junit入门
  • 原文地址:https://www.cnblogs.com/xhyccc/p/16349481.html
Copyright © 2020-2023  润新知