欢迎来到皮皮网网首页

【扫描网站 源码】【local源码介绍】【自动源码屋】preact的源码_presto源码

来源:蓝色漩涡攻击源码 时间:2024-12-29 08:28:06

1.preact��Դ��
2.详解|天猫搜索前端技术历代记
3.Preact(React)核心原理详解
4.preact源码解析,码p码从preact中理解react原理
5.如何编译ReactNative示例程序Examples
6.畅谈React material-ui的码p码样式方案

preact的源码_presto源码

preact��Դ��

       在掌握了 React 技能后,我尝试过不少小项目,码p码但总感觉这些项目只是码p码自娱自乐,对于找工作并没有太大帮助,码p码让我感到有些迷茫。码p码扫描网站 源码于是码p码,我决定尝试做点开源项目,码p码既能锻炼自己写 React 组件的码p码能力,又能让自己有所收获。码p码我和女票都很喜欢**,码p码因此产生了制作一个播放器的码p码想法。经过一番努力,码p码我开发了一个名为“qier-player”的码p码 h5 播放器。

       qier-player 目前已实现在线播放器的码p码基本功能,包括暂停、播放、全屏、音量调节、进度条拖拽和倍速等。接下来,我打算添加快捷键和一些性能优化。如果你对播放器有需求,但又不想自己从头开始编写,或者觉得现有的播放器功能不足、不够美观,那么 qier-player 就是你的不二之选。

       以下是这个开源组件的源代码,欢迎 star 和提建议!~

       介绍:qier-player 是一个基于 React 编写的在线视频播放器组件,界面简洁,操作流畅,具有大部分视频播放器的基础功能。支持视频清晰度的切换,提供了原画、4K、2K、P、P、P 的视频源接口。

       演示官网(tip: 演示的视频没有放cdn,下载比较慢,比较卡,local源码介绍需要等它加载完)

       示例快速开始安装使用近期更新记录1.0.4 (--)1.0.3 (--)

       如果你觉得这个项目对你有所帮助,不妨赏个 star,也可以点个 watch。版本迭代会第一时间通知到你 ^-^

详解|天猫搜索前端技术历代记

       天猫搜索前端技术的发展历程,从上古时代的PC搜索,到逐步演进的H5搜索,再到MV*时代的Preact应用,直至引入Weex技术与搭建时代的探索,直至智能时代的展望,每一步都承载着技术的革新与业务的革新。

       PC时代的搜索前端采用KISSY和MUI3作为主要技术方案,适应了3G/2G时代的网络环境和用户习惯。然而,随着智能手机的普及与流量成本的下降,流量需求激增,导致原有的技术方案显得力不从心。因此,H5搜索时代应运而生,采用Zepto和MUI4,引入前端模板,优化模块化方案与页面渲染策略,解决PC搜索时代的问题,同时引入前后端分离的wormhole app,降低模板维护成本。

       进入MV*时代,随着组织架构调整,搜索前端资源投入集中在核心功能与跨平台适应性上,如H5搜索凑单页、领券弹层等。引入Preact和MUI5,优化模块化方案,采用自动化工具转换技术,实现一份源码同时复用在Weex和Web上,提升了开发效率与代码复用性。

       Weex时代,为应对流量场景下的动态化需求,以及客户端迭代的挑战,引入Native内嵌Weex坑位技术方案,结合模板下发的Oreo平台,采用Prax解决方案,实现在Web和Weex间的技术兼容性与性能优化。

       搭建时代,自动源码屋面对共建与规模化的需求,长颈鹿项目应运而生,通过千叶平台提供模块化搭建能力,为品牌商与行业提供定制化页面,实现模块化、自动化搭建,有效提升运营效率与用户体验。同时,无界模块定投方案解决了多场景间的交叉展示问题,进一步优化了模块化搭建的灵活性与适应性。

       深度搭建时代,引入Rax1.0,针对Web进行优化,模块化划分明确,实现交互、展示与数据模块的分离,以实现更高效、更灵活的页面构建与内容复用。此外,团队正尝试基于机器学习的智能UI生成技术,以期实现UI零成本构建,推动前端技术与业务的深度融合。

       智能时代,展望未来,前端技术将融合更先进的AI与数据驱动策略,实现自动化的界面生成、内容产出与用户行为分析,从而构建更为个性化、智能化的用户体验,推动业务创新与技术迭代。

