Today I put together a small test repo to check how much space is saved when replacing React with Preact in a ClojureScript project.
I used npm init shadowfront prtest
to get a basic project up and running. This creates a simple one page Reagent app with a button you can click.
(ns prtest.core
(:require
[reagent.core :as r]
[reagent.dom :as rdom]))
(defonce state (r/atom {}))
(defn component-main [_state]
[:div
[:h1 "prtest"]
[:p "Welcome to the app!"]
[:button {:on-click #(js/alert "Hello world!")}
"click me"]])
(defn start {:dev/after-load true} []
(rdom/render [component-main state]
(js/document.getElementById "app")))
(defn init []
(start))
I made a build to check the size of the resulting js binary. Then I uninstalled react
and react-dom
and installed preact@8
and preact-compat
. Then I updated shadow-cljs.edn
to add the following clause into the :app
build:
:js-options {:resolve {"react" {:target :npm :require "preact-compat"}
"react-dom" {:target :npm :require "preact-compat"}}
This asks shadow-cljs
to alias those React modules to the Preact compatibility layer throughout the whole stack.
I ran make
to build the project before and after the change and got the following results:
- With React = 292k
$ du -hs build/js/main.js
292K build/js/main.js
- With Preact = 172k
$ du -hs build/js/main.js
172K build/js/main.js
A 41% size reduction (120k) for a simple one page app seems pretty good. Most of the remaining 172k would be ClojureScript core and libraries such as Reagent.
Update: shadow-cljs
lets us generate a build report. Here's a build report with React and then Preact:
React ClojureScript build report
Package | Weight | % |
---|---|---|
react-dom @ npm: 18.2.0 | 128.22 KB | 45.8 % |
org.clojure/clojurescript @ mvn: 1.11.60 | 115.71 KB | 41.4 % |
reagent @ mvn: 1.1.0 | 22.93 KB | 8.2 % |
react @ npm: 18.2.0 | 6.49 KB | 2.3 % |
scheduler @ npm: 0.23.0 | 3.96 KB | 1.4 % |
org.clojure/google-closure-library @ mvn: 0.0-20230227-c7c0a541 | 1.12 KB | 0.4 % |
Generated Files | 932 | 0.3 % |
src | 490 | 0.2 % |
Preact ClojureScript build report
Package | Weight | % |
---|---|---|
org.clojure/clojurescript @ mvn: 1.11.60 | 115.61 KB | 71.4 % |
reagent @ mvn: 1.1.0 | 22.94 KB | 14.2 % |
preact-compat @ npm: 3.19.0 | 9.24 KB | 5.7 % |
preact @ npm: 8.5.3 | 8.18 KB | 5.1 % |
preact-context @ npm: 1.1.4 | 2.55 KB | 1.6 % |
org.clojure/google-closure-library @ mvn: 0.0-20230227-c7c0a541 | 1.12 KB | 0.7 % |
Generated Files | 931 | 0.6 % |
prop-types @ npm: 15.8.1 | 801 | 0.5 % |
src | 490 | 0.3 % |