百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

前端 UI 框架新思考 - Himmel(前端界面设计框架)

ccwgpt 2024-09-20 13:33 27 浏览 0 评论

现代前端框架的实现原理都可以用以下公式进行概括:

UI = f(state)

其中:

  • state —— 当前的视图的状态
  • f —— 框架内部的运行机制
  • UI —— 宿主环境的视图

这个公式说明,框架内部运行机制根据当前状态渲染视图,这也能看出现代框架的两个重要特性:数据驱动和 描述 UI。

如何描述 UI 界面?

现状

现代前端 UI 框架还是沿用类 HTML 解决方案,主要理由就是“开发人员更熟悉”。但实际上,它们都已经扩展了 HTML,扩展的部分已经必不可少,实际可能远离了初衷 - “开发人员更熟悉”。

Vue 描述 UI 界面的部分代码如下:

html复制代码
<div id="app">
  <button @click="count++">
    Count is: {{ count }}
  </button>
</div>

TSX 描述 UI 界面的部分代码如下:

tsx复制代码export default function MyApp() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <MyButton onClick={{handleClick}} />
    </div>
  );
}

拥抱 Dom API

目前所有的前端 UI 框架对于描述 UI 界面的方式都是通过拓展 HTML 来实现的。因为 HTML 不支持直接运行 JS 代码,所以具体的扩展实现对开发者而言都是黑盒。同时随着框架演变,出现越来越多的魔法实现、指令和语法糖。对于开发者而言无疑增会加学习和使用成本。

通过解读框架对于描述 UI 界面的实现方法,可以发现都是通过 DOM API 来最后生成 HTML。因此,如果绕过扩展的 HTML,直接使用 DOM API 来描述 UI 界面是可行的。但 DOM API 是命令式,直接使用会产生大量样板代码,同时已经不符合当前开发者的习惯和思维。那么就需要对 DOM API 进行轻量封装,实现声明式的方法。

Himmel 描述 UI 界面的部分代码如下:

typescript复制代码function App() {
  return Div([
    Div([
      Img(himmelLogo).className("logo").attrs({ alt: "himmel Logo" }),
      Img(viteLogo).className("logo").attrs({ alt: "TypeScript Logo" }),
    ]).className("flex gap-2 justify-center"),
    H1("Himmel + TypeScript"),
    ])
}

因为不需要扩展 HTML,所有没有构建过程(当然也会损失构建中的性能优化,但这并非不可弥补),所有实现对开发者都是透明直接的。也不存在语法糖,使用 JS 便可以描述复杂且完整的 UI 界面。

如何驱动 UI 界面?

所有的前端框架都具有一套响应式机制来驱动 UI 界面。从本质而言,响应式可以认为是通过监听一系列状态,根据状态的变化来更新 UI 的过程。

React 的实现是通过订阅发布模式监听在 JSX 中通过 useState 创建的状态,然后通过 diff 算法,计算出整个 UI 界面(虚拟 dom 树)中的变化部分,然后仅更新变化的部分。存在的缺点是:

  1. JSX 内状态的订阅和 state 代码书写顺序有关(具体查阅),这非常不符合开发逻辑。
  2. 状态只能在 JSX 中被使用和更新,传递需要通过 props 或 context 等特定 API,使用成本较大。
  3. 状态变更后,需要通过 diff 算法(后面 Solid 证明 diff 算法不是必须)来知道具体变化的部分。
  4. 更新 UI 界面时,是通过 re-render 方式,需要开发者格外小心将 once-run 的代码通过各种手段避免在 re-render 时重复执行。
tsx复制代码function MyButton() {
  const [count, setCount] = useState(0); // define state

  function handleClick() {
    setCount(count + 1); // update state
  }

  return (
    <button onClick={handleClick}>
      {/* use state */}
      Clicked {count} times 
    </button>
  );
}

Vue 的实现是通过 Proxy 来监听在 Setup 方法中通过 ref 创建的状态,然后同样通过 diff 算法,计算变化部分。Vue 的实现避免 React 中 state 要注意顺序的问题,当其他缺陷是同样存在的。