Preact(React)核心原理详解

       本文作者:字节跳动 - 宝丁

       在前端领域,React 是一个广为人知的前端开发框架,它革新了全栈 Web 开发的体验。React 引入了诸如 JSX、虚拟 DOM、组件化与合成事件等概念。然而,探究其源码时,庞大且晦涩的代码体系往往让这一过程变得艰难。为了解答这个挑战,本文将聚焦 Preact,一个轻量级的cpu加密源码 React 替代方案,其体积仅为 3KB。Preact 的设计初衷是提升性能,简化复杂性。我们将从以下几个角度深入探讨 Preact 的核心原理。

       一、Preact 是什么?

       Preact 是一个功能与 React 类似的轻量级前端框架。它的名字中的“P”意味着“Performance”,强调了提高性能的初衷。Preact 旨在提供 React 的核心功能,同时以更简洁的代码实现。

       二、Preact 与 React 的区别

       1. 事件系统:React 内置了事件合成系统,主要使用 `onChange` 方法处理表单组件的值更新。相比之下,Preact 直接利用浏览器原生的事件系统,使用 `onInput` 方法,因此在体积上更加精简。

       2. DOM 规范描述:在描述 DOM 类名时,React 要求使用 `className`。Preact 支持使用 `class` 直接描述 DOM 类名,使其更贴近原生 DOM 规范。

       三、Preact 的工作流程

       1. JSX:JSX 是 Preact 的模板语法,它允许用类似 HTML 的结构描述 DOM。经过转换,JSX 被编译为函数调用,进而生成原生 DOM 结构。

       2. Virtual DOM:Preact 采用 Virtual DOM 技术,将 DOM 更新操作最小化。它通过比较虚拟 DOM 和实际 DOM,仅对发生变化的部分进行更新。

       四、Diff 算法详解

       1. Diff 儿童节点:比较新旧儿童节点,匹配相同的 key,进行差异比较,对未匹配的节点进行处理。

       2. Diff 阶段:根据节点类型(Fragment、Component、DOM node)进行不同处理,如更新组件状态、创建新 DOM 节点或更新现有 DOM 节点。

       3. Diff 属性:比较新旧 DOM 节点属性,ds源码分析仅更新变化的部分。

       五、结合实际组件

       通过一个简单的 Clock 组件,直观展示 Preact 的渲染流程,帮助理解 Preact 的工作原理。

       六、Preact Hooks

       Preact Hooks 是 React Hooks 的替代方案,提供了性能优化的组件状态管理机制。分为三类:MemoHook、ReducerHook 和 EffectHook,分别用于性能优化、状态管理与副作用操作。

       七、结束语

       本文深入介绍了 Preact 的核心原理,包括框架设计、与 React 的比较、工作流程、Diff 算法、实际应用以及 Hooks 机制。通过 Preact,前端开发者可以更高效地构建应用,同时理解其与 React 的异同。希望本文能够帮助大家更深入地掌握 Preact 的使用方法与性能优化策略。

