Closed syuilo closed 1 year ago
調査中
https://github.com/misskey-dev/misskey/blob/a4a171781b336f85c841846fe78b10715ce97f29/packages/frontend/src/components/MkModal.vue#L4 みたいに動的に使ってる箇所はまあそういう感じにコンパイルされるのも分かるけどそうじゃなく完全に静的に定義されている個所はもっと効率よくビルドできるはずなんだよな
Vue のランタイムを目 grep したところ useCssModule
のためだけにマップを持っていることがわかった
一切の使用を禁止すれば一応マップを取り除くことは可能
みたいに動的に使ってる箇所はまあそういう感じにコンパイルされるのも分かるけどそうじゃなく完全に静的に定義されている個所はもっと効率よくビルドできるはずなんだよな
最適化するなら動的に使うのもやめたいところではある
最適化するなら動的に使うのもやめたいところではある
yes 他にもこんな感じに使ってるとこいくつかあるけど、どれもやりようによっては静的に定義できるからやっていきたい
調査結果
Vue のランタイムを目 grep したところ
useCssModule
のためだけにマップを持っていることがわかった 一切の使用を禁止すれば一応マップを取り除くことは可能
useCssModuleを使っている個所をゼロにすればいい感じにコンパイルされるようになるってこと?
調査結果
Vue のランタイムを目 grep したところ
useCssModule
のためだけにマップを持っていることがわかった 一切の使用を禁止すれば一応マップを取り除くことは可能useCssModuleを使っている個所をゼロにすればいい感じにコンパイルされるようになるってこと?
No
それはそれとしてコンパイラに手を加える必要がある(ただ useCssModule
を使っていると壊れる)
コンパイラに手を加えるというか、ポストプロセッシングする必要があるという方が正しいか
Options API のときは
から
import { a as c, w as u, e as d, o as l, a0 as r } from "./vue-561933f7.js";
import { _ as i } from "./app-c70a3e7b.js";
const p = {
name: "MarqueeText",
props: {
duration: { type: Number, default: 15 },
repeat: { type: Number, default: 2 },
paused: { type: Boolean, default: !1 },
reverse: { type: Boolean, default: !1 },
},
setup(t) {
const e = c();
function a() {
const n = e.value.offsetWidth / t.repeat,
o = 3e3,
s = t.duration / ((1 / n) * o);
e.value.style.animationDuration = `${s}s`;
}
return (
u(() => t.duration, a),
d(() => {
a();
}),
l(() => {}),
{ contentEl: e }
);
},
render({
$slots: t,
$style: e,
$props: { duration: a, repeat: n, paused: o, reverse: s },
}) {
return r("div", { class: [e.wrap] }, [
r(
"span",
{ ref: "contentEl", class: [o ? e.paused : void 0, e.content] },
Array(n).fill(
r(
"span",
{
class: e.text,
style: { animationDirection: s ? "reverse" : void 0 },
},
t.default()
)
)
),
]);
},
},
f = "xhtbz",
m = "xatdo",
x = "xgYHc",
v = "x8M5E",
M = "xclje",
_ = { wrap: f, content: m, text: x, marquee: v, paused: M },
h = { $style: _ },
q = i(p, [["__cssModules", h]]);
export { q as M };
みたいなコードが吐かれるので
import { a as c, w as u, e as d, o as l, a0 as r } from "./vue-561933f7.js";
const p = {
name: "MarqueeText",
props: {
duration: { type: Number, default: 15 },
repeat: { type: Number, default: 2 },
paused: { type: Boolean, default: !1 },
reverse: { type: Boolean, default: !1 },
},
setup(t) {
const e = c();
function a() {
const n = e.value.offsetWidth / t.repeat,
o = 3e3,
s = t.duration / ((1 / n) * o);
e.value.style.animationDuration = `${s}s`;
}
return (
u(() => t.duration, a),
d(() => {
a();
}),
l(() => {}),
{ contentEl: e }
);
},
render({
$slots: t,
$style: e,
$props: { duration: a, repeat: n, paused: o, reverse: s },
}) {
return r("div", { class: "xhtbz" }, [
r(
"span",
{ ref: "contentEl", class: [o ? "xclje" : void 0, "xatdo"] },
Array(n).fill(
r(
"span",
{
class: "xgYHc",
style: { animationDirection: s ? "reverse" : void 0 },
},
t.default()
)
)
),
]);
},
};
export { p as M };
といった感じにポストプロセスできれば良い
(あーMkMarqueeまだoptions apiだったか)
Composition API のときは
から
import { _ as p } from "./MkMiniChart.vue_vue_type_script_setup_true_lang-c405dd11.js";
import { an as _, br as m, _ as h } from "./app-c70a3e7b.js";
import {
b as f,
a as v,
e as M,
z as r,
f as k,
j as y,
g as n,
k as C,
A as c,
l as e,
E as b,
u as t,
h as B,
B as g,
q as N,
} from "./vue-561933f7.js";
const w = { class: "body" },
U = { class: "name" },
V = { class: "sub" },
A = { class: "acct _monospace" },
D = f({
__name: "MkUserCardMini",
props: { user: {}, withChart: { type: Boolean, default: !0 } },
setup(i) {
const o = i;
let a = v(null);
return (
M(() => {
o.withChart &&
_("charts/user/notes", {
userId: o.user.id,
limit: 16 + 1,
span: "day",
}).then((s) => {
s.inc.splice(0, 1), (a.value = s.inc);
});
}),
(s, z) => {
const l = r("MkAvatar"),
u = r("MkUserName"),
d = k("adaptive-bg");
return y(
(n(),
C(
"div",
{
class: N([
s.$style.root,
{
yellow: s.user.isSilenced,
red: s.user.isSuspended,
gray: !1,
},
]),
},
[
c(
l,
{ class: "avatar", user: s.user, indicator: "" },
null,
8,
["user"]
),
e("div", w, [
e("span", U, [
c(u, { class: "name", user: s.user }, null, 8, ["user"]),
]),
e("span", V, [e("span", A, "@" + b(t(m)(s.user)), 1)]),
]),
t(a)
? (n(),
B(p, { key: 0, class: "chart", src: t(a) }, null, 8, [
"src",
]))
: g("", !0),
],
2
)),
[[d]]
);
}
);
},
}),
S = "xqX2u",
$ = { root: S },
q = { $style: $ },
I = h(D, [["__cssModules", q]]);
export { I as M };
みたいなコードが吐かれるので
import { _ as p } from "./MkMiniChart.vue_vue_type_script_setup_true_lang-c405dd11.js";
import { an as _, br as m, _ as h } from "./app-c70a3e7b.js";
import {
b as f,
a as v,
e as M,
z as r,
f as k,
j as y,
g as n,
k as C,
A as c,
l as e,
E as b,
u as t,
h as B,
B as g,
q as N,
} from "./vue-561933f7.js";
const w = { class: "body" },
U = { class: "name" },
V = { class: "sub" },
A = { class: "acct _monospace" },
D = f({
__name: "MkUserCardMini",
props: { user: {}, withChart: { type: Boolean, default: !0 } },
setup(i) {
const o = i;
let a = v(null);
return (
M(() => {
o.withChart &&
_("charts/user/notes", {
userId: o.user.id,
limit: 16 + 1,
span: "day",
}).then((s) => {
s.inc.splice(0, 1), (a.value = s.inc);
});
}),
(s, z) => {
const l = r("MkAvatar"),
u = r("MkUserName"),
d = k("adaptive-bg");
return y(
(n(),
C(
"div",
{
class: N([
"xqX2u",
{
yellow: s.user.isSilenced,
red: s.user.isSuspended,
gray: !1,
},
]),
},
[
c(
l,
{ class: "avatar", user: s.user, indicator: "" },
null,
8,
["user"]
),
e("div", w, [
e("span", U, [
c(u, { class: "name", user: s.user }, null, 8, ["user"]),
]),
e("span", V, [e("span", A, "@" + b(t(m)(s.user)), 1)]),
]),
t(a)
? (n(),
B(p, { key: 0, class: "chart", src: t(a) }, null, 8, [
"src",
]))
: g("", !0),
],
2
)),
[[d]]
);
}
);
},
});
export { D as M };
といった感じにポストプロセスできれば良い
現時点の制約 / 問題点
useCssModule()
を使っているとスタイルが壊れる(検知してキャンセルはできていない)
現在CSS Modulesは以下のようにコンパイルされている
ランタイムでCSS Modulesの元の名前とビルド後のクラス文字列のマッピングを持っておく(かつそのマッピングを元に変換処理をランタイムでやる)必要はないと考えられるので、直接クラス名文字列として埋め込みたい