Trong thế giới web hiện đại, JavaScript là một phần không thể thiếu, mang đến khả năng tạo ra các ứng dụng web mạnh mẽ và tương tác cao. Tuy nhiên, việc sử dụng JavaScript cũng có thể gây ra những thách thức cho SEO nếu không được tối ưu đúng cách. Đặc biệt, khi các trang hoặc nội dung của bạn không xuất hiện trên Google Tìm kiếm, có thể nguyên nhân nằm ở việc xử lý JavaScript. Bài viết này sẽ giúp bạn hiểu rõ hơn về cách Google xử lý JavaScript và cung cấp những phương pháp tốt nhất để tối ưu hóa SEO cho các ứng dụng web sử dụng JavaScript.
Nếu bạn nghi ngờ rằng trang web hoặc một số nội dung của mình không xuất hiện trên Google Tìm kiếm do vấn đề liên quan đến JavaScript, hãy tham khảo hướng dẫn khắc phục sự cố của chúng tôi để tìm giải pháp.
JavaScript là một phần không thể thiếu của nền tảng web, cung cấp nhiều tính năng giúp biến web thành một nền tảng ứng dụng mạnh mẽ. Đảm bảo rằng các ứng dụng web sử dụng JavaScript có thể dễ dàng được tìm thấy qua Google Tìm kiếm sẽ giúp bạn thu hút người dùng mới và duy trì sự quan tâm của người dùng hiện tại khi họ tìm kiếm nội dung mà ứng dụng của bạn cung cấp. Mặc dù Google Tìm kiếm tự động chạy JavaScript bằng một phiên bản Chromium được cập nhật thường xuyên, nhưng vẫn có thể tối ưu hóa một số yếu tố quan trọng.
Hướng dẫn này sẽ mô tả chi tiết cách Google Tìm kiếm xử lý JavaScript và cung cấp các phương pháp tối ưu nhất để cải thiện hiệu suất của các ứng dụng web sử dụng JavaScript trong Google Tìm kiếm.
Cách Google xử lý JavaScript
Google xử lý các ứng dụng web dùng JavaScript theo ba giai đoạn chính:
- Thu thập dữ liệu
- Kết xuất
- Lập chỉ mục
Googlebot xếp hàng các trang web để tiến hành thu thập dữ liệu và kết xuất nội dung. Việc phân biệt giữa một trang đang chờ thu thập dữ liệu và một trang đang chờ kết xuất thường không dễ dàng.
Khi Googlebot truy cập một URL từ hàng đợi thu thập dữ liệu thông qua yêu cầu HTTP, nó sẽ kiểm tra xem trang đó có cho phép thu thập dữ liệu hay không. Điều này được thực hiện bằng cách đọc tệp robots.txt. Nếu tệp này ngăn chặn việc thu thập dữ liệu từ URL đó, Googlebot sẽ bỏ qua yêu cầu HTTP và không xử lý URL đó nữa.
Sau khi xác nhận, Googlebot phân tích cú pháp nội dung phản hồi để tìm các URL khác được nhúng trong thuộc tính href của các liên kết HTML, rồi thêm các URL đó vào hàng đợi thu thập dữ liệu. Để ngăn Googlebot tìm ra những liên kết này, bạn có thể sử dụng thuộc tính nofollow.
Bạn cũng có thể sử dụng JavaScript để chèn các liên kết vào DOM, miễn là những liên kết này tuân thủ các phương pháp tốt nhất để đảm bảo chúng có thể được thu thập dữ liệu.
Phương pháp thu thập dữ liệu URL và phân tích cú pháp nội dung HTML phản hồi hoạt động hiệu quả đối với các trang web truyền thống hoặc các trang được kết xuất phía máy chủ, nơi HTML đã có sẵn toàn bộ nội dung trong phản hồi HTTP. Tuy nhiên, một số trang web sử dụng JavaScript có thể áp dụng mô hình giao diện ứng dụng, trong đó HTML ban đầu không chứa nội dung thực tế. Trong trường hợp này, Google cần thực thi JavaScript để có thể xem được nội dung thực tế của trang.
Googlebot sẽ đưa tất cả các trang vào hàng đợi kết xuất, trừ khi tiêu đề hoặc thẻ meta robots chỉ thị rằng trang không nên được lập chỉ mục. Thời gian một trang nằm trong hàng đợi này có thể kéo dài từ vài giây đến lâu hơn, tùy thuộc vào khả năng xử lý của Google. Khi tài nguyên sẵn sàng, Google sẽ sử dụng một phiên bản Chromium không có giao diện người dùng để kết xuất trang và thực thi JavaScript. Googlebot sẽ phân tích cú pháp HTML đã được kết xuất để tìm kiếm các liên kết và thêm những URL mới tìm thấy vào hàng đợi thu thập dữ liệu. HTML đã kết xuất này cũng được sử dụng để lập chỉ mục trang.
Nên nhớ rằng, kết xuất phía máy chủ hoặc kết xuất trước là các phương pháp tối ưu vì chúng giúp trang web của bạn tải nhanh hơn cho cả người dùng và trình thu thập dữ liệu. Hơn nữa, không phải tất cả các bot đều có khả năng thực thi JavaScript.
Mô tả trang bằng tiêu đề và đoạn trích độc đáo
Các phần tử <title> được tối ưu hóa và độc nhất, cùng với mô tả meta hữu ích, sẽ giúp người dùng dễ dàng tìm thấy kết quả phù hợp nhất với nhu cầu của họ. Chúng tôi cung cấp các nguyên tắc chi tiết về cách xây dựng phần tử <title> và mô tả meta chất lượng cao.
Bạn có thể sử dụng JavaScript để thiết lập hoặc cập nhật nội dung cho mô tả meta và phần tử <title>.
Google Tìm kiếm có thể hiển thị một tiêu đề liên kết khác dựa trên truy vấn tìm kiếm của người dùng. Hiện tượng này xảy ra khi tiêu đề hoặc mô tả của trang không liên quan chặt chẽ đến nội dung trên trang hoặc khi chúng tôi phát hiện các lựa chọn khác trên trang có liên quan hơn đến truy vấn tìm kiếm. Tìm hiểu thêm về nguyên nhân khiến tiêu đề trong kết quả tìm kiếm có thể khác với phần tử <title> của trang.
Viết mã tương thích
Các trình duyệt cung cấp nhiều API và JavaScript là một ngôn ngữ phát triển nhanh chóng. Google có một số giới hạn về các API và tính năng JavaScript được hỗ trợ. Để đảm bảo mã của bạn tương thích với Google, hãy tuân theo các nguyên tắc của chúng tôi để khắc phục các sự cố liên quan đến JavaScript.
Bạn nên sử dụng tính năng phân phát có điều kiện và các đoạn polyfill nếu phát hiện API trình duyệt mà bạn cần không nằm trong danh sách API được hỗ trợ. Một số tính năng của trình duyệt không thể sử dụng polyfill, vì vậy bạn nên tham khảo tài liệu về polyfill để nắm rõ các hạn chế (nếu có).
Sử dụng mã trạng thái HTTP có ý nghĩa
Googlebot sử dụng mã trạng thái HTTP để xác định các vấn đề khi thu thập dữ liệu trang.
Để thông báo cho Googlebot về một trang không thể thu thập dữ liệu hoặc lập chỉ mục, hãy sử dụng mã trạng thái phù hợp, chẳng hạn như 404 cho trang không tìm thấy hoặc 401 cho trang yêu cầu đăng nhập. Bạn có thể tận dụng mã trạng thái HTTP để báo hiệu cho Googlebot khi một trang đã được chuyển hướng sang URL mới, giúp Googlebot cập nhật chỉ mục tương ứng.
Dưới đây là danh sách mã trạng thái HTTP và tác động của chúng đối với Google Tìm kiếm.
Tránh các lỗi soft 404 trong ứng dụng trang đơn
Trong các ứng dụng trang đơn (SPA) kết xuất phía máy khách, định tuyến thường được triển khai dưới dạng định tuyến phía máy khách. Trong trường hợp này, việc sử dụng mã trạng thái HTTP có ý nghĩa có thể không khả thi hoặc không hiệu quả. Để tránh lỗi soft 404 khi sử dụng kết xuất và định tuyến phía máy khách, hãy áp dụng một trong các chiến lược sau:
- Sử dụng lệnh chuyển hướng JavaScript đến một URL mà máy chủ phản hồi bằng mã trạng thái HTTP 404 (ví dụ: /not-found).
- Thêm thẻ
<meta name="robots" content="noindex">vào các trang lỗi bằng JavaScript.
Dưới đây là mã mẫu cho phương pháp sử dụng lệnh chuyển hướng:
fetch(`/api/products/${productId}`)
.then(response => response.json())
.then(product => {
if(product.exists) {
showProductDetails(product); // hiển thị thông tin sản phẩm trên trang
} else {
// sản phẩm này không tồn tại, đây là trang lỗi
window.location.href = '/not-found'; // chuyển hướng đến trang 404 trên máy chủ
}
})
Dưới đây là mã mẫu cho phương pháp sử dụng thẻ noindex:
fetch(`/api/products/${productId}`)
.then(response => response.json())
.then(product => {
if(product.exists) {
showProductDetails(product); // hiển thị thông tin sản phẩm trên trang
} else {
// sản phẩm này không tồn tại, đây là trang lỗi
// lưu ý: ví dụ này giả định không có thẻ meta robots nào khác trong HTML
const metaRobots = document.createElement('meta');
metaRobots.name = 'robots';
metaRobots.content = 'noindex';
document.head.appendChild(metaRobots);
}
})Sử dụng API lịch sử thay vì các mảnh
Google chỉ có thể thu thập dữ liệu đường liên kết của bạn nếu đó là phần tử HTML <a> có thuộc tính href.
Đối với các ứng dụng trang đơn định tuyến phía máy khách, hãy sử dụng History API để triển khai định tuyến giữa các chế độ xem của ứng dụng web. Để đảm bảo Googlebot có thể phân tích và trích xuất các URL, hãy tránh sử dụng các mảnh URL (fragments) để tải những nội dung trang khác nhau. Ví dụ dưới đây minh họa một phương pháp không tối ưu vì Googlebot không thể xử lý các URL một cách đáng tin cậy:
<nav>
<ul>
<li><a href="#/products">Our products</a></li>
<li><a href="#/services">Our services</a></li>
</ul>
</nav><h1>Welcome to example.com!</h1><div id=“placeholder”>
<p>Learn more about <a href=“#/products”>our products</a> and <a href=“#/services”>our services</p>
</div>
<script>
window.addEventListener(‘hashchange’, function goToPage() {
// hàm này tải nội dung khác nhau dựa trên mảnh URL hiện tại
const pageToLoad = window.location.hash.slice(1); // mảnh URL
document.getElementById(‘placeholder’).innerHTML = load(pageToLoad);
});
</script>
Thay vào đó, bạn có thể triển khai History API để đảm bảo Googlebot có thể truy cập các URL:
<nav>
<ul>
<li><a href="/products">Our products</a></li>
<li><a href="/services">Our services</a></li>
</ul>
</nav><h1>Welcome to example.com!</h1><div id=“placeholder”>
<p>Learn more about <a href=“/products”>our products</a> and <a href=“/services”>our services</p>
</div>
<script>
function goToPage(event) {
event.preventDefault(); // ngăn trình duyệt chuyển hướng đến URL đích
const hrefUrl = event.target.getAttribute(‘href’);
const pageToLoad = hrefUrl.slice(1); // loại bỏ dấu gạch chéo đầu tiên
document.getElementById(‘placeholder’).innerHTML = load(pageToLoad);
window.history.pushState({}, window.title, hrefUrl); // cập nhật URL cũng như lịch sử trình duyệt
}
// bật định tuyến phía máy khách cho tất cả liên kết trên trangdocument.querySelectorAll(‘a’).forEach(link => link.addEventListener(‘click’, goToPage));
</script>
Chèn thẻ rel=”canonical” cho đường liên kết một cách chính xác
Mặc dù không khuyến khích sử dụng JavaScript trong trường hợp này, nhưng bạn có thể chèn thẻ rel=”canonical” cho đường liên kết bằng JavaScript. Google Tìm kiếm sẽ chọn URL chính tắc được chèn khi hiển thị trang. Dưới đây là ví dụ về cách chèn thẻ liên kết rel=”canonical” bằng JavaScript:
fetch('/api/cats/' + id)
.then(function (response) { return response.json(); })
.then(function (cat) {
// tạo thẻ liên kết canonical và xây dựng động URL
// ví dụ: https://example.com/cats/simba
const linkTag = document.createElement('link');
linkTag.setAttribute('rel', 'canonical');
linkTag.href = 'https://example.com/cats/' + cat.urlFriendlyName;
document.head.appendChild(linkTag);
});
Khi sử dụng JavaScript để chèn thẻ liên kết rel=”canonical”, hãy đảm bảo rằng đây là thẻ liên kết rel=”canonical” duy nhất trên trang. Nếu triển khai không đúng cách, có thể bạn sẽ tạo ra nhiều thẻ liên kết rel=”canonical” hoặc thay đổi một thẻ hiện có, gây ra tình trạng xung đột hoặc nhiều thẻ rel=”canonical”. Điều này có thể dẫn đến kết quả không mong muốn trong quá trình lập chỉ mục.
Thận trọng khi sử dụng thẻ meta robots
Thông qua thẻ meta robots, bạn có thể ngăn Google lập chỉ mục một trang hoặc theo dõi các đường liên kết trên trang đó. Ví dụ, việc thêm thẻ meta sau vào phần đầu của trang sẽ chặn Google lập chỉ mục trang này:
html
<!-- Google sẽ không lập chỉ mục trang này hoặc theo dõi các liên kết trên trang -->
<meta name="robots" content="noindex, nofollow">
Bạn cũng có thể sử dụng JavaScript để thêm thẻ meta robots vào trang hoặc thay đổi nội dung của trang đó. Đoạn mã sau đây minh họa cách thay đổi thẻ meta robots bằng JavaScript để ngăn Google lập chỉ mục trang hiện tại nếu API trả về lỗi:
fetch('/api/products/' + productId)
.then(function (response) { return response.json(); })
.then(function (apiResponse) {
if (apiResponse.isError) {
// lấy thẻ meta robots
var metaRobots = document.querySelector('meta[name="robots"]');
// nếu không có thẻ meta robots, thêm một thẻ mới
if (!metaRobots) {
metaRobots = document.createElement('meta');
metaRobots.setAttribute('name', 'robots');
document.head.appendChild(metaRobots);
}
// yêu cầu Google loại trừ trang này khỏi chỉ mục
metaRobots.setAttribute('content', 'noindex');
// hiển thị thông báo lỗi cho người dùng
errorMsg.textContent = 'Sản phẩm này không còn khả dụng';
return;
}
// hiển thị thông tin sản phẩm
// ...
});
Nếu Google gặp thẻ noindex trong thẻ meta robots trước khi chạy JavaScript, Google sẽ không kết xuất hoặc lập chỉ mục trang đó.
Google sẽ bỏ qua việc kết xuất và thực thi JavaScript nếu thẻ meta robots ban đầu có chứa noindex. Do đó, việc sử dụng JavaScript để thay đổi hoặc xoá thẻ meta robots có thể không mang lại kết quả như mong muốn. Nếu có khả năng bạn muốn Google lập chỉ mục trang đó, hãy tránh sử dụng thẻ noindex trong mã gốc của trang.
Sử dụng phương pháp lưu vào bộ nhớ đệm dài hạn
Googlebot thường lưu nội dung vào bộ nhớ đệm để giảm số lượng yêu cầu gửi đến mạng và tiết kiệm tài nguyên. Tuy nhiên, Web Rendering Service (WRS) có thể bỏ qua các tiêu đề bộ nhớ đệm, dẫn đến việc sử dụng các tài nguyên JavaScript hoặc CSS đã cũ. Bạn có thể tránh vấn đề này bằng cách sử dụng kỹ thuật fingerprinting (vân tay số) cho các tệp nội dung, ví dụ như đặt tên tệp là main.2bb85551.js. Vân tay số này sẽ thay đổi dựa trên nội dung của tệp, do đó tên tệp sẽ thay đổi mỗi khi bạn cập nhật. Để tìm hiểu thêm, hãy tham khảo hướng dẫn trên web.dev về các chiến lược lưu vào bộ nhớ đệm dài hạn.
Sử dụng dữ liệu có cấu trúc
Khi triển khai dữ liệu có cấu trúc trên các trang, bạn có thể sử dụng JavaScript để tạo nội dung JSON-LD và đưa vào trang. Đảm bảo kiểm tra kỹ việc triển khai để tránh các sự cố không mong muốn.
Thực hiện theo các phương pháp hay nhất cho thành phần web
Google hỗ trợ thành phần web. Khi kết xuất trang, Google sẽ gộp nội dung trong Shadow DOM và Light DOM thành một. Điều này có nghĩa là Google chỉ thấy nội dung xuất hiện trong HTML đã kết xuất. Để đảm bảo Googlebot có thể thấy nội dung của bạn sau khi kết xuất, hãy sử dụng Công cụ kiểm tra kết quả nhiều định dạng hoặc Công cụ kiểm tra URL để kiểm tra HTML đã kết xuất.
Nếu nội dung không xuất hiện trong HTML đã kết xuất, Google sẽ không thể lập chỉ mục nội dung đó.
Trong ví dụ sau, một thành phần web được tạo ra để hiển thị nội dung Light DOM bên trong Shadow DOM. Một cách để đảm bảo rằng cả nội dung Shadow DOM và Light DOM đều xuất hiện trong HTML đã kết xuất là sử dụng phần tử <slot>.
<script>
class MyComponent extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
}connectedCallback() {let p = document.createElement(‘p’);
p.innerHTML = ‘Hello World, this is shadow DOM content. Here comes the light DOM: <slot></slot>’;
this.shadowRoot.appendChild(p);
}
}
window.customElements.define(‘my-component’, MyComponent);</script>
<my-component><p>This is light DOM content. It’s projected into the shadow DOM.</p>
<p>WRS renders this content as well as the shadow DOM content.</p>
</my-component>
Sau khi kết xuất, Google có thể lập chỉ mục nội dung này:
<my-component>
Hello World, this is shadow DOM content. Here comes the light DOM:
<p>This is light DOM content. It's projected into the shadow DOM.</p>
<p>WRS renders this content as well as the shadow DOM content.</p>
</my-component>Khắc phục vấn đề về hình ảnh và nội dung tải từng phần
Hình ảnh có thể tiêu tốn nhiều băng thông và ảnh hưởng nghiêm trọng đến hiệu suất trang web. Một chiến lược hiệu quả là sử dụng phương pháp tải từng phần (lazy loading) để chỉ tải hình ảnh khi người dùng sắp cuộn đến chúng. Để đảm bảo việc triển khai tải từng phần phù hợp với các yêu cầu của công cụ tìm kiếm, hãy tuân theo các nguyên tắc về cơ chế tải từng phần mà chúng tôi đã đề xuất.
Thiết kế trang web nhằm hỗ trợ khả năng tiếp cận
Hãy tạo trang web không chỉ dành cho các công cụ tìm kiếm mà còn cho người dùng. Khi thiết kế, cần cân nhắc đến nhu cầu của mọi người dùng, bao gồm cả những người không sử dụng trình duyệt hỗ trợ JavaScript, như người dùng trình đọc màn hình hoặc các thiết bị di động đời cũ. Một cách đơn giản để kiểm tra khả năng tiếp cận của trang web là xem trước trang đó bằng trình duyệt đã tắt JavaScript hoặc sử dụng một trình duyệt chỉ hỗ trợ văn bản như Lynx. Bằng cách xem trang web dưới dạng văn bản thuần túy, bạn cũng có thể phát hiện các nội dung mà Googlebot có thể khó nhận diện, chẳng hạn như văn bản được nhúng trong hình ảnh.
Tối ưu hóa SEO cho các trang web sử dụng JavaScript đòi hỏi sự hiểu biết sâu sắc về cách Googlebot xử lý nội dung. Bằng cách tuân thủ các phương pháp tốt nhất và kiểm tra kỹ lưỡng, bạn có thể đảm bảo rằng trang web của mình không chỉ hoạt động tốt cho người dùng mà còn đạt hiệu quả cao trong kết quả tìm kiếm. Điều này sẽ giúp bạn thu hút thêm người dùng mới và duy trì sự quan tâm của người dùng hiện tại.
