《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等。

相关文章
|
8天前
|
前端开发 JavaScript 开发者
Express.js与前端框架的集成:React、Vue和Angular的示例与技巧
本文介绍了如何将简洁灵活的Node.js后端框架Express.js与三大流行前端框架——React、Vue及Angular进行集成,以提升开发效率与代码可维护性。文中提供了详细的示例代码和实用技巧,展示了如何利用Express.js处理路由和静态文件服务,同时在React、Vue和Angular中构建用户界面,帮助开发者快速掌握前后端分离的开发方法,实现高效、灵活的Web应用构建。
29 3
|
6天前
|
JavaScript 前端开发 API
如何在前端开发中有效管理状态:React vs. Vue
在现代前端开发中,状态管理是一个关键因素,它直接影响到应用的性能和可维护性。React 和 Vue 是当前最流行的前端框架,它们在状态管理方面各有优势和劣势。本文将深入探讨 React 和 Vue 在状态管理中的不同实现,分析它们的优缺点,并提供实际应用中的最佳实践,以帮助开发者选择最适合他们项目的解决方案。
|
20天前
|
前端开发 Java Spring
Spring与Angular/React/Vue:当后端大佬遇上前端三杰,会擦出怎样的火花?一场技术的盛宴,你准备好了吗?
【8月更文挑战第31天】Spring框架与Angular、React、Vue等前端框架的集成是现代Web应用开发的核心。通过RESTful API、WebSocket及GraphQL等方式,Spring能与前端框架高效互动,提供快速且功能丰富的应用。RESTful API简单有效,适用于基本数据交互;WebSocket支持实时通信,适合聊天应用和数据监控;GraphQL则提供更精确的数据查询能力。开发者可根据需求选择合适的集成方式,提升用户体验和应用功能。
52 0
|
20天前
|
前端开发 Java JSON
Struts 2携手AngularJS与React:探索企业级后端与现代前端框架的完美融合之道
【8月更文挑战第31天】随着Web应用复杂性的提升,前端技术日新月异。AngularJS和React作为主流前端框架,凭借强大的数据绑定和组件化能力,显著提升了开发动态及交互式Web应用的效率。同时,Struts 2 以其出色的性能和丰富的功能,成为众多Java开发者构建企业级应用的首选后端框架。本文探讨了如何将 Struts 2 与 AngularJS 和 React 整合,以充分发挥前后端各自优势,构建更强大、灵活的 Web 应用。
34 0
|
20天前
|
前端开发 Java UED
JSF 面向组件开发究竟藏着何种奥秘?带你探寻可复用 UI 组件设计的神秘之路
【8月更文挑战第31天】在现代软件开发中,高效与可维护性至关重要。JavaServer Faces(JSF)框架通过其面向组件的开发模式,提供了构建复杂用户界面的强大工具,特别适用于设计可复用的 UI 组件。通过合理设计组件的功能与外观,可以显著提高开发效率并降低维护成本。本文以一个具体的 `MessageComponent` 示例展示了如何创建可复用的 JSF 组件,并介绍了如何在 JSF 页面中使用这些组件。结合其他技术如 PrimeFaces 和 Bootstrap,可以进一步丰富组件库,提升用户体验。
35 0
|
20天前
|
开发者 安全 UED
JSF事件监听器:解锁动态界面的秘密武器,你真的知道如何驾驭它吗?
【8月更文挑战第31天】在构建动态用户界面时,事件监听器是实现组件间通信和响应用户操作的关键机制。JavaServer Faces (JSF) 提供了完整的事件模型,通过自定义事件监听器扩展组件行为。本文详细介绍如何在 JSF 应用中创建和使用事件监听器,提升应用的交互性和响应能力。
18 0
|
20天前
|
开发者 自然语言处理 存储
语言不再是壁垒:掌握 JSF 国际化技巧,轻松构建多语言支持的 Web 应用
【8月更文挑战第31天】JavaServer Faces (JSF) 框架提供了强大的国际化 (I18N) 和本地化 (L10N) 支持,使开发者能轻松添加多语言功能。本文通过具体案例展示如何在 JSF 应用中实现多语言支持,包括创建项目、配置语言资源文件 (`messages_xx.properties`)、设置 `web.xml`、编写 Managed Bean (`LanguageBean`) 处理语言选择,以及使用 Facelets 页面 (`index.xhtml`) 显示多语言消息。通过这些步骤,你将学会如何配置 JSF 环境、编写语言资源文件,并实现动态语言切换。
21 0
|
20天前
|
开发者 Java
JSF EL 表达式:乘技术潮流之风,筑简洁开发之梦,触动开发者心弦的强大语言
【8月更文挑战第31天】JavaServer Faces (JSF) 的表达式语言 (EL) 是一种强大的工具,允许开发者在 JSF 页面和后台 bean 间进行简洁高效的数据绑定。本文介绍了 JSF EL 的基本概念及使用技巧,包括访问 bean 属性和方法、数据绑定、内置对象使用、条件判断和循环等,并分享了最佳实践建议,帮助提升开发效率和代码质量。
26 0
|
20天前
|
前端开发 Java UED
瞬间变身高手!JSF 与 Ajax 强强联手,打造极致用户体验的富客户端应用,让你的应用焕然一新!
【8月更文挑战第31天】JavaServer Faces (JSF) 是 Java EE 标准的一部分,常用于构建企业级 Web 应用。传统 JSF 应用采用全页面刷新方式,可能影响用户体验。通过集成 Ajax 技术,可以显著提升应用的响应速度和交互性。本文详细介绍如何在 JSF 应用中使用 Ajax 构建富客户端应用,并通过具体示例展示 Ajax 在 JSF 中的应用。首先,确保安装 JDK 和支持 Java EE 的应用服务器(如 Apache Tomcat 或 WildFly)。
27 0
|
20天前
|
前端开发 UED 开发者
React组件优化全攻略:深度解析让你的前端应用飞速运行的秘诀——从PureComponent到React.memo的彻底性能比较
【8月更文挑战第31天】在构建现代Web应用时,性能是提升用户体验的关键因素。React作为主流前端库,其组件优化尤为重要。本文深入探讨了React组件优化策略,包括使用`PureComponent`、`React.memo`及避免不必要的渲染等方法,帮助开发者显著提升应用性能。通过实践案例对比优化前后效果,不仅提高了页面渲染速度,还增强了用户体验。优化React组件是每个开发者必须关注的重点。
35 0