Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
楽譜フォント(SMuFL)をCloudflareで配信する
Search
Ossamoon
September 11, 2025
Programming
0
59
楽譜フォント(SMuFL)をCloudflareで配信する
Google FontsとCloudflare Fontsから学ぶ配信最適化
Ossamoon
September 11, 2025
Tweet
Share
More Decks by Ossamoon
See All by Ossamoon
SSRアプリケーションにおけるPKCE付き認可コードフロー
ossamoon
0
54
RemixとCloudflare Stack におけるFile Upload
ossamoon
1
360
Other Decks in Programming
See All in Programming
為你自己學 Python - 冷知識篇
eddie
1
350
testingを眺める
matumoto
1
140
実用的なGOCACHEPROG実装をするために / golang.tokyo #40
mazrean
1
250
時間軸から考えるTerraformを使う理由と留意点
fufuhu
15
4.6k
Performance for Conversion! 分散トレーシングでボトルネックを 特定せよ
inetand
0
130
複雑なドメインに挑む.pdf
yukisakai1225
5
1.1k
AIと私たちの学習の変化を考える - Claude Codeの学習モードを例に
azukiazusa1
8
3.5k
もうちょっといいRubyプロファイラを作りたい (2025)
osyoyu
0
400
Testing Trophyは叫ばない
toms74209200
0
850
2025 年のコーディングエージェントの現在地とエンジニアの仕事の変化について
azukiazusa1
22
12k
パッケージ設計の黒魔術/Kyoto.go#63
lufia
3
430
機能追加とリーダー業務の類似性
rinchoku
2
1.2k
Featured
See All Featured
Music & Morning Musume
bryan
46
6.8k
The Art of Programming - Codeland 2020
erikaheidi
55
13k
Gamification - CAS2011
davidbonilla
81
5.4k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
358
30k
Visualization
eitanlees
148
16k
Into the Great Unknown - MozCon
thekraken
40
2k
GraphQLの誤解/rethinking-graphql
sonatard
72
11k
Stop Working from a Prison Cell
hatefulcrawdad
271
21k
How GitHub (no longer) Works
holman
315
140k
Imperfection Machines: The Place of Print at Facebook
scottboms
268
13k
Writing Fast Ruby
sferik
628
62k
Transcript
楽譜フォント(SMuFL) を Cloudflare で配信する 〜Google Fonts とCloudflare Fonts から学ぶ配信最適化〜 2025/09/10
Cloudflare Workers Tech Talks in Tokyo #6 齋藤 修 (Ossamoon)
目的 楽譜もサクサクWeb に配信したい!!しかし、ニッチな分野すぎてエコシステムが成熟していない… 楽譜用のフォントを自前で効率的に配信したい! Google Fonts やCloudflare Fonts のいいところを学んで取り入れたい
目次 1. Google Fonts の配信最適化 2. Cloudflare Fonts の配信最適化 3.
楽譜フォントの標準規格SMuFL の特徴 4. SMuFL のフォントをCloudflare で配信する
目次 1. Google Fonts の配信最適化 2. Cloudflare Fonts の配信最適化 3.
楽譜フォントの標準規格SMuFL の特徴 4. SMuFL のフォントをCloudflare で配信する
Google Fonts の配信最適化 1. <link rel="preconnect"> による事前接続の確立 2. CSS の動的取得によるフォントファイル形式の選択
3. unicode-range によるサブセットの配信 4. text= パラメータによる動的サブセットの配信
None
<link rel="preconnect"> による事前接続の確立 HTML に埋め込む <link> では、CSS を取得させる他に、 preconnect を指定してGoogle
Fonts 関連ドメイ ンのDNS 解決とTLS ハンドシェイクを事前に行う <link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+JP:
[email protected]
&display=swap" rel="stylesheet" />
CSS の動的取得によるフォントファイル形式の選択 fonts.googleapis.com からCSS ファイルを動的に取得する ブラウザごとに対応する最新のフォントファイルを選択する モダンなブラウザであればwoff2 が選ばれる @font-face {
font-family: 'Noto Sans JP'; font-style: normal; font-weight: 400; font-display: swap; src: url(https://fonts.gstatic.com/s/notosansjp/~~中略~~.woff2) format('woff2'); unicode-range: U+25ee8, U+25f23, ~~中略~~, U+2f9f4; } ~~以下略~~
unicode-range によるサブセットの配信 モダンなブラウザではWeb ページ内で使用される文字を自動で認識し、必要なサブセットを自動で取得す る Noto Sans JP の場合… 一つのweight
(文字の太さ)あたり、120 のサブセットに分割 一つのサブセットあたり、対応UniCode 範囲は50~230 個程度で、woff2 ファイルサイズは10~90KB 程度
text パラメータによる動的サブセットの配信 (1/2) CSS 取得時にクエリパラメータ text を指定することで、そのテキストの文字のみを含むサブセットを生成 してくれる 例: https://fonts.googleapis.com/css?family=Noto+Sans&text=Hello
ロゴやキャッチコピーなど、意匠が必要な特定の文字列を繰り返し表示する場合に有効 フォントファイルのサイズを目一杯小さくできる 生成されたサブセットはキャッシュされ、2 回目以降はより高速に配信される
text パラメータによる動的サブセットの配信 (2/2) CSS 生成時に以下の情報がクエリパラメータに格納される kit: 与えられた text に基づくハッシュのような文字列、おそらくキャッシュのkey に利用される
skey: 謎のセキュリティキー v: フォントのバージョン unicode-range は含まず、単一のサブセットで完結 @font-face { font-family: "Noto Sans JP"; font-style: normal; font-weight: 900; font-display: swap; src: url(https://fonts.gstatic.com/l/font?kit=~~中略~~&skey=72472b0eb8793570&v=v55) format("woff2"); }
fonts.gstatic.com fonts.googleapis.com Web サーバー ブラウザ fonts.gstatic.com fonts.googleapis.com Web サーバー ブラウザ
par [preconnect] [preconnect crossorigin] HTML 取得 DNS 解決、TLS ハンドシェイク DNS 解決、TLS ハンドシェイク @font-face CSS 取得 フォントファイル取得
Google Fonts の配信最適化から学べること 1. <link rel="preconnect"> による事前接続の確立 👉 DNS 接続やTLS ハンドシェイクも最適化対象 2.
CSS の動的取得によるフォントファイル形式の選択 👉 モダンブラウザ相手ならWoff2 形式 3. unicode-range によるサブセットの配信 👉 サブセットに分割することで無駄を省くことができる 4. text= パラメータによる動的サブセットの配信 👉 究極の最適化は専用のサブセットを作ること
目次 1. Google Fonts の配信最適化 2. Cloudflare Fonts の配信最適化 3.
楽譜フォントの標準規格SMuFL の特徴 4. SMuFL のフォントをCloudflare で配信する
Cloudflare Fonts の配信最適化 1. HTML 取得時に @font-face のCSS を埋め込み 2.
フォントファイルのURL を書き換えてDNS 解決・TLS ハンドシェイクを省略 注: 現在はbeta 版、かつGoogle Fonts のみ対応
fonts.gstatic.com fonts.googleapis.com Cloudflare ブラウザ fonts.gstatic.com fonts.googleapis.com Cloudflare ブラウザ HTML 取得リクエスト
@font-face CSS 取得 HTML (@font-face CSS 埋め込み) フォント取得リクエスト フォントファイル取得 フォントファイル
Cloudflare Fonts の配信最適化から学べること 1. HTML 取得時に @font-face のCSS を埋め込み 👉 CSS は埋め込んじゃった方が速い
2. フォントファイルのURL を書き換えてDNS 解決・TLS ハンドシェイクを省略 👉 フォントファイルも独自 ドメインから配信した方が速い
目次 1. Google Fonts の配信最適化 2. Cloudflare Fonts の配信最適化 3.
楽譜フォントの標準規格SMuFL の特徴 4. SMuFL のフォントをCloudflare で配信する
楽譜フォントの標準規格SMuFL の特徴 1. 楽譜の記号がUnicode のPrivate Use Area に定義されている 2. 記号の種類ごとに細かくUnicode
の範囲が割り振られている 3. 描画に必要なのはごく一部であることが多い Standard Music Font Layout 、W3C によって策定されている標準規格
楽譜の記号がUnicode のPrivate Use Area に定義され ている Private Use Area (PUA)
は以下の範囲で定義されている独自使用が可能な領域 U+E000 ~U+F8FF: 最も一般的に利用されており、SMuFL もこの領域を利用している U+F0000 ~U+FFFFF U+100000 ~U+10FFFD 理論上はブラウザがフォントとしてレンダリングできるため、一般的なフォントの配信最適化を適用するこ とができる
None
記号の種類ごとに細かくUnicode の範囲が割り振られ ている 楽譜記号が131 の分類に分けて定義されている 例: Clefs (U+E050-U+E07F), Noteheads (U+E0A0-U+E0FF)
サブセットを分割する際にはこの分類に沿って分割することができる
特殊な記号も多く含んでおり、描画に必要なのはごく 一部であることが多い 特定の作曲家しか使っていないような特殊な記号も仕様に含んでいる 例: シュトックハウゼンの臨時記号 (U+ED50-U+ED5F) 例えば、基本的な譜面を描画する場合、必要な記号は50~100 程度 SMuFL 全体では2000
を超える記号が定められているため、必要な記号のみをピックアップしサブセット化 できれば配信最適化に大きく寄与できる
SMuFL の特徴から考える配信最適化の方法 1. 楽譜の記号がUnicode のPrivate Use Area に定義されている 👉 サブセットによる配信最適化が適用でき る 2.
記号の種類ごとに細かくUnicode の範囲が割り振られている 👉 サブセット分割の目安となる 3. 描画に必要なのはごく一部であることが多い 👉 独自のサブセットを生成するとより効率的
目次 1. Google Fonts の配信最適化 2. Cloudflare Fonts の配信最適化 3.
楽譜フォントの標準規格SMuFL の特徴 4. SMuFL のフォントをCloudflare で配信する
SMuFL のフォントをCloudflare で配信する 1. フォントの配信方法 2. 楽譜の描画ライブラリの現状と課題 3. なぜCloudflare か
フォントの配信方法 (1/2) アプリに必要なフォントだけを事前に単一のサブセットとして配信する これができるならこれがいい 事前に必要なフォントが分かっている必要がある unicode-range で分割した複数のサブセットを配信する 描画され得るフォントが、実際に描画されるフォントよりも大きくなりがちなアプリケーションに適用 できる 仕様に基づいて分類しても良いが、Google
Fonts に比べるとサブセットあたりのサイズが小さくなりが ち
フォントの配信方法 (2/2) text パラメータによる動的サブセットの生成 実装難易度が高い DoS 攻撃への対策が必須となる
R2 Cloudflare Workers ブラウザ R2 Cloudflare Workers ブラウザ HTML 取得
(@font-face CSS 埋め込み) フォント取得リクエスト フォントファイル取得 フォントファイル
デモ vexflow がjsdelivr を通して提供しているBravura 独自にサブセットを生成してCloudflare から配信したBravura vexflow とBravura を用いて簡単な楽譜を描画
interface Env { FONT_BUCKET: R2Bucket; } const app = new
Hono<{ Bindings: Env }>(); app.get("/", async (c) => { const object = await c.env.FONT_BUCKET.get("bravura/original-subset.woff2"); if (!object) { return c.json({ error: "Font not found" }, 404); } const headers = new Headers(); object.writeHttpMetadata(headers); headers.set("Content-Type", "font/woff2"); headers.set("Cache-Control", "public, max-age=31536000, immutable"); // キャッシュの設定 return c.body(object.body, { headers }); });
楽譜の描画ライブラリの現状と課題 JS 環境で楽譜の描画を行うライブラリは複数存在する vexflow abcjs verovivo いずれも最終的にsvg やcanvas 内にpath として描画するため、ブラウザがフォントのUnicode
を認識できな い ブラウザネイティブな描画ロジックを持つライブラリの登場が待たれる
なぜCloudflare か 安い 大量のトラフィックを捌いても安い 柔軟なキャッシュコントロール Workers を挟めるのでサブセットごとに細かくキャッシュ時間等を指定できる デプロイしやすさ マイナーなフォントでもためらいなくデプロイできる
終わり ご清聴ありがとうございました