preact源码解析,从preact中理解react原理

       基于preact.3.4版本进行分析,完整注释请参阅链接。阅读源码建议采用跳跃式阅读,遇到难以理解的部分先跳过,待熟悉整体架构后再深入阅读。如果觉得有价值,不妨为项目点个star。

       一直对研究react源码抱有兴趣,但每次都半途而废,主要原因是react项目体积庞大,代码颗粒化且执行流程复杂,需要投入大量精力。因此,转向研究preact,一个号称浓缩版react,体积仅有3KB。市面上已有对preact源码的解析,但大多存在版本过旧和分析重点不突出的问题,如为什么存在_nextDom?value为何不在diffProps中处理?这些都是解析代码中的关键点和收益点。

       一. 文件结构

       二. 渲染原理

       简单demo展示如何将App组件渲染至真实DOM中。

       vnode表示节点描述对象。在打包阶段,babel的transform-react-jsx插件会将jsx语法编译为JS语法,即转换为React.createElement(type, props, children)形式。preact中需配置此插件,使React.createElement对应为h函数,编译后的jsx语法如下:h(App,null)。

       执行render函数后,先调用h函数,然后通过createVNode返回虚拟节点。最终,h(App,null)的执行结果为{ type:App,props:null,key:null,ref:null},该虚拟节点将被用于渲染真实DOM。

       首次渲染时,旧虚拟节点基本为空。diff函数比较虚拟节点与真实DOM,创建挂载完成,执行commitRoot函数,该函数执行组件的did生命周期和setState回调。

       2. diff

       diff过程包含diff、diffElementNodes、diffChildren、diffProps四个函数。diff主要处理函数型虚拟节点,非函数型节点调用diffElementNodes处理。判断虚拟节点是否存在_component属性,若无则实例化,执行组件生命周期,调用render方法,保存子节点至_children属性,进而调用diffChildren。

       diffElementNodes处理HTML型虚拟节点,创建真实DOM节点,查找复用,若无则创建文本或元素节点。diffProps处理节点属性,如样式、事件监听等。diffChildren比较子节点并添加至当前DOM节点。

       分析diff执行流程,render函数后调用diff比较虚拟节点,执行App组件生命周期和render方法,保存返回的虚拟节点至_children属性,调用diffChildren比较子节点。整体虚拟节点树如下:

       diffChildren遍历子节点,查找DOM节点,比较虚拟节点,返回真实DOM,追加至parentDOM或子节点后。

       三. 组件

       1. component

       Component构造函数设置状态、强制渲染、定义render函数和enqueueRender函数。

       强制渲染通过设置_force标记,加入渲染队列并执行。_force为真时,diff渲染不会触发某些生命周期。

       render函数默认为Fragment组件,返回子节点。

       enqueueRender将待渲染组件加入队列,延迟执行process函数。process排序组件,渲染最外层组件,调用renderComponent渲染,更新DOM后执行所有组件的did生命周期和setState回调。

       2. context

       使用案例展示跨组件传递数据。createContext创建context,包含Provider和Consumer组件。Provider组件跨组件传递数据,Consumer组件接收数据。

       源码简单,createContext后返回context对象,包含Consumer与Provider组件。Consumer组件设置contextType属性,渲染时执行子节点,等同于类组件。

       Provider组件创建函数,渲染到Provider组件时调用getChildContext获取ctx对象,diff时传递至子孙节点组件。组件设置contextType,通过sub函数订阅Provider组件值更新,值更新时渲染订阅组件。

       四. 解惑疑点

       理解代码意图。支持Promise时,使用Promise处理,否则使用setTimeout。了解Promise.prototype.then.bind(Promise.resolve())最终执行的Promise.resolve().then。

       虚拟节点用Fragment包装的原因是,避免直接调用diffElementNodes,以确保子节点正确关联至父节点DOM。

       hydrate与render的区别在于,hydrate仅处理事件,不处理其他props,适用于服务器端渲染的HTML,客户端渲染使用hydrate提高首次渲染速度。

       props中value与checked单独处理,diffProps不处理,处理在diffChildren中,找到原因。

       在props中设置value为空的原因是,遵循W3C规定,不设置value时,文本内容作为value。为避免MVVM问题,需在子节点渲染后设置value为空,再处理元素value。

       组件异常处理机制中,_processingException和_pendingError变量用于标记组件异常处理状态,确保不会重复跳过异常组件。

       diffProps中事件处理机制,为避免重复添加事件监听器,只在事件函数变化时修改dom._listeners,触发事件时仅执行保存的监听函数,移除监听在onChange设置为空时执行。

       理解_nextDom的使用,确保子节点与父节点关联,避免在函数型节点渲染时进行不必要的关联操作。

