9 điều bạn đang kỹ thuật quá mức (Trình duyệt đã giải quyết chúng)
Frontend·Dev.to·2 lượt xem

9 điều bạn đang kỹ thuật quá mức (Trình duyệt đã giải quyết chúng)

9 Things You’re Overengineering (The Browser Already Solved Them)

AI Summary

Bài viết này điểm qua chín tính năng trình duyệt mà các developer thường hay "over-engineer" (tức là xây dựng giải pháp phức tạp hơn mức cần thiết), thay vì tận dụng sẵn có. Ví dụ như lên lịch cho các tác vụ không quá khẩn cấp bằng `requestIdleCallback`, hay styling cho phần tử cha của input đang được focus với `:focus-within`. Bằng cách khai thác những khả năng tích hợp sẵn này, các developer có thể giảm bớt lượng JavaScript boilerplate, cải thiện hiệu năng và làm cho codebase gọn gàng hơn. Điểm mấu chốt là hãy tìm hiểu các browser API trước khi tự code giải pháp, vì các trình duyệt hiện đại thường đã có những cách triển khai native hiệu quả cho các vấn đề phát triển web phổ biến.

Tôi thích viết các bài tiểu luận triết học - những suy nghĩ về mã, công việc, tất cả những thứ đó. Tôi cũng thích lặn kỹ thuật sâu. Nhưng tôi biết bạn thích danh sách các tính năng thú vị của tôi mà không phải ai cũng biết đến 😄...

Tôi thích viết các bài tiểu luận triết học — suy nghĩ về mã, công việc, tất cả những thứ đó. Tôi cũng thích lặn kỹ thuật sâu. Nhưng tôi biết bạn thích danh sách các tính năng thú vị của tôi mà không phải ai cũng biết đến 😄

Có chuyện gì với tôi vậy? Tuần này, tôi đang chuẩn bị cho một hội nghị, giải quyết các vấn đề về hiệu suất và cố gắng chuẩn bị sẵn sàng ít nhất phần nào cho kỳ nghỉ lễ sắp tới 😉

Một điều gì đó thú vị cũng đã xảy ra. Tôi thích viết - không chỉ các bài viết kỹ thuật mà còn nói chung. Mùa hè năm ngoái, cuộc sống của tôi đã thay đổi khá nhiều, và để giữ sự tỉnh táo của mình, tôi bắt đầu viết một câu chuyện khoa học viễn tưởng để gửi đến một cuộc thi tổ chức khoa học viễn tưởng ở Ba Lan. Tôi đã không giành chiến thắng, nhưng câu chuyện của tôi đã tiến khá xa - đứng ở vị trí thứ 13 trong tổng số 179 bài gửi. Xem xét đây là lần đầu tiên tôi thử viết kiểu này… nó có thể còn tệ hơn 😄

Và nói về khoa học viễn tưởng — thể loại đang diễn ra ngay trước mắt chúng ta 😉 Hôm nay, tôi đã chuẩn bị một loạt thứ mà trình duyệt có thể thực hiện, những thứ mà cách đây không lâu, thực sự tôi chưa nghĩ đến. Rất nhiều trong số này vẫn chưa được biết đến rộng rãi và nhiều trong số chúng đã được hỗ trợ trên các trình duyệt hiện đại. Chúc bạn vui vẻ!


1. “Để tôi chạy cái này sau” → requestIdleCallback

Lúc đầu, tôi nghĩ API này thật vô nghĩa. Về cơ bản, nó cho phép bạn chạy một số mã khi không có gì thú vị xảy ra. Được rồi… tuyệt… nhưng tại sao tôi lại quan tâm?

Hóa ra — có rất nhiều trường hợp sử dụng. Ví dụ: thu thập dữ liệu về cách người dùng cư xử trên trang của bạn - chắc chắn không phải là điều bạn muốn làm trong khi 200 thành phần của bạn đang hiển thị 😅 Hoặc tải dữ liệu ít quan trọng hơn, xử lý trước nội dung nào đó, tạo hình ảnh ở chế độ nền.

Thành thật mà nói, có lẽ số lượng trường hợp sử dụng cũng nhiều như số lượng nhà phát triển.

