react Virtual DOM以及diff方法

Virtual DOM 及 Diff 算法

1. JSX 到底是什么

使用 React 就一定会写 JSX,JSX 到底是什么呢?它是一种 JavaScript 语法的扩展,React 使用它来描述用户界面长成什么样子。虽然它看起来非常像 HTML,但它确实是 JavaScript 。在 React 代码执行之前,Babel 会对将 JSX 编译为 React API.

<div className="container">
  <h3>Hello React</h3>
  <p>React is great </p>
</div>
React.createElement(
  "div",
  {
    className: "container"
  },
  React.createElement("h3", null, "Hello React"),
  React.createElement("p", null, "React is great")
);

从两种语法对比来看,JSX 语法的出现是为了让 React 开发人员编写用户界面代码更加轻松。

Babel REPL

2. DOM 操作问题

在现代 web 应用程序中使用 JavaScript 操作 DOM 是必不可少的,但遗憾的是它比其他大多数 JavaScript 操作要慢的多。

大多数 JavaScript 框架对于 DOM 的更新远远超过其必须进行的更新,从而使得这种缓慢操作变得更糟。

例如假设你有包含十个项目的列表,你仅仅更改了列表中的第一项,大多数 JavaScript 框架会重建整个列表,这比必要的工作要多十倍。

更新效率低下已经成为严重问题,为了解决这个问题,React 普及了一种叫做 Virtual DOM 的东西,Virtual DOM 出现的目的就是为了提高 JavaScript 操作 DOM 对象的效率。

3. 什么是 Virtual DOM

在 React 中,每个 DOM 对象都有一个对应的 Virtual DOM 对象,它是 DOM 对象的 JavaScript 对象表现形式,其实就是使用 JavaScript 对象来描述 DOM 对象信息,比如 DOM 对象的类型是什么,它身上有哪些属性,它拥有哪些子元素。

可以把 Virtual DOM 对象理解为 DOM 对象的副本,但是它不能直接显示在屏幕上。

<div className="container">
  <h3>Hello React</h3>
  <p>React is great </p>
</div>
{
  type: "div",
  props: { className: "container" },
  children: [
    {
      type: "h3",
      props: null,
      children: [
        {
          type: "text",
          props: {
            textContent: "Hello React"
          }
        }
      ]
    },
    {
      type: "p",
      props: null,
      children: [
        {
          type: "text",
          props: {
            textContent: "React is great"
          }
        }
      ]
    }
  ]
}

.babelrc

{
   
    "presets": [
        "@babel/preset-env",
        [
            "@babel/preset-react",
            {
   
                "pragma": "TinyReact.createElement"
            }
        ]
    ]
}

4. Virtual DOM 如何提升效率

精准找出发生变化的 DOM 对象,只更新发生变化的部分。

在 React 第一次创建 DOM 对象后,会为每个 DOM 对象创建其对应的 Virtual DOM 对象,在 DOM 对象发生更新之前,React 会先更新所有的 Virtual DOM 对象,然后 React 会将更新后的 Virtual DOM 和 更新前的 Virtual DOM 进行比较,从而找出发生变化的部分,React 会将发生变化的部分更新到真实的 DOM 对象中,React 仅更新必要更新的部分。

Virtual DOM 对象的更新和比较仅发生在内存中,不会在视图中渲染任何内容,所以这一部分的性能损耗成本是微不足道的。

在这里插入图片描述

<div id="container">
	<p>Hello React</p>
</div>
<div id="container">
	<p>Hello Angular</p>
</div>
const before = {
  type: "div",
  props: { id: "container" },
  children: [
    {
      type: "p",
      props: null,
      children: [
        { type: "text", props: { textContent: "Hello React" } }
      ]
    }
  ]
}
const after = {
  type: "div",
  props: { id: "container" },
  children: [
    {
      type: "p",
      props: null,
      children: [
        { type: "text", props: { textContent: "Hello Angular" } }
      ]
    }
  ]
}

实现精简版React

创建tiny-react文件夹
src放置源码
src下TinyReact放置对应的源码
TinyReact下 index.js放置源码综合配置
src下 index.js放置引入精简版react的使用,index.html放置模板
package.json放置依赖配置
webpack.config.js放置需要的webpack模块配置

package.json

{
   
  "name": "tiny-react",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
   
    "start": "webpack-dev-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
   
    "@babel/core": "^7.11.4",
    "@babel/preset-env": "^7.11.0",
    "@babel/preset-react": "^7.10.4",
    "babel-loader": "^8.1.0",
    "clean-webpack-plugin": "^3.0.0",
    "html-webpack-plugin": "^4.3.0",
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  },
  "dependencies": {
   }
}

webpack.config.js

const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const {
    CleanWebpackPlugin } = require("clean-webpack-plugin")

module.exports = {
   
  entry: "./src/index.js",
  output: {
   
    path: path.resolve("dist"),
    filename: "bundle.js"
  },
  devtool: "inline-source-map",
  module: {
   
    rules: [
      {
   
        test: /\.js$/,
        exclude: /node_modules/,
        use: "babel-loader"
      }
    ]
  },
  plugins: [
    // 在构建之前将dist文件夹清理掉
    new CleanWebpackPlugin({
   
      clea
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值