问题
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的配置可能很复杂 。有时候,你可能想要更轻量级的体验,这就是Preact存在的原因。
Preact虽然与React相似,但是体积更小。在撰写本书时,主要的Preact库大约只有4KB,为了实现在前端页面里增添类似于React的特性,这比直接写原生代码多不了多少代码。
Preact有两种使用方式:一种是在页面中当作一个独立的库引用(no-tools方式),另一种是作为一个框架搭建整套应用程序。
no-tools方式是一种基础方式。核心Preact库不支持JSX,也没有Babel支持,因此你无法使用高级一些的JavaScript用法。下面是一个只引入Preact库的代码示例:
这个应用程序将组件实例挂载到ID为root的<div>标签上,显示的效果是一个按钮。当你单击这个按钮时,它会用字符串"Hello"替换ID为root的标签里的内容,这是Preact应用程序最基本的功能。
但一般情况下,你不会使用这种方式,而更有可能使用preact-cli脚手架来创建可以运用JavaScript高级功能的应用程序。
Preact支持所有的JavaScript应用程序。另一个极端是,你可以使用preact-cli创建一个完整的Preact应用程序。
preact-cli是一个创建Preact应用程序的脚手架工具,类似于create-react-app。你可以使用以下方法创建Preact应用程序:
这个命令使用的是默认模板,当然你也可以使用其他模板,例如,Material风格组件模板或TypeScript的模板。更多信息请参见Preact GitHub页面( https://oreil.ly/IVQua )。
这个命令将在 my-app 子目录中创建新的Preact应用程序。要启动它,可以运行dev命令:
服务器将在端口8080上运行,如图1-7所示。
图1-7:来自Preact的页面
服务器会提供一个由 src/index.js 作为入口导出的JavaScript包所生成的网页。
现在,应用程序看起来就和React应用程序差不多。例如,Home组件内部的代码( src/routes/home/index.js )看起来就很有React风格,而且也完全支持JSX:
与标准React应用程序的唯一的显著区别是,名为h的函数是从preact库中导入的,而不是从react库中导入React。
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命令:
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 )。