چگونه و چرا ما Performance Insights را ایجاد کردیم

در Chrome 102 شاهد یک پانل آزمایشی جدید، Performance Insights در DevTools خود خواهید بود. در این پست ما نه تنها در مورد اینکه چرا روی یک پانل جدید کار می‌کنیم، بلکه چالش‌های فنی پیش روی ما و تصمیماتی که در این مسیر گرفته‌ایم بحث خواهیم کرد.

ALT_TEXT_HERE

چرا پنل دیگری بسازیم؟

(اگر قبلاً آن را ندیده‌اید، ما ویدیویی در مورد اینکه چرا پنل Performance Insights را می‌سازید و چگونه می‌توانید بینش عملی در مورد عملکرد وب‌سایت خود با آن به دست آورید، منتشر کردیم.)

اگر می‌خواهید تمام داده‌های وب‌سایت خود را در یک مکان ببینید، پنل عملکرد موجود منبع خوبی است، اما ما احساس کردیم که می‌تواند کمی طاقت‌فرسا باشد. اگر متخصص اجرا نیستید، سخت است بدانید که دقیقاً به دنبال چه چیزی باشید و چه بخش‌هایی از ضبط مرتبط هستند.

وارد پنل Insights شوید، جایی که همچنان می‌توانید جدول زمانی ردیابی خود را مشاهده کرده و داده‌ها را بررسی کنید، اما همچنین فهرستی مفید از آنچه DevTools به‌عنوان «Insights» اصلی می‌داند، دریافت کنید. Insights مسائلی مانند درخواست‌های مسدود کردن رندر، تغییر طرح‌بندی و کارهای طولانی را شناسایی می‌کند که همگی می‌توانند بر عملکرد بارگذاری صفحه وب‌سایت شما و به‌ویژه امتیازات Core Web Vital (CWV) سایت شما تأثیر منفی بگذارند. در کنار پرچم گذاری مشکلات، Performance Insights پیشنهادات عملی را برای بهبود امتیازات CWV به شما ارائه می دهد و پیوندهایی به منابع و مستندات بیشتر ارائه می دهد.

لینک بازخورد در پنل

این پنل آزمایشی است و ما بازخورد شما را می خواهیم! لطفاً اگر با اشکالی مواجه شدید یا درخواست ویژگی هایی دارید که فکر می کنید هنگام کار بر روی عملکرد سایت به شما کمک می کند، به ما اطلاع دهید.

چگونه بینش عملکرد را ایجاد کردیم

مانند بقیه DevTools، ما Performance Insights را در TypeScript ساختیم و از اجزای وب با پشتیبانی lit-html برای ساخت رابط کاربری استفاده کردیم. جایی که Performance Insights متفاوت است این است که رابط کاربری اصلی یک عنصر canvas HTML است و جدول زمانی روی این بوم ترسیم شده است. بسیاری از پیچیدگی ها ناشی از مدیریت این بوم است: نه تنها ترسیم جزئیات مناسب در مکان مناسب، بلکه مدیریت رویدادهای ماوس (به عنوان مثال: کاربر کجا روی بوم کلیک کرده است؟ آیا روی رویدادی که ما کشیده ایم کلیک کرده است؟ ) و اطمینان حاصل کنید که بوم را به طور موثر دوباره رندر می کنیم.

چند آهنگ روی یک بوم

برای یک وب‌سایت معین، چندین «آهنگ» وجود دارد که می‌خواهیم آن‌ها را ارائه کنیم، که هر کدام دسته متفاوتی از داده‌ها را نشان می‌دهند. به عنوان مثال، پانل Insights به طور پیش فرض سه آهنگ را نشان می دهد:

و با ادامه یافتن ویژگی‌ها در پنل، انتظار داریم آهنگ‌های بیشتری اضافه شود.

فکر اولیه ما این بود که هر یک از این آهنگ‌ها <canvas> خود را رندر کنند، به طوری که نمای اصلی به چندین عنصر بوم تبدیل شود که به صورت عمودی روی هم چیده شده‌اند. این امر رندرینگ در سطح آهنگ را ساده می کند، زیرا هر آهنگ می تواند به صورت مجزا رندر شود و خطر رندر آهنگ خارج از محدوده آن وجود نخواهد داشت، اما متأسفانه این رویکرد دو مشکل عمده دارد:

عناصر canvas برای (باز) گران قیمت هستند. داشتن چندین بوم گرانتر از یک بوم است، حتی اگر آن بوم بزرگتر باشد. رندر کردن هر پوششی که در چندین مسیر قرار می گیرد (به عنوان مثال، خطوط عمودی برای علامت گذاری رویدادهایی مانند زمان FCP) پیچیده می شود: باید روی چندین بوم رندر کنیم و مطمئن شویم که همه آنها با هم رندر شده و به درستی تراز می شوند.

استفاده از یک canvas برای کل رابط کاربری به این معنی بود که باید بفهمیم چگونه می‌توانیم مطمئن شویم که هر آهنگ در مختصات درست رندر می‌شود و در مسیر دیگری سرریز نمی‌شود. برای مثال، اگر یک آهنگ خاص 100 پیکسل بالا باشد، نمی‌توانیم به آن اجازه دهیم چیزی با ارتفاع 120 پیکسل را رندر کند و در مسیری که در زیر آن قرار دارد خونریزی کند. برای حل این مشکل ما می توانیم از clip استفاده کنیم. قبل از اینکه هر آهنگ را رندر کنیم، یک مستطیل می کشیم که نمایانگر پنجره تراک قابل مشاهده است. این تضمین می کند که هر مسیری که خارج از این محدوده ها ترسیم شده است توسط بوم بریده می شود.

canvasContext.beginPath();
canvasContext.rect(
    trackVisibleWindow.x, trackVisibleWindow.y, trackVisibleWindow.width, trackVisibleWindow.height);
canvasContext.clip();

ما همچنین نمی‌خواستیم هر آهنگ موقعیت خود را به صورت عمودی بداند: هر آهنگ باید خود را به گونه‌ای رندر کند که گویی در (0، 0) رندر می‌شود، و ما یک مؤلفه سطح بالاتر (که ما آن را TrackManager می‌نامیم) برای مدیریت کلی داریم. موقعیت مسیر این کار را می توان با translate انجام داد، که بوم را با یک موقعیت معین (x، y) ترجمه می کند. به عنوان مثال:

canvasContext.translate(0, 10); // Translate by 10px in the y direction
canvasContext.rect(0, 0, 10, 10); // draw a rectangle at (0, 0) that’s 10px high and wide

با وجود تنظیم کد rect 0, 0 به عنوان موقعیت، ترجمه کلی اعمال شده باعث می شود که مستطیل در 0, 10 ارائه شود. این به ما اجازه می‌دهد تا بر اساس یک آهنگ کار کنیم، گویی در حال رندر کردن در (0، 0) هستیم، و از مدیر آهنگ ما بخواهیم که هر تراک را ترجمه کند تا اطمینان حاصل شود که هر آهنگ به درستی زیر آهنگ قبلی رندر شده است.

بوم های خارج از صفحه برای آهنگ ها و هایلایت ها

رندر بوم نسبتاً گران است، و ما می‌خواهیم اطمینان حاصل کنیم که پانل Insights هنگام کار با آن، صاف و پاسخگو می‌ماند. گاهی اوقات نمی توانید از رندر مجدد کل بوم اجتناب کنید: برای مثال، اگر سطح بزرگنمایی را تغییر دهید، باید دوباره شروع کنیم و همه چیز را دوباره رندر کنیم. رندر مجدد بوم به ویژه گران است زیرا شما واقعا نمی توانید فقط بخش کوچکی از آن را دوباره رندر کنید. باید کل بوم را پاک کنید و دوباره بکشید. این برخلاف رندر مجدد DOM است که در آن ابزارها می توانند حداقل کار مورد نیاز را محاسبه کنند و همه چیز را حذف نکنند و دوباره شروع کنند.

یکی از زمینه هایی که در آن به مسائل بصری برخورد کردیم، برجسته کردن بود. هنگامی که ماوس را روی معیارها در پنجره نگه می‌دارید، آن‌ها را در جدول زمانی برجسته می‌کنیم، و به همین ترتیب، اگر ماوس را روی یک Insight برای یک رویداد معین نگه دارید، یک مرز آبی در اطراف آن رویداد می‌کشیم.