typescript复制代码import { createApp, ref } from 'vue'

createApp({
  setup() {
    return {
      count: ref(0) // define state
    }
  }
}).mount('#app')
html复制代码<div id="app">
  <button @click="count++"> // update state
    Count is: {{ count }} // use state
  </button>
</div>

Solid 的实现是通过 Proxy 来监听文件通过 createSignal 方法创建的状态,然后更新状态值对应的 UI 部分,因为没有虚拟DOM,所有不存在 re-render,每次更新都是在真实的 dom 上操作。

javascript复制代码import {
        createSignal,
        onCleanup,
      } from "https://cdn.skypack.dev/solid-js";
      import { render } from "https://cdn.skypack.dev/solid-js/web";
      import html from "https://cdn.skypack.dev/solid-js/html";

      const App = () => {
        const [count, setCount] = createSignal(0), // define state
          timer = setInterval(() => setCount(count() + 1), 1000); // update state
        onCleanup(() => clearInterval(timer));
        return html`<div>${count}</div>`; // use state
        // or
        return h("div", {}, count);
      };
      render(App, document.body);

Solid 是最直观的使用响应式方式的框架,Himmel 采用了完全相同的实现,只是在 api 命名上有所区别而已。因为 Himmel 没有使用 JSX,所以无法通过构建来将状态值自动包裹进 getter 函数中。但 Himmel 使用单独的 getdispatch 两个方法来获取最新状态值和更新状态值,却同样可以减少大量定义 getter、setter 方法的代码。

typescript复制代码import { dispatch, get, signal } from "himmel/signal";

const countSignal = signal(0); // define state
const hideSignal = signal(true);

export default function App() {
  return Div(
      Button(() => `count is ${get(countSignal)}`) // use state
        .attrs({ id: "counter" })
        .onClick(() => {
          dispatch(countSignal, (old) => old + 1); // update state
        })
    )
}

总结

我们的最终目标不是编写更少的代码,而是在明确表达应用程序且提供良好维护性的前提下编写更少的代码。如果这项技术单纯强调“简单”,那可能会包含过多的魔法,而掩盖掉重要的细节,比如 Vue 的种种指令,React 的 useEffect 。但掩盖掉的细节带来的副作用最终还是会暴露在开发者面前,只是角度有所不同,开发者仍然不得不面对。

这并非劝大家直接放弃所有现成的解决方案。但对于开发人员值得思考的是,如果对那些具有严重设计缺陷的“雪花” 前端框架进行重新设计,是否有新的方式来使得实现应用程序的最终代码会更好?

但如果那些强大的前端 UI 框架还没有意识到当前实践的缺陷,反而在错误的道路上越走越远。那么有新的挑战者出现也并非坏事。

参考

GitHub - xiamu14/himmel-dev: himmel-dev is a Modern frontend framework . no build, no virtual dom, n...

Himmel + TS Demo

All your mainstream UI frameworks are lying to you

作者:夏木14 链接:https://juejin.cn/post/7347664103039336482

相关推荐

详解DNFSB2毒王的各种改动以及大概的加点框架

首先附上改动部分,然后逐项分析第一个,毒攻掌握技能意思是力量智力差距超过15%的话差距会被强行缩小到15%,差距不到15%则无效。举例:2000力量,1650智力,2000*0.85=1700,则智力...

通篇干货!纵观 PolarDB-X 并行计算框架

作者:玄弟七锋PolarDB-X面向HTAP的混合执行器一文详细说明了PolarDB-X执行器设计的初衷,其初衷一直是致力于为PolarDB-X注入并行计算的能力,兼顾TP和AP场景,逐渐...

字节新推理模型逆袭DeepSeek,200B参数战胜671B,豆包史诗级加强

梦晨发自凹非寺量子位|公众号QbitAI字节最新深度思考模型,在数学、代码等多项推理任务中超过DeepSeek-R1了?而且参数规模更小。同样是MoE架构,字节新模型Seed-Thinkin...

