Ngày 19 tháng 6 năm 2025, tôi đến PiterJS #79 ở St. Petersburg. Chủ đề của buổi tối khá “không hào nhoáng”, và chính điều đó làm nó hữu ích: không phải cách ship feature tiếp theo, mà là cách duy trì những gì đã được xây dựng — monitoring, deployment và refactoring.
Chương trình bám rất sát chủ đề đó. Pavel Shlykov nói về việc cải thiện một monolith cũ, Alexander Panfilov trình bày về FrontOps, còn Igor Antonov nói về các chỉ số hiệu năng ứng dụng web. Tôi mang về những ghi chú thực tế từ cả ba chủ đề.
Phần bất ngờ là Q&A. Cuối cùng tôi nhận được hai giải thưởng vì đặt những câu hỏi hay nhất trong các phiên hỏi đáp. Đây chỉ là một chi tiết nhỏ, nhưng lại trở thành phần đáng nhớ nhất của buổi tối vì nó củng cố lý do tôi vẫn coi trọng meetup kỹ thuật trực tiếp: bạn có thể làm nhiều hơn việc nghe một bài nói đã được chuẩn bị sẵn. Bạn có thể kiểm tra cách mình hiểu vấn đề trong khi những người vừa trình bày vẫn còn ở ngay trong phòng.
Điều hữu ích là nói về bảo trì, không phải cái mới
Các sự kiện frontend rất dễ trở thành một cuộc diễu hành của framework, API và abstraction mới. PiterJS #79 thực tế hơn. Chủ đề được công bố là hỗ trợ phần mềm đã tồn tại.
Điều đó quan trọng vì phần lớn công việc engineering diễn ra sau lần release thành công đầu tiên. Một monolith legacy không tự động là một hệ thống tồi, và “modernization” cũng không tự động có nghĩa là viết lại mọi thứ. Câu hỏi thực tế thường hẹp hơn: ràng buộc nào đang thực sự gây đau cho hệ thống lúc này, và thay đổi nào có thể giảm vấn đề đó mà không tạo ra nhiều rủi ro hơn phần rủi ro nó loại bỏ?
Đó cũng là lý do ba bài nói khớp với nhau. Refactoring thay đổi code. FrontOps thay đổi cách frontend được build, đóng gói, phân phối và vận hành. Công việc về performance thay đổi cách chúng ta đo kết quả. Đây là những lớp khác nhau của cùng một bài toán: giữ cho một hệ thống thực tế vẫn dễ hiểu và kiểm soát được sau khi nó lớn lên.
FrontOps rộng hơn một Dockerfile
Một trong những ghi chú của tôi tại meetup là về việc triển khai FrontOps với Docker. Điểm cần phân biệt là Docker là công cụ, không phải định nghĩa của FrontOps.
Trách nhiệm với frontend không nhất thiết kết thúc khi npm run build chạy thành công. Trong production, vẫn cần người nghĩ về build có thể tái tạo, cách đóng gói artifact, cách cấu hình đến được ứng dụng, rollback release, hành vi cache và cách quan sát lỗi. Container có thể làm một phần công việc đó dễ dự đoán hơn, nhưng không thay thế các quyết định vận hành.
Đây là một điều chỉnh hữu ích cho một cách nghĩ khá phổ biến: build thành công chỉ chứng minh quá trình build đã hoàn tất. Nó không chứng minh ứng dụng sẽ được deploy đúng, hoạt động đúng ở production hay dễ phục hồi khi có sự cố.
Hiệu năng bắt đầu bằng việc định nghĩa “chậm” là gì
Bài nói về performance đặc biệt thực tế ở cách đặt vấn đề đo lường. Phạm vi được công bố gồm các yếu tố ảnh hưởng đến tốc độ tải, những metric performance frontend khác nhau, cách định lượng “chậm”, và thậm chí cả câu hỏi vì sao không phải lúc nào tối ưu cũng cần thiết.
Điểm cuối cùng rất dễ bị xem nhẹ. “Làm nó nhanh hơn” nghe có vẻ khách quan, nhưng nếu không có metric và một vấn đề người dùng thật sự nhìn thấy, nó có thể biến thành việc đoán mò tốn kém. Một quy trình performance hữu ích bắt đầu bằng việc xác định chính xác điều gì đang chậm, đo nó, tìm bottleneck, thay đổi một yếu tố có liên quan rồi đo lại.
Một metric tự nó không phải là user experience, nhưng nó cho cuộc thảo luận một đơn vị chung. Không có đo lường, công việc performance có thể biến thành tập hợp những thay đổi trông rất ấn tượng về kỹ thuật nhưng không có bằng chứng rõ ràng rằng chúng cải thiện vấn đề thực sự quan trọng.
Q&A đã thay đổi giá trị của meetup đối với tôi
Tôi hoàn toàn có thể xem recording và lưu các link sau đó. Điều khó tái tạo hơn nhiều là sự tương tác quanh các bài nói. Đặt một câu hỏi tốt buộc bạn phải nén sự chưa chắc chắn của mình thành một điều đủ cụ thể để một engineer khác có thể trả lời.
Nhận hai giải thưởng tất nhiên là vui, nhưng bài học hữu ích hơn lại đơn giản: đến meetup với sự chuẩn bị để tham gia khiến một sự kiện offline có giá trị hơn rất nhiều so với việc xem nó như một playlist YouTube đang phát trực tiếp.
Một câu hỏi kỹ thuật tốt thường có context và constraint. Thay vì “Kiến trúc nào tốt nhất?”, sẽ hữu ích hơn nếu hỏi trade-off nào thay đổi khi đội ngũ không thể viết lại một hệ thống legacy, khi deployment phải tiếp tục backward-compatible, hoặc khi một metric tốt lên nhưng người dùng không nhận được lợi ích tương ứng.
Điều đó không có nghĩa mọi câu hỏi phải thật thông minh. Câu hỏi nên giúp làm lộ ra giả định, giới hạn hoặc failure mode.
Điều tôi sẽ mang tới meetup kỹ thuật tiếp theo
- Biết vì sao một bài nói quan trọng với mình. Trước khi bắt đầu, ghi lại một vấn đề thực tế hoặc một điều chưa chắc chắn.
- Tách trải nghiệm của speaker khỏi hệ thống của mình. Một case study hữu ích là bằng chứng, không phải công thức phổ quát.
- Hỏi về trade-off. “Khi nào bạn sẽ không dùng cách này?” thường cho nhiều thông tin hơn “Tool nào tốt nhất?”
- Ghi lại một hành động tiếp theo. Một ghi chú có giá trị hơn khi nó dẫn tới điều cần kiểm tra, thử nghiệm hoặc đọc thêm sau meetup.
- Đừng nhầm một bài nói thuyết phục với bằng chứng production. Các quyết định về architecture, deployment và performance vẫn phải được kiểm chứng trong môi trường của chính mình.
Điều còn ở lại với tôi
Tôi không muốn phóng đại mức độ một meetup có thể thay đổi mọi thứ. Tôi không rời PiterJS với một công thức kiến trúc phổ quát, và một bài nói tốt không thay thế documentation, profiling, testing hay dữ liệu production.
Điều tôi thực sự mang về cụ thể hơn: những ghi chú hữu ích về hiện đại hóa monolith legacy, FrontOps với Docker và đo lường hiệu năng web; hai giải thưởng từ Q&A; cùng một lời nhắc nữa rằng cộng đồng developer địa phương đáng để mình xuất hiện trực tiếp.
Recording có thể lưu lại phần trình bày. Phần khó lưu trữ nhất là cuộc trò chuyện xảy ra xung quanh nó.