如何编译ReactNative示例程序Examples

       ã€€ã€€ç¼–译示例程序需要将整个项目导入到androidStudio中,androidStudio导入项目时选择react-native/ReactAndroid目录。

       ã€€ã€€ç”±äºŽé¡¹ç›®ä¾èµ–ndk因此如果要编译Examples还需要安装配置ndk目录,下载ndk后是一个自解压程序,会释放ndk的目录。

       ã€€ã€€ç„¶åŽéœ€è¦è®¾ç½®çŽ¯å¢ƒå˜é‡æˆ–者在react-native根目录下新建local.properties文件,文件内容如下:

       ã€€ã€€sdk.dir=c:\你的sdk目录

       ã€€ã€€ndk.dir=c:\你的ndk目录

       ã€€ã€€è®¾ç½®è¦ä¹‹åŽå°±å¯ä»¥ç¼–译了,导入和编译的过程比较曲折,请继续看下文。

       ã€€ã€€åœ¨ç¼–译AwesomeProject项目时,没有用到ndk,实际上这里的ndk默认情况下并没有用到,只是gradle的设置里有ndk因此必须配置ndk才能导入项目。

       ã€€ã€€ndk是在编译核心库是才用到,核心库位于react-native/ReactAndroid,导入整个项目时以lib形式存在。查看Examples目录下UIExplorer,会发现在build.gradle是以在线的方式导入核心库的。通过源码的方式导入被注释掉了。

       ã€€ã€€dependencies {

       ã€€ã€€compile fileTree(dir: 'libs', include: ['*.jar'])

       ã€€ã€€compile 'com.android.support:appcompat-v7:.0.1'

       ã€€ã€€// Depend on pre-built React Nativecompile 'com.facebook.react:react-native:0..+'

       ã€€ã€€// Depend on React Native source.

       ã€€ã€€// This is useful for testing your changes when working on React Native.

       ã€€ã€€// compile project(':ReactAndroid')

       ã€€ã€€}

       ã€€ã€€ç”±æ­¤å¯çŸ¥ï¼Œç¼–译UIExplorer并不需要ndk,如果你不想设置ndk,有2个办法

       ã€€ã€€1.拷贝AwesomeProject项目中的build.gradle,settings.gradle到UIExplorer的android目录,在导入项目时选择UIExplorer/android就可以了,这样androidStudio会导入单个项目,否则会导入整个项目。

       ã€€ã€€2.用androidStudio新建一个同名的项目,然后把UIExplorer目录中的文件拷贝到新建的项目中。

       ã€€ã€€ç¼–译好之后启动服务器端,到react-native目录下执行:

       ã€€ã€€npm install

       ã€€ã€€node packager\packager.js

       ã€€ã€€windows下如果出现错误需要根据错误提示修改代码blogs.com/zhaojietec/p/.html

       ã€€ã€€ä¸è¿‡éœ€è¦æ³¨æ„çš„是,目前为止,UIExplorer在Android下有一个bug,IOS下没有问题,通过google可以找到了解决办法。/facebook/react-native/issues/

       ã€€ã€€åŽŸå› æ˜¯ï¼Œjs代码和android原生代码不同步,通过build.gradle可以看到android下的引用的reactNative核心库为,而js代码版本已经更新到了。

       ã€€ã€€è§£å†³çš„办法有2个,一个是使用git工具(如smartGit),将js代码恢复到之前的版本,另一个办法是重新编译reactNative的核心库,编译核心库需要ndk,在mac下没有问题,在windows编译会出错。编译reactNative核心库,对UIExplorer下注释掉的依赖项进行修改即可,编译速度较慢 需要在线下载第三方依赖库。

       ã€€ã€€dependencies {

       ã€€ã€€compile fileTree(dir: 'libs', include: ['*.jar'])

       ã€€ã€€compile 'com.android.support:appcompat-v7:.0.1'

       ã€€ã€€// Depend on pre-built React Native//compile 'com.facebook.react:react-native:0..+'

       ã€€ã€€// Depend on React Native source.

       ã€€ã€€// This is useful for testing your changes when working on React Native.

       ã€€ã€€compile project(':ReactAndroid')

       ã€€ã€€}

       ã€€ã€€ç”±äºŽwindows下无法编译,所以这里提供编译好的aar文件,修改UIExplorer build.gradle中的依赖项就可以了。至于如何引入aar文件,可以自行搜索。当然mac下同样也可以用这个aar,可以省去不少麻烦。

