Skip to content

feat(frontend): URLプレビューでsummary_large_image形式の大きいカード表示に対応#17392

Open
chan-mai wants to merge 36 commits into
misskey-dev:developfrom
chan-mai:feat/url-preview-large-image-card
Open

feat(frontend): URLプレビューでsummary_large_image形式の大きいカード表示に対応#17392
chan-mai wants to merge 36 commits into
misskey-dev:developfrom
chan-mai:feat/url-preview-large-image-card

Conversation

@chan-mai

Copy link
Copy Markdown
Contributor

What

リンクプレビューで twitter:card = summary_large_image 相当の大きいカード表示に対応する。

変更内容:

  • @misskey-dev/summaly を 5.3.0 → 5.4.0 に更新。summaly が thumbnailStyle: 'summary' | 'summary_large_image' | null を返すようになった (misskey-dev/summaly#66)
  • MkUrlPreview.vuethumbnailStyle === 'summary_large_image' のとき、サムネイルを上部全幅 (16:9) で表示する大きいカードレイアウトに切り替える。画像は元解像度で取得する(preview=1 パラメータを除去)
  • ユーザー設定「URLプレビューを常にコンパクト表示にする」を追加(環境設定 > タイムラインとノート)。オンにすると summary_large_image 指定があっても従来の小さいカードで表示する

Before / After:

Before After
どんなリンクも一律で左 100px サムネイル + 本文の小さいカード summary_large_image 指定のリンクは上部全幅サムネイル + 本文の大きいカードで表示

Why

現行の実装はリンク先の種別に関わらず一律で同じ小さなカードに収束してしまい、リンク先ごとの性質を反映した見せ方ができない。twitter:card = summary_large_image にフォールバックする形であれば、既に OGP を整備しているサイトに追加対応を求めずに恩恵を出せる。

Related: #17391

Additional info (optional)

Checklist

  • Read the contribution guide
  • Test working in a local environment
  • (If needed) Add story of storybook
  • (If needed) Update CHANGELOG.md
  • (If possible) Add tests

@github-actions github-actions Bot added packages/frontend Client side specific issue/PR packages/backend Server side specific issue/PR labels May 11, 2026
@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label May 11, 2026
@github-actions

github-actions Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

このPRによるapi.jsonの差分
差分はありません。
Get diff files from Workflow Page

@codecov

codecov Bot commented May 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 31.25000% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 25.14%. Comparing base (c29a3d9) to head (abf51e8).
⚠️ Report is 40 commits behind head on develop.

Files with missing lines Patch % Lines
packages/frontend/src/components/MkUrlPreview.vue 36.36% 12 Missing and 2 partials ⚠️
packages/frontend-shared/js/media-proxy.ts 0.00% 4 Missing ⚠️
.../backend/src/server/file/FileServerProxyHandler.ts 66.66% 1 Missing ⚠️
packages/frontend/src/components/MkLink.vue 0.00% 1 Missing ⚠️
packages/frontend/src/components/MkNote.vue 0.00% 1 Missing ⚠️
packages/frontend/src/composables/use-note.ts 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           develop   #17392       +/-   ##
============================================
+ Coverage    15.00%   25.14%   +10.14%     
============================================
  Files          248     1170      +922     
  Lines        12402    39615    +27213     
  Branches      4224    10947     +6723     
============================================
+ Hits          1861     9963     +8102     
- Misses        8239    23767    +15528     
- Partials      2302     5885     +3583     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented May 11, 2026

Copy link
Copy Markdown
Contributor

⚙️ Backend Memory Usage Report

After GC

Metric Base Head Δ median Δ MAD Δ min Δ max
HeapUsed 72.6 MB
± 0 MB
72.6 MB
± 0 MB
$\text{+0 MB}$
$\text{+0\%}$
0 MB $\text{-0 MB}$ $\text{+0 MB}$
Pss 291.8 MB
± 0.7 MB
294.9 MB
± 2 MB
$\color{orange}{\text{+3.2 MB}}$
$\color{orange}{\text{+1.1\%}}$
4.7 MB $\color{green}{\text{-2.7 MB}}$ $\color{orange}{\text{+7.9 MB}}$
Private_Dirty 230.3 MB
± 0.6 MB
233.5 MB
± 1.5 MB
$\color{orange}{\text{+3.2 MB}}$
$\color{orange}{\text{+1.4\%}}$
4.6 MB $\color{green}{\text{-2.7 MB}}$ $\color{orange}{\text{+7.8 MB}}$
VmRSS 329.6 MB
± 0.6 MB
332.8 MB
± 2 MB
$\color{orange}{\text{+3.2 MB}}$
$\color{orange}{\text{+1\%}}$
4.7 MB $\color{green}{\text{-2.7 MB}}$ $\color{orange}{\text{+7.9 MB}}$
External 8.7 MB
± 0 MB
8.7 MB
± 0 MB
0 MB
0%
0 MB 0 MB 0 MB

V8 Heap Snapshot Statistics

Metric Base Head Δ median Δ MAD Δ min Δ max
$\color{gray}{\rule{8pt}{8pt}}$ Total 86 MB
± 5.8 KB
86 MB
± 3 KB
$\text{+5 KB}$
$\text{+0\%}$
2.9 KB $\text{-13 KB}$ $\text{+8.3 KB}$
$\color{orange}{\rule{8pt}{8pt}}$ Code28.8% → 28.8%
25 MB 25 MB $\text{+3.6 KB}$ 3.6 KB $\text{-10 KB}$ $\text{+7.5 KB}$
$\color{red}{\rule{8pt}{8pt}}$ Strings34.8% → 34.8%
30 MB 30 MB $\text{-960 B}$ 944 B $\text{-1.9 KB}$ $\text{+2 KB}$
$\color{cyan}{\rule{8pt}{8pt}}$ JS arrays4.8% → 4.8%
4.1 MB 4.1 MB 0 B 0 B 0 B 0 B
$\color{green}{\rule{8pt}{8pt}}$ Typed arrays0.6% → 0.6%
533 KB 533 KB 0 B 0 B 0 B 0 B
$\color{yellow}{\rule{8pt}{8pt}}$ System objects2.6% → 2.6%
2.2 MB 2.2 MB $\text{-224 B}$ 824 B $\text{-1 KB}$ $\text{+1.8 KB}$
$\color{violet}{\rule{8pt}{8pt}}$ Other JS objs28.4% → 28.4%
24 MB 24 MB $\text{-136 B}$ 72 B $\text{-208 B}$ $\text{-32 B}$
$\color{pink}{\rule{8pt}{8pt}}$ Other non-JS objs0% → 0%
39 KB 39 KB 0 B 0 B 0 B 0 B
Head heap snapshot composition
%%{init: {"sankey":{"showValues":false,"linkColor":"target","labelStyle":"outlined","nodeAlignment":"center","nodePadding":10,"nodeColors":{"Head":"#888888","code":"#f28e2c","bytecode":"#f28e2c","Other":"#888888","strings":"#e15759","string":"#e15759","jsArrays":"#76b7b2","typedArrays":"#59a14f","systemObjects":"#edc949","otherJsObjects":"#af7aa1","otherNonJsObjects":"#ff9da7"}}}}%%
sankey-beta
"Head","Code",28.81
"Code","bytecode",9.57
"Code","Other",19.24
"Head","Strings",34.75
"Strings","string",34.06
"Strings","Other",0.7
"Head","JS arrays",4.81
"Head","Typed arrays",0.62
"Head","System objects",2.58
"Head","Other JS objs",28.38
"Head","Other non-JS objs",0.04
Loading

Download representative V8 heap snapshot (head)

Runtime Loaded JS Footprint

Click to show
Metric Base Head Δ Δ (%)
Loaded JS modules 186 186 0 0%
Loaded JS source 11 MB 11 MB $\color{green}{\text{-500 B}}$ $\color{green}{\text{-0\%}}$
External packages loaded 30 30 0 0%
Native addon packages 2 2 0 0%

Largest Newly Loaded Modules

Module Package Loaded JS
packages/backend/built/ServerService-C4gqW2U5.js backend 977 KB
packages/backend/built/master-Ou6xzZVM.js backend 5.9 KB
packages/backend/built/common-BuL1H6fl.js backend 1.3 KB
packages/backend/built/MainModule-BkzHHzXC.js backend 1.2 KB
packages/backend/built/ServerService-Cz4qElE0.js backend 75 B

@syuilo

syuilo commented May 12, 2026

Copy link
Copy Markdown
Member

スクリーンショットなどあれば助かります 🙏🏻

@chan-mai

Copy link
Copy Markdown
Contributor Author

このような表示になります!

image

@kakkokari-gtyih

kakkokari-gtyih commented May 12, 2026

Copy link
Copy Markdown
Member

preview外した場合でも画像の縮小ってされてたかしら
サイト管理者がog imageにGIFを貼っていたり、解像度のめちゃくちゃでかい画像を貼っていた場合にあれかもしれない

画像プロキシに thumbnail オプションを生やして1280x720くらいに縮小してGIF解除して返す(or DriveFile.thumbnailUrlと同等の圧縮・サイズ変更を掛ける)と良いのかも

@kakkokari-gtyih

Copy link
Copy Markdown
Member

あとMkUrlPreviewPopupでは強制的にsummary相当で出すようにする必要がありそう

@poppingmoon

Copy link
Copy Markdown
Contributor

リンクが複数あるときの表示が気になります
TwitterやBlueskyではリンクが複数あってもカードは1つしか表示されませんが、Misskeyではすべてのリンクに対してプレビューが表示されるので、かなり大きな面積を占めることになるのではないかと思います

現在の実装では、リンクが4つ以上あるノートは折りたたまれることになっていますが、この条件についても考える必要がありそうです

if (urls.length >= 4) {
return true;
}

@chan-mai

Copy link
Copy Markdown
Contributor Author

リンクが複数あるときの表示が気になります
TwitterやBlueskyではリンクが複数あってもカードは1つしか表示されませんが、Misskeyではすべてのリンクに対してプレビューが表示されるので、かなり大きな面積を占めることになるのではないかと思います
現在の実装では、リンクが4つ以上あるノートは折りたたまれることになっていますが、この条件についても考える必要がありそうです

Twitter同様、先頭のURLのみ埋め込み、残りはリンクテキストとしたほうがいいんでしょうか?

@poppingmoon

Copy link
Copy Markdown
Contributor

[]()?[]() が別々にあることを考えると、リンクを貼ったのにプレビューが出ない(ことがある)というのはあまり好まれないかもしれないと思いました

対案としては、リンクが一定数以上あるときはすべて細くするとか、カルーセルにしてスワイプできるようにするとかは思いつきました

@kakkokari-gtyih

kakkokari-gtyih commented May 12, 2026

Copy link
Copy Markdown
Member

プレビュー対象になるリンクが2件以上の場合はsummary相当にするのが丸い気がしなくもない
あと添付メディアがあって、かつプレビュー対象のリンクが1つでもある場合もsummary相当になるか

@chan-mai

Copy link
Copy Markdown
Contributor Author

一旦2件以上の場合はsummary相当になる形で実装してみます🙌🏻

@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels May 12, 2026
@chan-mai

Copy link
Copy Markdown
Contributor Author
image

とりあえずこんな感じになりました

@chan-mai

Copy link
Copy Markdown
Contributor Author

ああsubmoduleでCIコケちゃった
なおします

@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels May 12, 2026
@dosubot dosubot Bot removed the size:M This PR changes 30-99 lines, ignoring generated files. label May 12, 2026
@kakkokari-gtyih

Copy link
Copy Markdown
Member

👀

@poppingmoon

Copy link
Copy Markdown
Contributor

画面の幅が小さいときの表示が崩れています

@poppingmoon

Copy link
Copy Markdown
Contributor

キャッシュされていないURLを表示するときにレイアウトシフトが発生することがありそうです

video.mov

@kakkokari-gtyih

kakkokari-gtyih commented Jul 12, 2026

Copy link
Copy Markdown
Member

キャッシュされていないURLを表示するときにレイアウトシフトが発生することがありそうです

これどうしようもないのでは(n秒以内にリクエストが完了しなければ強制的に小さい表示にするとか?)

@kakkokari-gtyih

kakkokari-gtyih commented Jul 12, 2026

Copy link
Copy Markdown
Member

画面の幅が小さいときの表示が崩れています

再現しなかった(Windows Chrome, Emulated Pixel 7)

@chan-mai

chan-mai commented Jul 12, 2026

Copy link
Copy Markdown
Contributor Author

画面の幅が小さいときの表示が崩れています

私も確認してみましたが再現しませんでした(Mac Safari/Chrome)

@poppingmoon

Copy link
Copy Markdown
Contributor

macOSのChromeとFirefoxとSafariで確認しました

@kakkokari-gtyih

Copy link
Copy Markdown
Member

再現した
compactforceCompactCard があってややこしくなってそう

@kakkokari-gtyih

Copy link
Copy Markdown
Member

foxed

@syuilo

syuilo commented Jul 14, 2026

Copy link
Copy Markdown
Member

/preview

@syuilo

syuilo commented Jul 14, 2026

Copy link
Copy Markdown
Member

読み込んだ時にレイアウトシフトが発生するのがちょっと気になりますね

@syuilo

syuilo commented Jul 14, 2026

Copy link
Copy Markdown
Member

Webサイト管理者として、自分のWebサイトのプレビューが表示されて欲しいけども小さく表示したい、というシチュエーションってよくあることでしょうか?

@syuilo

syuilo commented Jul 14, 2026

Copy link
Copy Markdown
Member

もしあまりないのであれば、サイトごとにプレビューの大きさを指示できるようにするのではなく、一律に(表示するユーザー側で)プレビューを大きく表示するか小さく表示するか選べるだけの方がレイアウトシフトも発生しなくてシンプルかと思いました

@syuilo

syuilo commented Jul 14, 2026

Copy link
Copy Markdown
Member

一ユーザーとしては、あるWebサイトのプレビューが表示されるとき、それをどんなサイズで見るかは自分の好みなので、Webサイト自身がサイズを決めるのはあまり嬉しくないというか、Webサイトによってサイズが変わるのは一貫性がない気がしちゃいますね
(「あるWebサイトは大きく、あるWebサイトは小さく見たい」と思うことがあったとしても、Webサイトがその通りの指定をするかは運次第)

@syuilo

syuilo commented Jul 14, 2026

Copy link
Copy Markdown
Member
  • Webサイトごとにプレビュー時のサイズを指示できるという仕様(summary_large_image)は意味のある(価値のある)仕様なのかが知りたい(Webサイト運営者として、プレビューを小さいままにしたい、と思うシチュエーションがあまりないのであれば、そのような仕様はあまり意味があるとはいえず、Misskeyがその仕様に対応する合理性に欠ける。ユーザー目線で、単にプレビューをもう少し大きく見たいというのであれあばプレビューを大きくするオプションを実装するだけで足りる)
    • これにより、どのように実装するか(ユーザー自身がサイズを指定できるのか、Webサイト自身がサイズを指定できるのか)が変わる
  • ↑で価値ある仕様だったとして、いちユーザーとして「プレビューがWebサイトごとに異なるサイズで表示されてほしい」とは思わない派だから、そう思う人の意見を知りたい
    • これにより、オプトインにするかオプトアウトにするかが変わる

あと、MisskeyはWebサイトのためというよりユーザーのためのソフトだから、「サイト運営者が嬉しいか」よりは「ユーザーが嬉しいか」という視点で考える方が自然そう

Webサイトごとにプレビューのサイズが違うようになる機能がユーザーにとって嬉しいかどうかになるけど、必ずしも大きく表示されるものが自分が大きく見たいと思うものと一致するわけではないから、果たして嬉しいかどうか

@ZerglingGo

ZerglingGo commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

少なくとも私が運営しているサイトのうち、外部へのリンク共有が頻繁に行われているサイトについては、OpenGraph画像を標準サイズ(1200×630)に準拠して生成し、twitter:cardsummary_large_imageに指定しています。

そのため、summary_large_imageに指定してありますが、他のプラットフォームでOG画像を1:1のような比率でトリミングすると、両側のテキストが切り取られてUXの品質が低下するケースが発生します。

対策として、1:1のアスペクト比のOpenGraph画像をsecondaryとして追加してみましたが、summalyでは対応されていないようでした。

@ihoronir

Copy link
Copy Markdown
Contributor
  • summary_large_image を指定しているウェブサイトは、大きいカードで表示されることを前提にした画像を用意している
    • 凝った装飾・小さめの文字など
  • summary を指定しているウェブサイトは、小さいカードで表示されることを前提にした画像を用意している
    • ロゴやアイコンを流用するなど、シンプルなもの

ことが多いと思います。

大きいカードで表示される前提の画像を小さいカードで表示すると:

  • 文字が小さくて読めない
    • 例: GitHub の OG 画像は、現在の小さいカードでの表示では文字が小さくて読めない(例: #17392(comment)
  • 細かな装飾が全く見えない
  • 16:9 の画像の両端がトリミングされてしまう

小さいカードで表示される前提の画像を大きいカードで表示すると:

  • 大きく表示される前提ではない画像が大きく表示されていると間の抜けた感じになる
    • 例: Wikipedia のロゴが大きいカードで表示されていたら変
  • 1:1 の画像の上下がトリミングされてしまう

などの問題が生じます。

なので、一ユーザーとして個人的には、ウェブサイトで指定されている通りにカードを表示できると嬉しいです。

また、ウェブサイト運営者として、 summary_large_image ではなく summary を選択したいシチュエーションはあると思います。例えば:

  • カードは表示してほしいが、大きく表示される前提の画像を用意するのは面倒なので、ロゴやアイコンを流用して済ませたい
  • ひかえめなカード表示を選択することで、質実剛健な印象を与えたい
    • ウェブサイトを運営しているコミュニティの性格によっては、華美なアイキャッチ画像を用意するのは文化にそぐわないかもしれない
      • 例:MDN など?

@syuilo

syuilo commented Jul 14, 2026

Copy link
Copy Markdown
Member

summary_large_image用とsummary用でサムネイルそれぞれ用意することはできないんですね
(そうすると元の仕様がやっぱり微妙ですね)

@syuilo

syuilo commented Jul 14, 2026

Copy link
Copy Markdown
Member

/preview

@syuilo

syuilo commented Jul 14, 2026

Copy link
Copy Markdown
Member

ユーザー視点のアンケート中(オプトインがいいかオプトアウトがいいかの判断材料に)
https://misskey.io/notes/aoo0nhdjyyv201i9

@kakkokari-gtyih

kakkokari-gtyih commented Jul 14, 2026

Copy link
Copy Markdown
Member

summary_large_image用とsummary用でサムネイルそれぞれ用意することはできないんですね (そうすると元の仕様がやっぱり微妙ですね)

出来なくはないっぽいけどこの仕様に適合している実装がどの程度あるか
https://ogp.me/#array

あとサイト側が og:image:widthog:image:height を明示的に指定していない実装はかなり多いのであまり活用できない

@syuilo

syuilo commented Jul 14, 2026

Copy link
Copy Markdown
Member

とりあえずオプトインで出すのが丸いかもしれない

@kakkokari-gtyih

kakkokari-gtyih commented Jul 14, 2026

Copy link
Copy Markdown
Member

この機能は割とメンテナンスコストが大きいため(summalyやデファクトスタンダードとの兼ね合いなど)、オプトアウトにしないのであればいっそ見送るというのもありかと思います

@poppingmoon

Copy link
Copy Markdown
Contributor

理想的には、サーバー側でsummalyの結果をthumbnailStyleだけでも覚えておいて、APIレスポンスにヒントを含めることができればクライアント側でレイアウトシフトなく出し分けることができそうです

ちなみにMastodonやBlueskyではノートにあたるものの中にプレビューの内容が含まれているようです
https://docs.joinmastodon.org/entities/Status/#card
https://docs.bsky.app/docs/advanced-guides/posts#website-card-embeds

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

packages/backend Server side specific issue/PR packages/frontend Client side specific issue/PR size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Development

Successfully merging this pull request may close these issues.

feat: summary_large_image相当の大きいカード表示がほしい

6 participants