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
74
楽譜フォント(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
370
Other Decks in Programming
See All in Programming
ててべんす独演会〜Flowの全てを語ります〜
tbsten
1
220
複雑化したリポジトリをなんとかした話 pipenvからuvによるモノレポ構成への移行
satoshi256kbyte
1
790
Web技術を最大限活用してRAW画像を現像する / Developing RAW Images on the Web
ssssota
2
1.2k
Advance Your Career with Open Source
ivargrimstad
0
340
実践AIチャットボットUI実装入門
syumai
7
2.5k
Your Perfect Project Setup for Angular @BASTA! 2025 in Mainz
manfredsteyer
PRO
0
130
フロントエンド開発に役立つクライアントプログラム共通のノウハウ / Universal client-side programming best practices for frontend development
nrslib
7
3.9k
Back to the Future: Let me tell you about the ACP protocol
terhechte
0
130
CSC509 Lecture 03
javiergs
PRO
0
330
AIで開発生産性を上げる個人とチームの取り組み
taniigo
0
130
株式会社 Sun terras カンパニーデック
sunterras
0
230
Swift Concurrency - 状態監視の罠
objectiveaudio
2
460
Featured
See All Featured
Site-Speed That Sticks
csswizardry
11
880
Testing 201, or: Great Expectations
jmmastey
45
7.7k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
36
2.5k
Building a Modern Day E-commerce SEO Strategy
aleyda
43
7.7k
Large-scale JavaScript Application Architecture
addyosmani
514
110k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
248
1.3M
Building Better People: How to give real-time feedback that sticks.
wjessup
368
20k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
Navigating Team Friction
lara
189
15k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
Speed Design
sergeychernyshev
32
1.1k
Building an army of robots
kneath
306
46k
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 を挟めるのでサブセットごとに細かくキャッシュ時間等を指定できる デプロイしやすさ マイナーなフォントでもためらいなくデプロイできる
終わり ご清聴ありがとうございました