Skip to content

Commit 88e7b47

Browse files
authored
Merge pull request #2876 from zsviczian/reduce-size
Refactoring: main.js size reduction
2 parents 04869e8 + 1616a72 commit 88e7b47

9 files changed

Lines changed: 305 additions & 103 deletions

File tree

RefactorPlan.md

Lines changed: 114 additions & 0 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 2 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,12 @@
3838
"lz-string": "^1.5.0",
3939
"monkey-around": "^2.3.0",
4040
"nanoid": "^5.1.16",
41-
"opentype.js": "^1.3.4",
4241
"pako": "^2.1.0",
4342
"points-on-path": "^0.2.1",
4443
"polybooljs": "^1.2.0",
4544
"react": "^18.2.0",
4645
"react-dom": "^18.2.0",
47-
"roughjs": "^4.5.2",
48-
"yaml": "^2.9.0"
46+
"roughjs": "^4.5.2"
4947
},
5048
"devDependencies": {
5149
"@babel/core": "^7.22.9",
@@ -69,7 +67,6 @@
6967
"@types/chroma-js": "^3.1.1",
7068
"@types/js-beautify": "^1.14.0",
7169
"@types/node": "^22.19.19",
72-
"@types/opentype.js": "^1.3.8",
7370
"@types/react": "^18.2.45",
7471
"@types/react-dom": "^18.2.18",
7572
"@zsviczian/excalidraw-extras-api": "^0.0.13",
@@ -81,7 +78,6 @@
8178
"eslint-plugin-obsidianmd": "^0.4.0",
8279
"eslint-plugin-prettier": "^5.0.0",
8380
"jiti": "^2.6.1",
84-
"jsesc": "^3.0.2",
8581
"obsidian": "1.8.7",
8682
"postcss": "^8.5.25",
8783
"prettier": "^3.0.1",
@@ -111,4 +107,4 @@
111107
"node": ">=22.0.0",
112108
"npm": ">=10.0.0"
113109
}
114-
}
110+
}