این ویژگی ابتدا با تشخیص حرکت ماوس بر روی عنصری که برجسته‌سازی را ایجاد می‌کند و سپس کشیدن آن برجسته به طور مستقیم بر روی بوم اصلی اجرا شد. مشکل ما زمانی پیش می آید که باید برجسته را حذف کنیم: تنها گزینه این است که همه چیز را دوباره ترسیم کنیم! غیرممکن است که فقط منطقه ای را که برجسته شده است دوباره ترسیم کنید (نه بدون تغییرات معماری عظیم)، اما دوباره کشیدن کل بوم فقط به این دلیل که می خواهیم یک حاشیه آبی را در اطراف یک آیتم حذف کنیم که به نظر بیش از حد است. همچنین اگر به سرعت ماوس خود را بر روی آیتم های مختلف حرکت دهید تا چندین برجسته به صورت متوالی ایجاد شود، از نظر بصری عقب می ماند.

برای رفع این مشکل، رابط کاربری خود را به دو بوم خارج از صفحه تقسیم می‌کنیم: بوم «اصلی»، جایی که آهنگ‌ها در آن نمایش داده می‌شوند، و بوم «برجسته‌ها»، که در آن نقاط برجسته کشیده می‌شوند. سپس با کپی کردن آن بوم‌ها روی بوم تکی که روی صفحه برای کاربر قابل مشاهده است، رندر می‌کنیم. می‌توانیم از متد drawImage بر روی یک بافت بوم استفاده کنیم، که می‌تواند بوم دیگری را به عنوان منبع آن انتخاب کند.

انجام این کار به این معنی است که حذف یک برجسته باعث ترسیم مجدد بوم اصلی نمی شود: در عوض می توانیم بوم روی صفحه را پاک کنیم و سپس بوم اصلی را روی بوم قابل مشاهده کپی کنیم . عمل کپی کردن یک بوم ارزان است، این نقاشی است که گران است. بنابراین با جابجایی هایلایت ها روی بوم جداگانه، از این هزینه در هنگام روشن و خاموش کردن هایلایت جلوگیری می کنیم.

تجزیه ردیابی به طور کامل آزمایش شده است

یکی از مزایای ایجاد یک ویژگی جدید از ابتدا این است که می‌توانید انتخاب‌های فنی قبلی را بررسی کنید و پیشرفت‌هایی انجام دهید. یکی از چیزهایی که می‌خواستیم آن را بهبود ببخشیم، تقسیم کد خود به دو بخش تقریباً کاملاً متمایز بود:

فایل ردیابی را تجزیه کنید و داده های مورد نیاز را بیرون بکشید. مجموعه ای از آهنگ ها را رندر کنید.

جدا نگه داشتن تجزیه (قسمت 1) از کار رابط کاربری (قسمت 2) ما را قادر ساخت یک سیستم تجزیه جامد بسازیم. هر ردیابی از طریق یک سری از Handler ها اجرا می شود که مسئول نگرانی های مختلف هستند: یک LayoutShiftHandler تمام اطلاعات مورد نیاز ما برای Layout Shifts را محاسبه می کند و یک NetworkRequestsHandler منحصراً با بیرون کشیدن درخواست های شبکه مقابله می کند. داشتن این مرحله تجزیه صریح که در آن کنترل‌کننده‌های مختلفی داریم که مسئول بخش‌های مختلف ردیابی هستند نیز سودمند بوده است: تجزیه ردیابی می‌تواند بسیار پیچیده شود و به توانایی تمرکز روی یک نگرانی در یک زمان کمک می‌کند.

ما همچنین توانسته‌ایم با ضبط موارد ضبط شده در DevTools، ذخیره آنها و سپس بارگیری آنها به عنوان بخشی از مجموعه آزمایشی خود، تجزیه ردیابی خود را به طور جامع آزمایش کنیم. این عالی است زیرا ما می‌توانیم با ردیابی واقعی آزمایش کنیم و حجم عظیمی از داده‌های ردیابی جعلی را که ممکن است منسوخ می‌شوند، ایجاد نکنیم.

تست اسکرین شات برای بوم UI

