DecompressionStreamでJSを解凍します
Why
64KB制限
1ファイル
バイナリを別ファイルにするなどは禁止
httpサーブなし
当然gzipは効きません
--allow-file-access-from-files はお情けでオッケー
バカじゃねーの
Related Works
Our Method
htmlは末尾にバイナリでペイロード入れてもちゃっかり動いてしまうため、JsExeと同じようなことができる Working Code
code:js
const { readFileSync, writeFileSync } = require( 'fs' );
const { resolve } = require( 'path' );
const zlib = require( 'zlib' );
const inputPath = resolve( process.cwd(), process.argv 2 ); const outputPath = resolve( process.cwd(), process.argv 3 ); const inputFile = readFileSync( inputPath );
const compressed = zlib.deflateSync( inputFile, {
level: 9,
} );
const header = '<script>fetch("#").then(t=>t.blob()).then(t=>new Response(t.slice(156).stream().pipeThrough(new DecompressionStream("deflate"))).text()).then(eval)</script>';
const headerBuffer = Buffer.alloc( header.length );
headerBuffer.write( header );
writeFileSync( outputPath, concated );
localhost ・ --allow-file-access-from-files ともに問題なく動きます
Comparison
jsexe: 54,519 bytes
これ: 56,578 bytes
だめじゃん
解散
敗因
PNGOUTの公式サイト 見に行ったら、なんか「その辺のソフトより強い圧縮してるよ」とか書いてあるので、たぶん強いんだと思う zopfliで再戦
code:js
const compressed = zopfli.zlibSync( inputFile, {
numiterations: 100,
blocksplitting: true,
} );
Comparison (2)
jsexe: 54,519 bytes
これ: 54,174 bytes
ウオオオオオオオオオオオオ!!!!!!
jsexeの時代、終わり!
Compatibility
Firefoxが対応してない
知らね~~~~~~~~!!!!!!
Update 2023-05: Firefoxも対応しました!
Future Works
FirefoxのDecompression Stream対応を祈る
Mozillaさんの気分は "worth prototyping" とのことです 🔗 より短いヘッダコード
全然考えてないのでまだまだ短くなるはず
より強い圧縮アルゴリズム
実現した場合、Domainが 47,358 bytes に圧縮されるらしいです
glTFみたいに複数のbufferviewにする?
複数のバイナリをがっちゃんこして、チャンクの一部を参照してコード、他の一部を参照して画像アセット……
現状、画像データや音声データはbase64で文字列として格納されているので、これで多少はサイズが小さくなる可能性がある
いや結局デコード部分のコード含めたらそうでもないかも……?
gist
Update 2022-08-15: fetchcrunch
zopfliで固めたjsをDecompressionStreamで読む感じ
one-knob-cyberiaを圧縮してみたところ、同じzopfliのイテレーションでcompekoのほうがわずかに小さかった(4,094 vs. 4,099) 俺の勝ち ただ、ヘッダを見るともうちょっと差がついても良いんじゃないかなという感じだった たぶんdeflateのバイナリ部分がfetchcrunchのほうがもっと小さい
現状、node-zopfliのzopfliのバージョンはv1.0.2らしいが、fetchcrunchのほうが新しいzopfli(v1.0.3)を使っているっぽいので、その差かもしれんね
https://media.discordapp.net/attachments/534447164043165700/1008701322436038696/unknown.png?width=138&height=262 https://media.discordapp.net/attachments/534447164043165700/1008701322863841360/unknown.png?width=137&height=220
ヘッダの改善
fetchcrunchを読んでみると、compekoのヘッダにいくつか改善点が見つかったので、改善してみた
<script></script> → <svg onload="">
かしこすぎ
fetch("#") → fetch\`#\`
これはシンプルに記法を知らなかった
deflate → deflate-raw
以下、改善版compeko
deflateのヘッダも合わせて6 bytesの削減です やったね
https://gyazo.com/f2800ac4943f1f4de06d73af9eeb7f56