در ۱۹ ژوئن ۲۰۲۵ به PiterJS #79 در سنپترزبورگ رفتم. موضوع آن شب عمداً چندان پرزرقوبرق نبود و همین برایم جذابش کرد: نه اینکه feature بعدی را چطور منتشر کنیم، بلکه اینکه چیزی را که از قبل ساخته شده چطور نگه داریم — monitoring، deployment و refactoring.
برنامه هم دقیقاً با این موضوع هماهنگ بود. Pavel Shlykov درباره بهتر کردن یک monolith قدیمی صحبت کرد، Alexander Panfilov سراغ FrontOps رفت و Igor Antonov درباره معیارهای عملکرد اپلیکیشنهای وب حرف زد. از هر سه موضوع یادداشتهای کاربردی برداشتم.
بخش غیرمنتظره Q&A بود. در پایان به خاطر پرسیدن بهترین سؤالها دو جایزه گرفتم. اتفاق بزرگی از نظر فنی نیست، اما بهیادماندنیترین جزئیات آن شب شد، چون دوباره نشان داد چرا هنوز meetupهای فنی حضوری را ارزشمند میدانم: فقط شنونده یک ارائه آماده نیستید. میتوانید همانجا، وقتی ارائهدهنده هنوز در سالن است، درک خودتان از موضوع را محک بزنید.
موضوع مفید، نگهداری بود نه تازگی
رویدادهای frontend خیلی راحت میتوانند تبدیل شوند به رژهای از frameworkها، APIها و abstractionهای جدید. PiterJS #79 زمینیتر بود. موضوع اعلامشدهاش پشتیبانی از نرمافزاری بود که از قبل وجود دارد.
این موضوع مهم است، چون بخش بزرگی از کار engineering بعد از اولین release موفق شروع میشود. یک legacy monolith لزوماً سیستم بدی نیست و «modernization» هم لزوماً به معنی بازنویسی کامل نیست. سؤال عملی معمولاً محدودتر است: الان دقیقاً کدام محدودیت به سیستم آسیب میزند و چه تغییری میتواند آن مشکل را کاهش دهد بدون اینکه ریسک بیشتری از چیزی که حذف میکند ایجاد کند؟
به همین دلیل سه ارائه برای من خوب کنار هم قرار گرفتند. Refactoring کد را تغییر میدهد. FrontOps نحوه build، بستهبندی، تحویل و عملیات frontend را تغییر میدهد. کار روی performance هم نحوه اندازهگیری نتیجه را تغییر میدهد. اینها لایههای مختلف یک مسئلهاند: قابلفهم و قابلکنترل نگه داشتن یک سیستم واقعی بعد از رشد کردنش.
FrontOps گستردهتر از یک Dockerfile است
یکی از یادداشتهای من از meetup درباره اجرای FrontOps با Docker بود. تمایز مهم این است که Docker یک ابزار است، نه تعریف FrontOps.
مسئولیت frontend لزوماً وقتی npm run build موفق میشود تمام نمیشود. در production هنوز کسی باید به buildهای قابلتکرار، بستهبندی artifactها، رسیدن configuration به اپلیکیشن، rollback نسخهها، رفتار cache و مشاهده خطاها فکر کند. Containerها میتوانند بخشی از این کار را قابلپیشبینیتر کنند، اما جای تصمیمهای عملیاتی را نمیگیرند.
این اصلاح خوبی برای یک مدل ذهنی رایج است: build موفق فقط ثابت میکند build تمام شده است. ثابت نمیکند اپلیکیشن درست deploy میشود، در production درست رفتار میکند یا وقتی مشکلی پیش آمد بهسادگی قابل بازیابی است.
Performance با تعریف «کند» شروع میشود
ارائه performance از این جهت عملی بود که موضوع اندازهگیری را چگونه چارچوببندی میکرد. محدوده اعلامشده شامل عوامل مؤثر بر سرعت بارگذاری، metricهای مختلف frontend، روشهای عددی کردن «کندی» و حتی این سؤال بود که چرا optimization همیشه لازم نیست.
نکته آخر را بهراحتی میشود دستکم گرفت. «سریعترش کن» هدفی عینی به نظر میرسد، اما بدون metric و بدون مشکلی که کاربر واقعاً حس کند میتواند تبدیل به حدس زدن پرهزینه شود. یک فرایند مفید performance با این شروع میشود که مشخص کنیم چه چیزی واقعاً کند است، آن را اندازه بگیریم، bottleneck را پیدا کنیم، یک تغییر مرتبط انجام دهیم و دوباره اندازه بگیریم.
یک metric بهتنهایی همان user experience نیست، اما واحد مشترکی برای بحث میدهد. بدون اندازهگیری، کار performance میتواند تبدیل به مجموعهای از تغییرهای فنی چشمگیر شود بدون اینکه مدرک روشنی داشته باشیم مشکل مهم واقعاً بهتر شده است.
Q&A ارزش meetup را برای من تغییر داد
میتوانستم بعداً recordingها را ببینم و لینکها را جمع کنم. چیزی که به همان راحتی قابل بازتولید نیست، تعامل اطراف ارائههاست. پرسیدن یک سؤال خوب مجبورمان میکند ابهام خودمان را به چیزی آنقدر مشخص تبدیل کنیم که مهندس دیگری بتواند جواب بدهد.
گرفتن دو جایزه سرگرمکننده بود، اما درس مفیدتر سادهتر بود: وقتی برای مشارکت آماده به یک meetup حضوری میروید، ارزش بسیار بیشتری میگیرید تا زمانی که آن را مثل یک playlist زنده YouTube ببینید.
یک سؤال فنی خوب معمولاً context و constraint دارد. بهجای «بهترین architecture چیست؟» مفیدتر است بپرسیم وقتی تیم نمیتواند legacy system را بازنویسی کند چه trade-offی عوض میشود، وقتی deployment باید backward-compatible بماند چه چیزی تغییر میکند، یا وقتی metric بهتر شده ولی کاربر بهبود متناظری حس نمیکند باید چطور قضاوت کرد.
قرار نیست هر سؤال خیلی هوشمندانه به نظر برسد. سؤال خوب باید کمک کند assumptionها، مرزها یا failure modeها روشن شوند.
چیزهایی که به meetup فنی بعدی میبرم
- بدانم چرا یک ارائه برایم مهم است. قبل از شروع یک مسئله واقعی یا ابهام مشخص را یادداشت کنم.
- تجربه speaker را از سیستم خودم جدا کنم. یک case study خوب شواهد است، نه نسخهای جهانی.
- درباره trade-offها سؤال کنم. «چه زمانی از این استفاده نمیکنی؟» اغلب بیشتر از «بهترین ابزار چیست؟» اطلاعات میدهد.
- یک اقدام بعدی ثبت کنم. یادداشت وقتی ارزشمندتر میشود که به چیزی برای بررسی، تست یا مطالعه بعد از meetup وصل باشد.
- یک ارائه قانعکننده را با production proof اشتباه نگیرم. تصمیمهای architecture، deployment و performance هنوز باید در محیط خودم اعتبارسنجی شوند.
چیزی که برایم ماند
نمیخواهم تأثیر یک meetup را بیش از حد بزرگ کنم. از PiterJS با یک نسخه معماری جهانی بیرون نیامدم و یک ارائه خوب جای documentation، profiling، testing یا production data را نمیگیرد.
چیزی که واقعاً با خودم آوردم مشخصتر بود: یادداشتهای مفید درباره modernize کردن legacy monolith، FrontOps با Docker و اندازهگیری performance وب؛ دو جایزه از Q&A؛ و یک یادآوری دیگر که ارزش دارد برای جامعه محلی توسعهدهندگان حضوری وقت بگذاریم.
Recording میتواند خود ارائه را حفظ کند. سختترین بخش برای آرشیو، گفتوگویی است که اطراف آن شکل میگیرد.