畅谈React material-ui的样式方案

       Google 在 年提出了 material design 的设计理念,极具颠覆性,在国外非常受欢迎。各类前端框架也都出现了material design风格的组件库,其中 React 最受欢迎的 material design 风格组件库非 material-ui 莫属。mui-org/material-ui 这个开源库目前收获了 star,npm 的周下载量达到了 万,数据摆在那儿,也不需要继续“吹捧” material-ui 了。本文主要是带大家一起领略一下 material-ui 的样式方案。

       material-ui 将自己的样式方案独立发布成一个 npm 包,叫 @material-ui/styles。它拥抱了CSS-in-JS,据他们的文档,也尝试过使用 LESS 等其他方案,但发现有明显的局限性,最后拥抱了 CSS-in-JS。官方文档宣称material-ui 样式方案有以下优点。

       使用 @material-ui/styles 的样式方案主要支持三种形式的API,但底层的代码和逻辑是一致的。下面是代码示范,通过 makeStyles API,传入一个描述CSS的对象(下面简称css对象),就能得到一个自定义的Hook,通常命名为 useStyles。在函数式组件内调用这个Hook,得到一个对象,通常命名为classes。最后,将classes 对象的“对应值” 赋给 组件的 className 属性,就成功定制了这个组件的样式。细节:classes对象的 root 属性 对应的就是 css对象的 root 属性。下面是代码示范:

       使用 styled API 就能采用类似于 styled-components 的语法,当然还是有区别的 —— styled-components 用的是 es6 tagged template literals 而 material-ui styled API 返回函数的参数是css对象。使用 Higher-order component API 接收一个 css 对象返回一个高阶组件函数。material-ui 的 Higher-order component API 不仅能用于函数组件也能用于类组件,但在 Hook 大行其道后这个 API 慢慢退出舞台了。接下来都只使用 makeStyles API 做后面的代码示范。

       material-ui 上述的API 在底层都会生成一些“随机的html class 名称” 以及 相应的 css 规则。以 上面的 makeStyles demo 为例,会生成以下 css 规则插入到 html head。自定义样式按钮 对应的 html 片段如下。小结:上述这三种形式的API都能定制化组件的样式。查看源码就能发现其实 styled 和 withStyles 底层都调用了makeStyles API。

       在底层原理是动态生成 css 规则插入到 html 中。这三个API的使用方法中,最关键的都是两部分:查看 css 对象的构成和使用。接下来将细聊 css 对象的构成和使用。嵌套选择器:上面的代码可以得到以下效果。实际生成的 css 规则如下。

       根据传入值动态调整:上述的 css 对象并不一定是单纯的简单对象。可以将函数传递给makeStyles (“插值”),这样一来根据组件的属性可以变换生成的样式的值。 此函数可以运用于样式规则的级别,也可以放在 CSS 属性级别。例1和例2展示了如何根据组件属性动态调整样式。

       覆盖样式 —— classes 属性:接下来换个角度,假如你使用 material-ui 样式方案创作了一些组件(提供了默认的样式)并作为公用组件分享给其他模块使用,如何让调用端可自定义这些组件的样式呢?上面提到的根据传入值动态调整 是一种解决方案,但很明显这是一种只允许微调的方案;而且这个方案的实现通常比较繁琐。假如以下是我们设计的一个组件代码。那么我在 Parent 中如何自定义这个 Nested 组件的 span 样式呢?我们可以利用classes属性 覆盖样式。上面的代码中,我们往 useStyles 这个hook中传入 props 作为参数 (其实是为了将 classes 传进去)。而在 Parent 的代码中,我们给 Nested 传入 classes 属性(这个命名是个规范,必须遵守)。最终的效果生成的 html 中 span 的 class 值是 ‘makeStyles-label-2 my-label’ —— 注意 my-label 的顺序在后面,因此它的样式会覆盖前面 makeStyles-label-2 的样式。

       总结:你所在前端项目使用的样式方案还是 LESS, SASS 甚至是 css 吗?material-ui 样式解决方案是不是对你有所冲击或者启示呢?欢迎留言评论。如果觉得文章质量不错,请积极地点赞、喜欢、收藏三连!p.s. material-ui 样式方案中还有其他内容,如主题、JSS 插件等,个人感觉难度比较小,文档也易懂,(或者过于生僻,很少使用),本文就不做介绍了,如果有读者强烈要求写某个部分,我再继续补充。