rollup.config.mjs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import fs from 'fs';
1010
import path from 'path';
1111
import postprocess from '@zsviczian/rollup-plugin-postprocess';
1212
import cssnano from 'cssnano';
13-
import jsesc from 'jsesc';
1413
import { minify } from 'uglify-js';
1514
import json from '@rollup/plugin-json';
1615
import { parseEnv } from 'node:util';
@@ -103,8 +102,13 @@ const react_pkg = isLib ? "" : minifyCode(isProd
103102
const reactdom_pkg = isLib ? "" : minifyCode(isProd
104103
? fs.readFileSync("./node_modules/react-dom/umd/react-dom.production.min.js", "utf8")
105104
: fs.readFileSync("./node_modules/react-dom/umd/react-dom.development.js", "utf8"));
105+
const reactPackagesCompressed = isLib
106+
? ""
107+
: compressDeflateBase64(react_pkg + reactdom_pkg + jsxRuntimeShim);
106108

107-
const pako_pkg = isLib ? "" : fs.readFileSync("./node_modules/pako/dist/pako.min.js", "utf8");
109+
// Runtime payloads are only decompressed; including Pako's deflate implementation
110+
// would add unused code to the size-constrained Obsidian plugin bundle.
111+
const pako_pkg = isLib ? "" : fs.readFileSync("./node_modules/pako/dist/pako_inflate.min.js", "utf8");
108112

109113
if (!isLib) {
110114
const excalidraw_styles = isProd
@@ -140,10 +144,7 @@ const packageString = isLib
140144
' ' + pako_pkg + '\n' +
141145
' return module.exports;\n' +
142146
'})();\n' +
143-
'\nlet REACT_PACKAGES = `' +
144-
jsesc(react_pkg + reactdom_pkg + jsxRuntimeShim, { quotes: 'backtick' }) +
145-
'`;\n' +
146-
// NEW: Fast, mobile-compatible runtime decompression
147+
// Define the dependency-free inflater before React participates in bootstrap.
147148
'const unpackBase64Deflate = (b64) => {\n' +
148149
' const binStr = atob(b64);\n' +
149150
' const len = binStr.length;\n' +
@@ -152,6 +153,7 @@ const packageString = isLib
152153
' return new TextDecoder().decode(pako.inflate(bytes));\n' +
153154
'};\n' +
154155
'window.unpackBase64Deflate = unpackBase64Deflate;\n' +
156+
'let REACT_PACKAGES = unpackBase64Deflate("' + reactPackagesCompressed + '");\n' +
155157
'const unpackExcalidraw = () => unpackBase64Deflate("' + compressDeflateBase64(excalidraw_pkg) + '");\n' +
156158
'let {react, reactDOM } = new Function(`${REACT_PACKAGES}; return {react: React, reactDOM: ReactDOM};`)();\n' +
157159
'let excalidrawLib = {};\n' +
@@ -292,4 +294,4 @@ if (process.env.NODE_ENV === "lib") {
292294
config.push(BUILD_CONFIG);
293295
}
294296

295-
export default config;
297+
export default config;

src/core/managers/FontManager.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
} from "src/constants/constants";
88
import { t } from "src/lang/helpers";
99
import { getCJKDataURLs } from "src/utils/CJKLoader";
10-
import { getFontDataURL, getFontMetrics } from "src/utils/utils";
10+
import { getFontDataURL } from "src/utils/utils";
11+
import { getFontMetrics } from "src/utils/fontMetrics";
1112
import type ExcalidrawPlugin from "src/core/main";
1213

1314
declare const mainDocument: Document;
@@ -115,17 +116,16 @@ export class FontManager {
115116
this.plugin.settings.experimantalFourthFont,
116117
"",
117118
);
118-
let fontMetrics = file.extension.startsWith("woff")
119+
let fontMetrics = file.extension.startsWith("woff") || !font.arrayBuffer
119120
? undefined
120-
: await getFontMetrics(fourthFontDataURL, "Local Font");
121+
: getFontMetrics(font.arrayBuffer);
121122

122123
if (!fontMetrics) {
123124
fontMetrics = {
124125
unitsPerEm: 1000,
125126
ascender: 750,
126127
descender: -250,
127128
lineHeight: 1.2,
128-
fontName: "Local Font",
129129
};
130130
}
131131
this.getPackageMap().forEach(({ excalidrawLib }) => {

src/utils/embeddedAssetUtils.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ export { getEmbeddedFilenameParts } from "./embeddedFilenameParts";
1313
* @param fontFileName - Vault link path or font filename to resolve.
1414
* @param sourcePath - Vault path from which the font link is resolved.
1515
* @param name - Optional font-family name overriding the file basename.
16-
* @returns The font definition, resolved family name, and encoded data URL.
17-
* Empty strings are returned when the font cannot be resolved.
16+
* @returns The font definition, resolved family name, encoded data URL, and
17+
* original buffer. Empty strings and a null buffer are returned when the font
18+
* cannot be resolved.
1819
* @remarks
1920
* MIME types and CSS format names intentionally preserve the established
2021
* extension mapping used by plugin startup and embedded SVG font loading.
@@ -24,13 +25,19 @@ export async function getFontDataURL(
2425
fontFileName: string,
2526
sourcePath: string,
2627
name?: string,
27-
): Promise<{ fontDef: string; fontName: string; dataURL: string }> {
28+
): Promise<{
29+
fontDef: string;
30+
fontName: string;
31+
dataURL: string;
32+
arrayBuffer: ArrayBuffer | null;
33+
}> {
2834
let fontDef = "";
2935
let fontName = "";
3036
let dataURL = "";
37+
let arrayBuffer: ArrayBuffer | null = null;
3138
const f = app.metadataCache.getFirstLinkpathDest(fontFileName, sourcePath);
3239
if (f) {
33-
const ab = await app.vault.readBinary(f);
40+
arrayBuffer = await app.vault.readBinary(f);
3441
let mimeType = "";
3542
let format = "";
3643

@@ -55,12 +62,12 @@ export async function getFontDataURL(
5562
mimeType = "application/octet-stream";
5663
}
5764
fontName = name ?? f.basename;
58-
dataURL = await getDataURL(ab, mimeType);
65+
dataURL = await getDataURL(arrayBuffer, mimeType);
5966
const split = dataURL.split(";base64,", 2);
6067
dataURL = `${split[0]};charset=utf-8;base64,${split[1]}`;
6168
fontDef = ` @font-face {font-family: "${fontName}";src: url("${dataURL}") format("${format}")}`;
6269
}
63-
return { fontDef, fontName, dataURL };
70+
return { fontDef, fontName, dataURL, arrayBuffer };
6471
}
6572

6673
/**

0 commit comments

Comments
 (0)