DevTools را برای مسیر شکست باز کن، نه برای لاگ بیشتر
فرق توسعهدهنده مرتب با کسی که در حادثه معطل میماند اغلب تمیزی کد نیست. این است که وقتی رفتار گاهی هست و گاهی نیست، ابزار را بلد باشد. DevTools همان ابزار است، به شرطی که بهجای دیوار `console.log` از آن سؤال مشخص بپرسی.
هر مرورگر همهچیز را یکسان نشان نمیدهد. Chrome DevTools برای پروفایل جاوااسکریپت سنگین، آبشار شبکه، و بررسی HTTPS معمولاً نقطه شروع من است. Firefox در بازرس CSS Grid و پنل دسترسپذیری قویتر است و برای چیدمان پیچیده ارزش یک بار دیدن را دارد. Safari Web Inspector را وقتی لازم داری که محتوا روی خود iOS اجرا میشود. باگ لمس، نوار ابزار، یا ذخیره که در شبیهساز دسکتاپ دروغ میگوید، از منوی توسعهدهنده Safari به دستگاه واقعی وصل میشود. خودت را به یک مرورگر محدود نکن. مسئلهای که در Chrome خفیف است ممکن است در Firefox واضح باشد.
کنسول فقط log نیست
`console.table` برای آرایه و شیء، دامپ درهم را به جدول قابل مقایسه تبدیل میکند. وقتی چند ردیف پاسخ API را با چشم مقایسه میکنی، از `log` تودرتو بهتر است. `console.dir` درخت تعاملی شیء را نشان میدهد، نه فقط نمایش رشتهای. برای دیدن getter و نمونه کلاس به درد میخورد.
`console.trace` میگوید چطور به این خط رسیدی، نه فقط اینکه رسیدی. وقتی یک تابع از سه مسیر صدا زده میشود و فقط یکی خراب است، trace ارزانتر از حدس است. `console.count` تعداد عبور از یک شاخه را میشمارد و حلقه یا رندر غیرمنتظره را لو میدهد. `console.time` و `console.timeEnd` مدت یک بلوک مشخص را میگیرند. این بنچمارک آزمایشگاه نیست. مقایسه دو پیادهسازی روی همان داده است.
`console.profile` و `console.profileEnd` پروفایل را در پنل Performance میسازند بدون اینکه دستی جلسه را با کلیک شروع کنی. وقتی گلوگاه داخل یک عمل کاربر است، دور همان عمل پروفایل بگیر نه دور کل بارگذاری صفحه.
لاگ را بعد از پیدا شدن فرض حذف کن. لاگ رهاشده در مسیر پروداکشن هم نویز است هم گاهی نشت داده.
آبشار شبکه را بخوان
بیشتر آدمها پنل Network را فقط برای وضعیت ۲۰۰ یا ۵۰۰ باز میکنند. آبشار فازها را جدا میکند: DNS، اتصال، دستدادن TLS، انتظار سرور، و دانلود. رنگها تزئین نیستند. دنبال الگو بگرد. DNS طولانی اغلب به پیکربندی نام یا CDN برمیگردد. انتظار طولانی اغلب کار سمت سرور است نه «اینترنت کند». چند درخواست همزمان به یک میزبان که میشد یکی شود، فرصت دستهکردن است.
محدود کردن شبکه را روشن کن. کاربر روی اتصال ضعیف همان چیزی را میبیند که تو روی فیبر نمیبینی. پروفایل آماده نقطه شروع است. اگر میدانی بخش مهمی از کاربر روی شرایط مشخص است، پروفایل سفارشی نزدیک به همان بساز و حداقل یک مسیر حیاتی را با آن ببین. حالت آفلاین را هم امتحان کن. پیام خطا معنی دارد یا اپ در سکوت میماند؟ قابلیت اصلی خراب میشود یا فقط بخش غیرضروری؟
برای اپ Next.js، در همین پنل ببین کدام درخواست واقعاً از کلاینت رفته. خیلی از «کندی React» در واقع انتظار یک Route Handler یا یک آبشار fetch است که در سرور باید موازی میشد.
حافظه را با سه تصویر بگیر، نه با حس
نشت حافظه در جاوااسکریپت شایعتر از آن است که تیمها قبول میکنند. علامت معمول، رشد تدریجی مصرف است تا اینکه تب کند یا کرش کند. پنل Memory دو ابزار مفید دارد: snapshot هیپ در یک لحظه، و خط زمان تخصیص که نشان میدهد حافظه کی گرفته شده و آیا رها شده.
به شیئی نگاه کن که باید جمع میشد و نشده. شنونده رویدادی که برداشته نشده، closure که به شیء بزرگ اشاره دارد، و گره DOM جداشده مقصرهای معمولیاند. روش عملی: یک بار کار کاربر را انجام بده، snapshot بگیر، همان کار را چند بار تکرار کن، snapshot دوم و سوم را بگیر، و بینشان مقایسه کن. رشدی که با تکرار عمل زیاد میشود و بعد از رها کردن UI برنمیگردد، نامزد نشت است. یک snapshot تنها معمولاً فقط ترس تولید میکند.
Performance را هم با فرض باز کن. اگر صفحه موقع تایپ میلرزد، ضبط را به همان چند ثانیه محدود کن و دنبال کار طولانی روی نخ اصلی بگرد. ضبط پنج دقیقهای از کل جلسه را کسی تا آخر نمیخواند.
عادت جلسه دیباگ
یک فرض بنویس. یک ابزار را انتخاب کن که آن فرض را رد یا تأیید کند. اگر شبکه است آبشار، اگر زمان تابع است پروفایل، اگر رشد تب است snapshot، اگر فقط مسیر صداست trace. ابزار دوم را وقتی باز کن که اولی فرض را بسته باشد. چرخیدن همزمان در چهار پنل حس حرفهای بودن میدهد و مسئله را دیرتر حل میکند.
و وقتی باگ فقط روی دستگاه اپل است، همانجا را ببین. پروفایل عالی Chrome روی ماشین تو، Safari روی گوشی کاربر را جایگزین نمیشود.
نقطه شکست را به فرض وصل کن
وقتی رفتار فقط گاهی خراب است، `debugger` یا نقطه شکست شرطی از لاگ پراکنده دقیقتر است. شرط را روی همان مقداری بگذار که فکر میکنی غلط است، مثلاً شناسه تهی یا وضعیت غیرمنتظره، تا اجرا در مسیر سالم نایستد. در کد ناهمگام، call stack را با گزینه async ببین وگرنه فقط callback آخر را میبینی و مسیر واقعی را از دست میدهی.
Source map باید به کد خودت برسد نه فقط به باندل minify. اگر در پروداکشن map عمومی نمیدهی، حداقل در محیط بازتولید باگ روشن باشد. دیباگ روی کد فشرده، وقت را میسوزاند و نتیجهاش معمولاً یک فرض ضعیفتر است.
پرسشهای کوتاه
log را کامل کنار بگذارم؟ نه. برای فرض کوچک هنوز سریع است. برای داده تو در تو، شمارش، و پشته صدا، متد دقیقتر کنسول کمتر دروغ میگوید.
کدام مرورگر را پیشفرض کنم؟ همان را که کاربر در حادثه استفاده کرده. برای چیدمان Grid و دسترسپذیری یکبار Firefox را هم ببین. برای iOS، Safari روی دستگاه.
هر کندی را از Memory شروع کنم؟ نه. اگر کندی با یک کلیک میآید اول شبکه و Performance. Memory را وقتی تب با زمان بدتر میشود بیاور.