کلیپبورد وب حالا فقط فرمت لازم رو میخونه
خلاصهٔ کاملتر
به گفتهی نویسنده، تو اپهایی مثل ویرایشگر متن، صفحهگسترده یا ابزار طراحی، کاربر انتظار داره پیست کردن آنی حس بشه. ولی مشکل اینجاست که وقتی از یه اپ مثل Excel یا Photoshop کپی میکنی، سیستم چند نسخهی مختلف از همون داده رو تو کلیپبورد میذاره: متن ساده، HTML، عکس و گاهی فرمتهای سفارشی. اپ وبی که پیست میکنه معمولاً فقط یکی از اینها رو میخواد.
تا امروز navigator.clipboard.read() همهی نسخهها رو از کلیپبورد سیستم میکشید بیرون، روشون sanitize اجرا میکرد (که مخصوصاً برای HTML یا عکس بزرگ کند و پرهزینهست) و همه رو تو حافظه نگه میداشت، حتی فرمتی که اپ اصلاً بهش دست نمیزد. هر چی دادهی استفادهنشده بزرگتر، انتظار کاربر بیشتر و مصرف حافظهی تب هم بالاتر.
راهحل اینه که از کروم و اج ۱۴۹، شیءهای ClipboardItem که از read() برمیگردن فقط توصیف میکنن چی تو کلیپبورده و بایت واقعی هر فرمت فقط وقتی خونده میشه که ClipboardItem.getType(mimeType) رو صدا بزنی. سطح API هیچ تغییری نکرده، پس همون کد دیروزت امروز هم کار میکنه و خودبهخود سریعتر میشه:
const items = await navigator.clipboard.read();
for (const item of items) {
if (item.types.includes('text/html')) {
const blob = await item.getType('text/html');
useThePastedHtml(await blob.text());
break;
}
}نویسنده میگه سود اصلی دو تاست. تأخیر: کارهایی مثل کپی بایتها بین پروسهها، sanitize کردن HTML یا decode عکس حالا فقط برای فرمتی انجام میشه که اپ واقعاً میخواد؛ HTML بیشترین سود رو میبره چون sanitize کردنش گرونترینه. حافظه: اگه کلیپبورد یه عکس ۵۰ مگابایتی داشته باشه ولی اپ فقط متنشو بخواد، دیگه اون ۵۰ مگ تو حافظهی رندرر اشغال نمیشه. این هم بدون هیچ opt-in برای همهی سایتها فعاله.
یه تغییر رفتار هم هست که باید حواست باشه: ClipboardItem دیگه یه snapshot یخزده از لحظهی read() نیست، بلکه یه دستهی تنبل (lazy handle) به دادهی کلیپبورد سیستمه. اگه بین read() و getType() محتوای کلیپبورد عوض بشه، اون فراخوانی با خطای InvalidStateError رد میشه، حتی برای فرمتی که قبلاً موفق خونده بودی.
نویسنده میگه واسه بیشتر کدها این تغییر نامرئیه چون معمولاً read() و getType() پشتسرهم تو همون هندلر پیست صدا زده میشن. ولی اگه ClipboardItem رو نگه میداری (مثلاً برای یه UI تاریخچهی کلیپبورد)، بهتره فراخوانی getType() رو تو try / catch بذاری، بهمحض گرفتن Blob اونو تو ساختار خودت کپی کنی و از رویداد clipboardChange برای بیاعتبار کردن دستههای قدیمی استفاده کنی. این تغییر یه اصلاح استاندارد Clipboard APIه که Safari هم پشتیبانیش میکنه و Firefox هم موافقه.
نکات کلیدی:
- از کروم و اج ۱۴۹، read() فقط فرمتها رو لیست میکنه و دادهی هر فرمت با getType() روی تقاضا خونده میشه
- بیشترین سود تأخیر و حافظه برای اپهایی که HTML یا عکس بزرگ رو نادیده میگیرن
- بدون opt-in و بدون تغییر کد، همهی سایتها این بهبود رو میگیرن
- ClipboardItem حالا یه دستهی تنبله؛ اگه کلیپبورد عوض بشه getType() خطای InvalidStateError میده
- Safari هم پیادهسازیش کرده و Firefox موضع مثبت گرفته




