![React Cookbook中文版:87个案例带你精通React框架](https://wfqqreader-1252317822.image.myqcloud.com/cover/471/47491471/b_47491471.jpg)
1.5 用Preact创建轻量级应用程序
问题
React应用程序的体积可能会很大。即使创建的是简单的React应用程序,其编译后的代码包也可能有几百KB。所以你可能想要创建一个类似React,但体积小得多的应用程序。
解决方案
如果你想保留React的特性,但又不想用React那么大的JavaScript包,那么可以考虑使用Preact。
Preact不是React。它是一个独立的库,虽然被设计得尽可能接近React,但更轻量化。
React框架如此庞大的原因在于它的工作方式。React组件不会直接在浏览器的DOM(Document Object Model,文档对象模型)中生成元素。相反,它们在虚拟DOM中创建元素,然后定期更新实际DOM。这样做可以使基本的DOM渲染更快,因为实际DOM只需要在实际发生更改时更新。然而,它也有缺点。React的虚拟DOM要保持最新的话,需要大量代码。类似于浏览器中的模型,它需要管理整个合成事件模型。考虑到这个原因,React框架体积较大,加载耗时也更长。
解决这个问题的一种方法是使用SSR(服务端渲染)之类的技术,但SSR的配置可能很复杂注5。有时候,你可能想要更轻量级的体验,这就是Preact存在的原因。
Preact虽然与React相似,但是体积更小。在撰写本书时,主要的Preact库大约只有4KB,为了实现在前端页面里增添类似于React的特性,这比直接写原生代码多不了多少代码。
Preact有两种使用方式:一种是在页面中当作一个独立的库引用(no-tools方式),另一种是作为一个框架搭建整套应用程序。
no-tools方式是一种基础方式。核心Preact库不支持JSX,也没有Babel支持,因此你无法使用高级一些的JavaScript用法。下面是一个只引入Preact库的代码示例:
![](https://epubservercos.yuewen.com/2E539C/26886944502812306/epubprivate/OEBPS/Images/31_01.jpg?sign=1738860402-IMt60PdQYCYaLOxexbHS7KkSbSOgnE0A-0-e754747a0b767366adfbe6b08e94bb7e)
这个应用程序将组件实例挂载到ID为root的<div>标签上,显示的效果是一个按钮。当你单击这个按钮时,它会用字符串"Hello"替换ID为root的标签里的内容,这是Preact应用程序最基本的功能。
但一般情况下,你不会使用这种方式,而更有可能使用preact-cli脚手架来创建可以运用JavaScript高级功能的应用程序。
Preact支持所有的JavaScript应用程序。另一个极端是,你可以使用preact-cli创建一个完整的Preact应用程序。
preact-cli是一个创建Preact应用程序的脚手架工具,类似于create-react-app。你可以使用以下方法创建Preact应用程序:
![](https://epubservercos.yuewen.com/2E539C/26886944502812306/epubprivate/OEBPS/Images/31_03.jpg?sign=1738860402-pauCbAEEfrcpsGziPgYyzrbAx56fztfs-0-9fcb2c694b16197a815018676ff96d8c)
![](https://epubservercos.yuewen.com/2E539C/26886944502812306/epubprivate/OEBPS/Images/31_02.jpg?sign=1738860402-7cidi2Eat5kb2ciunoCNYG4AimXzjjzu-0-205466ada567a5ee108155a390dd73ab)
这个命令使用的是默认模板,当然你也可以使用其他模板,例如,Material风格组件模板或TypeScript的模板。更多信息请参见Preact GitHub页面(https://oreil.ly/IVQua)。
这个命令将在my-app子目录中创建新的Preact应用程序。要启动它,可以运行dev命令:
![](https://epubservercos.yuewen.com/2E539C/26886944502812306/epubprivate/OEBPS/Images/32_01.jpg?sign=1738860402-f19bAcMHCsRFr61hVS8s69ARZhejZXQy-0-c1077d64634a4a59e122e8739660ecff)
服务器将在端口8080上运行,如图1-7所示。
![](https://epubservercos.yuewen.com/2E539C/26886944502812306/epubprivate/OEBPS/Images/32_02.jpg?sign=1738860402-aEtdYIVGrQx9Qx3c3w7KX8JKFH6Flq0V-0-50247ec341c561287d1e76990dce7d50)
图1-7:来自Preact的页面
服务器会提供一个由src/index.js作为入口导出的JavaScript包所生成的网页。
现在,应用程序看起来就和React应用程序差不多。例如,Home组件内部的代码(src/routes/home/index.js)看起来就很有React风格,而且也完全支持JSX:
![](https://epubservercos.yuewen.com/2E539C/26886944502812306/epubprivate/OEBPS/Images/32_03.jpg?sign=1738860402-PO4ltf4yCvSWvhmNRKKkpgNlPbZlMm9R-0-4d01d01f59031294c187f18bde55991d)
与标准React应用程序的唯一的显著区别是,名为h的函数是从preact库中导入的,而不是从react库中导入React。
![](https://epubservercos.yuewen.com/2E539C/26886944502812306/epubprivate/OEBPS/Images/32_04.jpg?sign=1738860402-PFDsrl7qavUciWRlr7i4F8i4LXjLp3K1-0-9db37fd7b89ff196b1f94101979f459a)
Preact代码中的JSX将被转换为对h函数的一系列调用,这就是需要导入h函数的原因。考虑到同样的原因,在版本17之前使用create-react-app创建的应用程序也需要导入react对象。版本17之后的create-react-app转而使用JSX转换(https://oreil.ly/HOwS9),这样就避免了每次都需要导入react的问题。Preact的未来版本也有可能做出类似的改变。
但是,应用程序的体积也增大了:现在略超过300KB。这其实就很大了,但我们仍然处于开发模式。要了解Preact的真正威力,请按<Ctrl+C>键停止开发模式服务,然后运行build命令:
![](https://epubservercos.yuewen.com/2E539C/26886944502812306/epubprivate/OEBPS/Images/33_01.jpg?sign=1738860402-0CldMRGayCuErWHKDbbkp4KdabhrgwXH-0-4fde260d31aa53b4abf5ac7159dcf314)
build命令会预渲染应用程序,并在build目录中创建页面的静态HTML。首先,预渲染静态页面的方式可以让你的主页快速加载。其次,它将从应用程序中删除所有未使用的代码,并对代码进行压缩。将应用程序部署在Web服务器上后,浏览器首次访问页面只需加载50~60KB。
讨论
Preact是一个非常棒的项目。尽管原理与React不同,但它只用React的一小部分体积就几乎实现了相同的功能。Preact的应用场景十分丰富,无论是单独引入还是作为复杂单页面应用的框架,其都能胜任。这也意味着,如果应用程序的体积至关重要,那么此时Preact是非常值得考虑的。
你可以在Preact网站(https://preactjs.com)上找到更多关于Preact的信息。
你可以从GitHub网站下载no-tools示例(https://oreil.ly/N9PKf)和更大的Preact示例(https://oreil.ly/F0tW9)的源代码。
如果你想让Preact看起来更像React,那么请查看preact-compat(https://oreil.ly/3YXOv)库。最后,还有一个类似于Preact的框架:InfernoJS(https://infernojs.org)。