ادیتور ۱۷٪ سریعتر، بدون کمکردن حتی یه بایت
خلاصهٔ کاملتر
Recraft Studio یه اپ وبه که توش تصویر میسازی و روی یه canvas باهاش کار میکنی. نویسنده میگه با چهار تا PR و حدود ۳۰۰ خط کد، زمان اولین رندر روی canvas تو p50، p75 و p90 بین ۱۵ تا ۱۹ درصد کم شد. جالبیش اینه که حجم دانلود عوض نشد (۱۶.۷۵ مگابایت قبل، ۱۶.۷۱ الان). فقط زمان شروع دانلود بزرگترین فایل عوض شد: موتور رندرشون که یه fork از Skia کامپایلشده به WebAssembly با حجم ۹.۲ مگابایت هست.
ماجرا از اندازهگیری شروع شد. نویسنده چند تا performance mark اضافه کرد و تو Amplitude دید رسیدن به صحنهٔ کامل روی canvas تو p75 حدود ۸.۵ ثانیه طول میکشه. مشکل این بود که import ماژول WASM توی یه lazy chunk بود. یعنی مرورگر تا وقتی کلی JS رو parse نکرده بود و به storage لحظهای وصل نشده بود و استایلها نرسیده بودن، اصلاً از وجود این فایل خبر نداشت. نویسنده میگه compile این فایل مشکل نیست، چون همزمان با دانلود انجام میشه؛ مشکل شبکهست.
یه گیر دیگه هم تو درخت React بود. چند تا hook پشت سر هم با Suspense (یعنی کامپوننت تا رسیدن داده رندرشو متوقف میکنه) کار میکردن. اولی که suspend میشد، دومی اصلاً اجرا نمیشد. مثلاً درخواست فونت فقط بعد از تمومشدن دانلود ۹.۲ مگابایتی WASM فرستاده میشد:
export const Stage = ({ children, ...props }: Props) => {
useKitInit()
useFontInit()
useInitSkiaWorker()
...
}راهحل سه بخش داشت. اول، تگهای preload برای فایل WASM و فونت پیشفرض توی head صفحه. دوم، صدازدن initSkia() در سطح ماژول که initKit() و initFont() رو همزمان و بدون await راه میندازه. برای این کار FontCache.initFont() به یه promise از نوع memoized و idempotent (یعنی چند بار صدا زدنش فقط یه درخواست میفرسته) تبدیل شد تا مسیر Suspense و گرمکردن زودهنگام سر یه fetch دعوا نکنن. سوم، درخواست استایلها بالاتر تو درخت فرستاده شد. نتیجه اینکه درخواست CanvasKit حدود ۱.۵ ثانیه زودتر، همراه خود document، میره.
یه نکتهٔ ریز هم هست: URL فونت بهصورت hardcode نوشته شده، چون import کردن FontCache یه فایل fonts.json با حجم ۶۵۲ کیلوبایت رو وارد bundle میکرد و سود preload رو میخورد. نویسنده اشتباهشم گفته: اولش روی صفحهٔ لیست پروژهها هم preload گذاشته بود که باعث رقابت منابع شد. درستش اینه که روی ادیتور preload (یعنی همین الان لازمه) و روی صفحهٔ لیست prefetch (یعنی برای صفحهٔ بعد، با اولویت پایین) باشه.
به گفتهٔ نویسنده، بیشترین سود رو کاربرهای کندتر بردن، چون اون ۱.۵ ثانیه صرف bootstrap و احراز هویت میشد و هرچی اینترنت کندتر باشه این فاصله بیشتره. این نتیجه از یه آزمایش واقعی با گروه کنترل اومده، نه یه نمودار قبل و بعد.
نکات کلیدی:
- اولین رندر canvas تو p50، p75 و p90 بین ۱۵ تا ۱۹ درصد سریعتر شد.
- حجم کل دانلود صفحه تقریباً ثابت موند: ۱۶.۷۵ مگابایت در برابر ۱۶.۷۱.
- فایل WASM موتور رندر (fork از Skia) ۹.۲ مگابایته و قبلاً آخر از همه درخواست میشد.
- آزمایش با حدود ۱۸ هزار کاربر تو هر گروه و طی پنج روز انجام شد.
- preload برای منابع همین صفحهست و prefetch برای صفحهٔ بعد؛ قاطیکردنشون باعث رقابت منابع میشه.
- import کردن FontCache یه fonts.json ۶۵۲ کیلوبایتی رو وارد bundle میکرد، برای همین URL فونت hardcode شد.