با ماندن در موضوع آزمایش، ما معمولا اجزای ظاهری خود را با رندر کردن آنها در مرورگر آزمایش می کنیم و اطمینان حاصل می کنیم که مطابق انتظار رفتار می کنند. می‌توانیم رویدادهای کلیک را برای راه‌اندازی به‌روزرسانی‌ها ارسال کنیم و ادعا کنیم که DOM که مؤلفه‌ها تولید می‌کنند درست است. این رویکرد برای ما خوب عمل می‌کند، اما هنگام بررسی رندر کردن روی بوم، از بین می‌رود. هیچ راهی برای بررسی بوم و تعیین آنچه در آنجا کشیده شده وجود ندارد! بنابراین رویکرد معمول ما برای رندر کردن و سپس پرس و جو مناسب نیست.

برای اینکه بتوانیم پوشش آزمایشی داشته باشیم، به تست اسکرین شات روی آوردیم. هر تست یک بوم را روشن می کند، آهنگی را که می خواهیم آزمایش کنیم رندر می کند و سپس یک اسکرین شات از عنصر بوم می گیرد. سپس این اسکرین شات در پایگاه کد ما ذخیره می‌شود و آزمایش‌های آتی اسکرین‌شات ذخیره‌شده را با اسکرین‌شاتی که تولید می‌کنند مقایسه می‌کنند. اگر اسکرین شات ها متفاوت باشند، آزمایش ناموفق خواهد بود. ما همچنین یک پرچم برای اجرای آزمایش ارائه می دهیم و زمانی که به طور هدفمند رندر را تغییر داده ایم و نیاز به به روز رسانی آزمایش داریم، به روز رسانی اسکرین شات را مجبور می کنیم.

تست های اسکرین شات کامل نیستند و کمی صریح هستند. شما فقط می‌توانید آزمایش کنید که کل مؤلفه به‌جای ادعاهای خاص‌تر، همانطور که انتظار می‌رود ارائه می‌شود، و در ابتدا ما به دلیل استفاده بیش از حد از آنها برای اطمینان از اینکه تک تک مؤلفه‌ها (HTML یا بوم) به درستی ارائه شده‌اند، مقصر بودیم. این کار مجموعه آزمایشی ما را به شدت کند کرد و منجر به مشکلاتی شد که در آن ترفندهای کوچک و تقریباً نامربوط در رابط کاربری (مانند تغییرات ظریف رنگ، یا اضافه کردن مقداری حاشیه بین موارد) باعث شکست چندین اسکرین شات و نیاز به به روز رسانی شد. اکنون استفاده از اسکرین‌شات‌ها را کاهش داده‌ایم و از آن‌ها صرفاً برای مؤلفه‌های مبتنی بر بوم استفاده می‌کنیم، و این تعادل تاکنون برای ما خوب عمل کرده است.

نتیجه گیری

ساخت پنل جدید Performance Insights یک تجربه آموزشی بسیار لذت بخش برای تیم بوده است. ما مجموعه‌ای از فایل‌های ردیابی، کار با بوم و موارد دیگر را یاد گرفته‌ایم. امیدواریم از استفاده از پنل جدید لذت ببرید و منتظر شنیدن نظرات شما نباشیم.

برای کسب اطلاعات بیشتر در مورد پانل اطلاعات آماری عملکرد، به اطلاعات آماری عملکرد مراجعه کنید: اطلاعات بینش عملی در مورد عملکرد وب سایت خود دریافت کنید .

کانال های پیش نمایش را دانلود کنید

استفاده از Chrome Canary ، Dev یا Beta را به عنوان مرورگر توسعه پیش‌فرض خود در نظر بگیرید. این کانال‌های پیش‌نمایش به شما امکان دسترسی به جدیدترین ویژگی‌های DevTools را می‌دهند، به شما اجازه می‌دهند APIهای پلتفرم وب پیشرفته را آزمایش کنید و به شما کمک می‌کنند تا قبل از کاربران، مشکلات سایت خود را پیدا کنید!

با تیم Chrome DevTools در تماس باشید

از گزینه‌های زیر برای بحث در مورد ویژگی‌های جدید، به‌روزرسانی‌ها یا هر چیز دیگری مربوط به DevTools استفاده کنید.