阿里智能化研发起飞!RTP-LLM 实现 Cursor AI 1000 token/s 推理技术揭秘

作者|赵骁勇阿里巴巴智能引擎事业部审校|刘侃,KittyRTP-LLM是阿里巴巴大模型预测团队开发的高性能LLM推理加速引擎。它在阿里巴巴集团内广泛应用,支撑着淘宝、天猫、高德、饿...

多功能高校校园小程序/校园生活娱乐社交管理小程序/校园系统源码

校园系统通常是为学校、学生和教职工提供便捷的数字化管理工具。综合性社交大学校园小程序源码:同城校园小程序-大学校园圈子创业分享,校园趣事,同校跑腿交友综合性论坛。小程序系统基于TP6+Uni-app...

婚恋交友系统nuiAPP前端解决上传视频模糊的问题

婚恋交友系统-打造您的专属婚恋交友平台系统基于TP6+Uni-app框架开发;客户移动端采用uni-app开发,管理后台TH6开发支持微信公众号端、微信小程序端、H5端、PC端多端账号同步,可快速打包...

已节省数百万GPU小时!字节再砍MoE训练成本,核心代码全开源

COMET团队投稿量子位|公众号QbitAI字节对MoE模型训练成本再砍一刀,成本可节省40%!刚刚,豆包大模型团队在GitHub上开源了叫做COMET的MoE优化技术。COMET已应用于字节...

通用电气完成XA102发动机详细设计审查 将为第六代战斗机提供动力

2025年2月19日,美国通用电气航空航天公司(隶属于通用电气公司)宣布,已经完成了“下一代自适应推进系统”(NGAP)计划下提供的XA102自适应变循环发动机的详细设计审查阶段。XA102是通用电气...

tpxm-19双相钢材质(双相钢f60材质)

TPXM-19双相钢是一种特殊的钢材,其独特的化学成分、机械性能以及广泛的应用场景使其在各行业中占有独特的地位。以下是对TPXM-19双相钢的详细介绍。**化学成分**TPXM-19双相钢的主要化学成...

thinkphp6里怎么给layui数据表格输送数据接口

layui官网已经下架了,但是产品还是可以使用。今天一个朋友问我怎么给layui数据表格发送数据接口,当然他是学前端的,后端不怎么懂,自学了tp框架问我怎么调用。其实官方文档上就有相应的数据格式,js...

完美可用的全媒体广告精准营销服务平台PHP源码

今天测试了一套php开发的企业网站展示平台,还是非常不错的,下面来给大家说一下这套系统。1、系统架构这是一套基于ThinkPHP框架开发的HTML5响应式全媒体广告精准营销服务平台PHP源码。现在基于...

一对一源码开发,九大方面完善基础架构

以往的直播大多数都是一对多进行直播社交,弊端在于不能满足到每个用户的需求,会降低软件的体验感。伴随着用户需求量的增加,一对一直播源码开始出现。一个完整的一对一直播流程即主播发起直播→观看进入房间观看→...

Int J Biol Macromol .|交联酶聚集体在分级共价有机骨架上的固定化:用于卤代醇不对称合成的高稳定酶纳米反应器

大家好,今天推送的文章发表在InternationalJournalofBiologicalMacromolecules上的“Immobilizationofcross-linkeden...

【推荐】一款开源免费的 ChatGPT 聊天管理系统,支持PC、H5等多端

如果您对源码&技术感兴趣,请点赞+收藏+转发+关注,大家的支持是我分享最大的动力!!!项目介绍GPTCMS是一款开源且免费(基于GPL-3.0协议开源)的ChatGPT聊天管理系统,它基于先进的GPT...

高性能计算(HPC)分布式训练:训练框架、混合精度、计算图优化

在深度学习模型愈发庞大的今天,分布式训练、高效计算和资源优化已成为AI开发者的必修课。本文将从数据并行vs模型并行、主流训练框架(如PyTorchDDP、DeepSpeed)、混合精度训练(...

取消回复欢迎 发表评论: