《React设计原理》读书分享–前端框架概述

简介: 《React设计原理》读书分享–前端框架概述

很早就阅读了电子版的《React技术揭秘》,后来听说出了实体书,果断就下单了

所以今天分享下最近的阅读心得

基本原理

概述

前端框架主要的作用是将数据的变化映射为UI的变化:

UI=fn(state)

fn就是计算数据的变动导致UI是如何变化的,不同的框架中,fn的描述方式不同

主流的描述方式分为:

  1. jsx:使UI和逻辑更紧密,它是ES语法糖.(从逻辑出发,扩展逻辑,描述UI)
  2. 模板语法:使用HTML描述UI,它是HTML语法扩展。(从UI出发,扩展UI,描述逻辑)

jsx是动态的,即使代码没有边,每次更新,都会重新编译,

模板语法是静态的,可以用来分析,哪些节点是动态的,哪些节点是静态的。有很大的优化空间。

不管是jsx还是模板语法,它们都是组织逻辑和UI的关系

// react
const [count, setCount] = useState(0)
<div onClick={() => setCount(conut++)}>{count}</div>
// Vue
const count = ref(0)
<div @click={count.value++}>{count.value}</div>
// Svelte
const let = 0
<div on:click={() => conut++}>{count}</div>

上面三块代码功能都是一样的:当count发生变化时,UI跟着变化

根据UI变化方式(更新细粒度)不同,将框架可以分为三类:

  1. 应用级:数据变化时,重新渲染整个应用,React
  2. 组件级:数据变化时,重新渲染数据有变化的组件Vue
  3. 元素级:数据变化时,只渲染数据变化的DOM节点,Svelte

按下性能问题暂且不表,先想想,为啥会有这种差别呢?

这是因为不同的框架,架构不同导致的。

我们的代码并不是立即执行的,而是先进行编译(语法转换、将ts转为js、压缩、polyfill等),将我们的代码转为宿主环境可以识别的代码。

React

React经过编译之后返回的是createElement函数,所以每次数据变化,React都会从应用根节点重新加载整个应用。

export const App = () => {
  const [count, setCount] = useState(0);
  return /*#__PURE__*/React.createElement("div", {
    onClick: () => setCount(conut++)
  }, count);
};

所以这种框被架称为应用级框架

Vue

Vue经过编译之后返回的是组件的render函数,

function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createElementBlock("h1", {
    onClick: _cache[0] || (_cache[0] = $event => (_ctx.count++))
  }, _toDisplayString(_ctx.count), 1 /* TEXT */))
}

Vue3会为每个组件建立watchEffect事件,这个大致如下:

// patch是对比前后VNode变化的方法
watchEffect(() => patch(render(props), preVDOM), [conut])

在页面首次进入或者watchEffect的依赖项发生变化时,都会调用组件的render函数。

render函数的返回值是本次更新的VNode,Vue会根据本次更新的VNode与上传更新做比较(patch),找到最优的更新路径,并且进行更新。

所以这种框架被称为组件级框架

Svelte

Svelte经过编译之后的返回值如下:(先别晕,可以跳过代码往下看)

import {
    SvelteComponent,
    append,
    detach,
    element,
    init,
    insert,
    listen,
    noop,
    safe_not_equal,
    set_data,
    text
} from "svelte/internal";
function create_fragment(ctx) {
    let div;
    let t;
    let mounted;
    return {
        c() {
            div = element("div");
            t = text(/*count*/ ctx[0]);
        },
        m(target, anchor) {
            insert(target, div, anchor);
            append(div, t);
            if (!mounted) {
                dispose = listen(div, "click", /*click_handler*/ ctx[1]);
                mounted = true;
            }
        },
        p(ctx, [dirty]) {
            if (dirty & /*count*/ 1) set_data(t, /*count*/ ctx[0]);
        },
        d(detaching) {
            if (detaching) detach(div);
            mounted = false;
            dispose();
        }
    };
}
function instance($$self, $$props, $$invalidate) {
    let count = 0;
    const click_handler = () => $$invalidate(0, count++, count);
    return [count, click_handler];
}
class App extends SvelteComponent {
    constructor(options) {
        super();
        init(this, options, instance, create_fragment, safe_not_equal, {});
    }
}
export default App;

Svelte返回的值主要包括三块:

1.create_fragment函数:

  1. c方法:create元素div的操作。
  2. m方法:mounted时执行将创建的div插入,并且监听divclick事件.
  3. d方法:delete元素div的操作。
  4. p方法:updata数据的操作。

2.instance函数:

声明在模板使用的变量,以及变量变化时的回调函数,并且返回它们(其实就是ctx上下文)。

3.继承SvelteComponent的组件,并且执行init方法

init方法的大致逻辑是:当数据变化,触发mounted阶段监听事件的回调函数,这个回调函数就是instance函数返回值里的click_handler,即ctx[1]

如果仅仅声明了但是没有在模板中使用,那么就会作为第四块,单独声明,但这里就不做赘述了。

从前面的代码可以看出:Svelte在编译阶段,就已经找到元素和变量之间的对应关系了。

所以这种框被架称为元素级框架

React性能

你肯定会问,我就改了个count的值,像React这样大动干戈,重新渲染整个应用,是不是很低效啊。

其实,React在运行时阶段,做了一部分关键的优化。

不管是Vue还是React,在编译之后返回的都是VNode

双缓存机制

一方面,React在拿到编译之后的VNode,首先会在内存中和上次更新的VNode进行对比,找到具体更新的VNode并且在内存中更新,上次没有更新时(mount),在内存中全部更新。


然后将VNode渲染在真实Dom里,使用current属性连接,同时保留内存中的VNode,使用altername属性使每个真实Dom对应,以方便下次更新时对比。

这个机制叫做双缓存机制另一方面,React被重新设计为可以中断的更新UI,这么做的好处是可以避免因为高复杂度的更新因为耗时长使用户感知到页面的卡顿。

Firbe架构

这种可中断的更新架构就是Firbe架构。

可以中断的更新原理是:如果浏览器计算和渲染的时间超过人眼可以感知卡顿的最短时间16.6ms,那就中断它,把时间让给下一个更新任务。等时间充裕的时候再重新更新。

其他的手段

React还将一些优化的任务交给了开发者,比如,前面说过,jsx是动态的,如果你的组件全是不会变化的,那么你可以使用React.meno()包裹你的组件,明确这是个静态的,以此来较少无用的更新。还有useStateuseMemouseCallback等。

相关文章
|
19天前
|
前端开发 JavaScript 开发者
颠覆传统:React框架如何引领前端开发的革命性变革
【10月更文挑战第32天】本文以问答形式探讨了React框架的特性和应用。React是一款由Facebook推出的JavaScript库,以其虚拟DOM机制和组件化设计,成为构建高性能单页面应用的理想选择。文章介绍了如何开始一个React项目、组件化思想的体现、性能优化方法、表单处理及路由实现等内容,帮助开发者更好地理解和使用React。
51 9
|
1月前
|
前端开发
深入解析React Hooks:构建高效且可维护的前端应用
本文将带你走进React Hooks的世界,探索这一革新特性如何改变我们构建React组件的方式。通过分析Hooks的核心概念、使用方法和最佳实践,文章旨在帮助你充分利用Hooks来提高开发效率,编写更简洁、更可维护的前端代码。我们将通过实际代码示例,深入了解useState、useEffect等常用Hooks的内部工作原理,并探讨如何自定义Hooks以复用逻辑。
|
1月前
|
前端开发 数据管理 编译器
引领前端未来:React 19的重大更新与实战指南🚀
React 19 即将发布,带来一系列革命性的新功能,旨在简化开发过程并显著提升性能。本文介绍了 React 19 的核心功能,如自动优化重新渲染的 React 编译器、加速初始加载的服务器组件、简化表单处理的 Actions、无缝集成的 Web 组件,以及文档元数据的直接管理。这些新功能通过自动化、优化和增强用户体验,帮助开发者构建更高效的 Web 应用程序。
124 1
引领前端未来:React 19的重大更新与实战指南🚀
|
24天前
|
前端开发 JavaScript Android开发
前端框架趋势:React Native在跨平台开发中的优势与挑战
【10月更文挑战第27天】React Native 是跨平台开发领域的佼佼者,凭借其独特的跨平台能力和高效的开发体验,成为许多开发者的首选。本文探讨了 React Native 的优势与挑战,包括跨平台开发能力、原生组件渲染、性能优化及调试复杂性等问题,并通过代码示例展示了其实际应用。
52 2
|
25天前
|
前端开发 JavaScript 开发者
React与Vue:前端框架的巅峰对决与选择策略
【10月更文挑战第23天】React与Vue:前端框架的巅峰对决与选择策略
|
25天前
|
前端开发 JavaScript 开发者
“揭秘React Hooks的神秘面纱:如何掌握这些改变游戏规则的超能力以打造无敌前端应用”
【10月更文挑战第25天】React Hooks 自 2018 年推出以来,已成为 React 功能组件的重要组成部分。本文全面解析了 React Hooks 的核心概念,包括 `useState` 和 `useEffect` 的使用方法,并提供了最佳实践,如避免过度使用 Hooks、保持 Hooks 调用顺序一致、使用 `useReducer` 管理复杂状态逻辑、自定义 Hooks 封装复用逻辑等,帮助开发者更高效地使用 Hooks,构建健壮且易于维护的 React 应用。
31 2
|
25天前
|
前端开发 JavaScript 数据管理
React与Vue:两大前端框架的较量与选择策略
【10月更文挑战第23天】React与Vue:两大前端框架的较量与选择策略
|
1月前
|
JavaScript 前端开发 算法
前端优化之超大数组更新:深入分析Vue/React/Svelte的更新渲染策略
本文对比了 Vue、React 和 Svelte 在数组渲染方面的实现方式和优缺点,探讨了它们与直接操作 DOM 的差异及 Web Components 的实现方式。Vue 通过响应式系统自动管理数据变化,React 利用虚拟 DOM 和 `diffing` 算法优化更新,Svelte 通过编译时优化提升性能。文章还介绍了数组更新的优化策略,如使用 `key`、分片渲染、虚拟滚动等,帮助开发者在处理大型数组时提升性能。总结指出,选择合适的框架应根据项目复杂度和性能需求来决定。
|
1月前
|
缓存 前端开发 JavaScript
前端serverless探索之组件单独部署时,利用rxjs实现业务状态与vue-react-angular等框架的响应式状态映射
本文深入探讨了如何将RxJS与Vue、React、Angular三大前端框架进行集成,通过抽象出辅助方法`useRx`和`pushPipe`,实现跨框架的状态管理。具体介绍了各框架的响应式机制,展示了如何将RxJS的Observable对象转化为框架的响应式数据,并通过示例代码演示了使用方法。此外,还讨论了全局状态源与WebComponent的部署优化,以及一些实践中的改进点。这些方法不仅简化了异步编程,还提升了代码的可读性和可维护性。
|
1月前
|
XML 前端开发 JavaScript
前端开发进阶:从HTML到React.js
【10月更文挑战第9天】前端开发进阶:从HTML到React.js
下一篇
无影云桌面