不使用React来使用JSX
尝试不使用React使用JSX。
这里是我们进行过各种实验的代码库。
简洁的页面
这是一个已经完成的捆绑包。
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>My App</title>
<script defer="defer" src="bundle.js"></script>
</head>
<body>
<h1>Hello World</h1>
<div id="root"></div>
</body>
</html>
(()=>{
"use strict";
const e = (t,n)=>{
Array.isArray(n) ? n.forEach((n=>e(t, n))) : ((e,t)=>{
e.appendChild(t?.nodeType ? t : document.createTextNode(t))
}
)(t, n)
}
, t = (t,n)=>{
const {children: r} = n;
if ("function" == typeof t)
return t(n, r);
const o = document.createElement(t);
return Object.entries(n || {}).forEach((([e,t])=>{
e.startsWith("on") && e.toLowerCase()in window ? o.addEventListener(e.toLowerCase().substr(2), t) : o.setAttribute(e, t)
}
)),
e(o, r),
o
}
, n = ({children: e, onClick: n})=>t("button", {
onClick: n,
children: e
});
document.getElementById("root").appendChild(t((()=>t("div", {
children: t(n, {
onClick: ()=>alert(1),
children: "Click 1"
})
})), {}))
}
)();
这两个文件总共大小为801字节!很轻量哦。
根据Google PageSpeed Insights,得分为100分!
我们从参考链接中借用了jsx的运行时。
const add = (parent, child) => {
parent.appendChild(child?.nodeType ? child : document.createTextNode(child));
};
const appendChild = (parent, child) => {
if (Array.isArray(child)) {
child.forEach((nestedChild) => appendChild(parent, nestedChild));
} else {
add(parent, child);
}
};
export const jsx = (tag, props) => {
const { children } = props;
if (typeof tag === "function") return tag(props, children);
const element = document.createElement(tag);
Object.entries(props || {}).forEach(([name, value]) => {
if (name.startsWith("on") && name.toLowerCase() in window) {
element.addEventListener(name.toLowerCase().substr(2), value);
} else {
element.setAttribute(name, value);
}
});
appendChild(element, children);
return element;
};
export const jsxs = jsx;
稍微复杂的页面
只需显示200个待办事项清单的页面。
页面速度似乎没有问题。
import { Button } from "./Button";
import { todos } from "./data";
const App = () => {
// 代入だと動かない。fetchしたものを代入するにはdocumentAPI使うしかない?
// let todo = [];
// fetch("https://jsonplaceholder.typicode.com/todos")
// .then(response => response.json())
// .then(json => {
// console.log(json);
// todo = json;
// })
return (
<div>
<Button onClick={() => alert(1)}>Click 1</Button>
{todos.length > 0 && <table>
{todos.map((item) => {
return <tr><td>{item.id}</td><td>{item.title}</td></tr>;
})}
</table>}
</div>
)
}
const rootElement = document.getElementById("root");
rootElement.appendChild(<App />);
export default App;
有没有一种方法可以尝试使用fetch并查看其运行情况呢?
如果只是一个包含现有数据的静态页面,可能没有问题。
我不知道如何使用useState()之类的赋值方法。
回应
$ npx create-react-app react-app
使用React的最简单配置创建的页面
构建文件夹的大小为518kb,但性能非常好。
当在这里添加了很多东西时,性能就会下降…所有的一切都取决于人的手。
总的来说/总结一下
因为将518千字节转换为801字节,也许可以尝试一下吗…?
我认为如果是真正的静态页面,不再使用setState之类的语法也没有问题,而且如果使用React、React-static等生成的页面也会很轻量化,甚至可以考虑使用Preact之类的库。
以下是可供參考的資料。
import { Page } from '@nakedjsx/core/page'
我本来想在上面简单地应用,但最终发现如果不进行转译或捆绑等工作,可能无法将源代码上传到Qiita(使用GitHub Pages),所以只是参考了一下。
我在babel/webpack方面参考了这份资料。
我是根据原版官方文档参考来理解了 react/jsx-runtime 的相关内容。
参考素材:将Webpack引入纯净版的React的方法