function trackUserScrolling() {
  console.log("User scrolled. This changes everything.");
}
if ("requestIdleCallback" in window) {
  requestIdleCallback(trackUserScrolling);
} else {
  setTimeout(trackUserScrolling, 0);
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hỗ trợ: trình duyệt hiện đại (trước đây bị thiếu trong Safari nên dự phòng vẫn là một ý tưởng hay)


2. “Tại sao nội dung nhập của tôi không được đánh dấu ???” → :tiêu điểm bên trong

Thật dễ dàng để tạo kiểu cho một phần tử có tiêu điểm. Nhưng nếu bạn muốn tạo kiểu cho div cha thì sao? Ví dụ: tô màu hồng, thêm vài bông hoa 😉 Bạn có thể viết 40 dòng JavaScript… hoặc chỉ cần sử dụng :focus-within.

Hoạt động. Không có người nghe. Không có lỗi. Không đau khổ.

.form-field {
  border: 1px solid #ccc;
  padding: 12px;
}
.form-field:focus-within {
  border-color: hotpink;
}

Vào chế độ toàn màn hình Thoát toàn màn hình chế độ

<div class="form-field">
  <input placeholder="Type something meaningful..." />
</div>

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hỗ trợ: về cơ bản ở mọi nơi quan trọng


3. “Hãy hiển thị chế độ ngoại tuyến” → navigator.onLine

Bạn đã bao giờ xây dựng PWA chưa? Bởi vì tôi có, và vấn đề muôn thuở là phải làm gì khi người dùng mất kết nối (ví dụ: họ đang ở nơi hoang dã hoặc vừa bước vào thang máy 😄). Bạn có thể viết một loạt các if phức tạp hoặc chỉ nghe ngoại tuyếntrực tuyến. Trên ngoại tuyến bạn có thể lưu trữ dữ liệu trong IndexedDB và khi người dùng trực tuyến trở lại, hãy gửi dữ liệu đó đến máy chủ.

window.addEventListener("offline", () => {
  alert("You are offline. Time to panic.");
});
window.addEventListener("online", () => {
  alert("You're back. Panic cancelled.");
});

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hỗ trợ: được hỗ trợ rộng rãi (nhưng “trực tuyến” ≠ “phần phụ trợ của bạn hoạt động” 😅)


4. “Hoạt ảnh mượt mà nhưng khiến nó bị nguyền rủa” → requestAnimationFrame

Tất cả chúng ta đều đã thấy điều này:

setInterval(() => {
  element.style.left = Math.random() * 100 + "px";
}, 16);

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Bạn có thể cảm thấy đây không phải là ý tưởng hay nhất 😉 Nó chỉ bị chậm thôi. Thật may là chúng tôi có requestAnimationFrame, được đồng bộ hóa với chu kỳ sơn lại của trình duyệt, nên mọi thứ thực sự diễn ra suôn sẻ.

function animate() {
  element.style.transform = `translateX(${Date.now() % 300}px)`;
  requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hỗ trợ: ở mọi nơi


5. “Thẻ này sẽ thích ứng… nhưng chỉ ở đây thôi” → truy vấn vùng chứa

Tính năng này có vẻ gần như không công bằng. Tôi đang ở một thời điểm trong sự nghiệp của mình mà tôi hầu như không còn viết CSS nữa (ngoại trừ những khoảnh khắc không thường xuyên như khoảnh khắc tôi mô tả ở đây: Học CSS có lãng phí thời gian vào năm 2026 không?).

Nhưng đã có lúc tôi viết rất nhiều về nó. Và thật tuyệt vời - tôi sẽ phải trả bao nhiêu tiền để áp dụng truy vấn phương tiện cho một phần tử cụ thể thay vì toàn bộ khung nhìn. Bây giờ cuối cùng chúng ta có thể. Thành phần này sẽ tự nhận thức và chúng ta có thể đi uống cà phê.

.card-wrapper {
  container-type: inline-size;
}
.card {
  display: grid;
}
@container (min-width: 400px) {
  .card {
    grid-template-columns: 1fr 2fr;
  }
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hỗ trợ: trình duyệt hiện đại (thêm dự phòng nếu cần)


6. “ID ngẫu nhiên, điều gì có thể xảy ra?” → crypto.getRandomValues

const id = Math.random().toString(36).slice(2);

Vào chế độ toàn màn hình Thoát toàn màn hình chế độ

Đây là cách mà lỗi được sinh ra. Nó trông giống như tiền điện tử “đủ tốt” từ AliExpress và hoạt động… cho đến khi nó không hoạt động. Trước hết, nó phụ thuộc vào việc triển khai động cơ - chúng tôi thực sự không biết điều gì đang xảy ra bên trong. Một số mẫu hoàn toàn có thể xảy ra và với đủ ID, về cơ bản bạn sẽ yêu cầu các bản sao.

May mắn thay, giờ đây chúng tôi đã có giải pháp gốc đơn giản. Đó không phải là viên đạn bạc, nhưng crypto.getRandomValues khá chắc chắn — entropy tốt hơn nhiều, không có kiểu mẫu kỳ lạ, giảm đáng kể khả năng va chạm. Trình duyệt thực hiện đúng cách.

const bytes = new Uint8Array(8);
crypto.getRandomValues(bytes);
const id = Array.from(bytes)
  .map(b => b.toString(16).padStart(2, "0"))
  .join("");
console.log("Secure-ish ID:", id);

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hỗ trợ: được hỗ trợ rộng rãi


7. “Chúng tôi cần một modal” → <hộp thoại>

Thật sự rất vui khi các trình duyệt cuối cùng cũng đã hỗ trợ và thông báo: được rồi, đây là phương thức của bạn 😄 Không còn phải cài đặt thư viện 12KB chỉ để mở hộp thoại mà người dùng vô cùng yêu thích. Cái này cũng có thể truy cập được theo mặc định, vì vậy win-win.

<dialog id="modal">
  <p>Are you sure you want to deploy on Friday?</p>
  <button onclick="modal.close()">Cancel</button>
  <button onclick="alert('Good luck 😬')">Deploy</button>
</dialog>
<button onclick="modal.showModal()">Open modal</button>

Hỗ trợ: trình duyệt hiện đại


8. “Nhập giọng nói sẽ rất tuyệt…” → API giọng nói

Có phải bạn đã cài đặt Transforms.js vì bạn cần nhận dạng giọng nói không? Hãy thư giãn - hóa ra trình duyệt cũng có thứ gì đó cho việc đó. Chà… ít nhất thì Chrome cũng vậy 😄 Vì vậy, nếu bạn có thể “khuyến khích” người dùng sử dụng Chrome, Edge hoặc thứ gì đó tương tự thì bạn đã ổn. Cá nhân tôi vẫn cẩn thận khi sử dụng sản xuất, nhưng đối với bản demo thì sao? Tại sao không.

const SpeechRecognition =
  window.SpeechRecognition || window.webkitSpeechRecognition;
if (SpeechRecognition) {
  const recognition = new SpeechRecognition();
  recognition.onresult = e => {
    console.log("You said:", e.results[0][0].transcript);
  };
  recognition.start();
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hỗ trợ: chủ yếu là Chrome


9. “Liệu CSS này có phát nổ không?” → @supports

Đây là giải pháp hiện đại cho giải pháp cổ điển “nó hoạt động trên máy của tôi” — ít nhất là trong CSS 😉 Bạn không cần phải đoán xem liệu điều gì đó có làm hỏng bố cục của mình hay không. Chỉ cần gói nó trong @supports. Có một nhược điểm nhỏ — mặc dù dịch vụ hỗ trợ rất tốt nhưng không phải ở mọi nơi, thật trớ trêu là… chúng ta có thể sử dụng @supports cho @supports.

.card {
  background: white;
}
@supports (backdrop-filter: blur(10px)) {
  .card {
    backdrop-filter: blur(10px);
    background: rgba(255, 255, 255, 0.6);
  }
}

Vào chế độ toàn màn hình Thoát chế độ toàn màn hình

Hỗ trợ: rất tốt


⚠️ Nhưng đừng hiểu lầm tôi

Thư viện thật tuyệt vời. Đôi khi bạn thực sự cần chúng. Nhưng đôi khi… bạn đang cài đặt một phần phụ thuộc cho thứ gì đó mà trình duyệt đã giải quyết từ nhiều năm trước. Trước khi cài đặt bất cứ thứ gì, chỉ cần tự hỏi bản thân (hoặc Google): “Có phải trình duyệt ở đây đã thông minh hơn tôi rồi không?” Đôi khi câu trả lời là có. Và điều đó… hoàn toàn ổn 😄

Tác giả: Sylwia Laskowska

#webdev#javascript#css#browser