Việt Gia Trang

Quán nhỏ ven đường

  • Cuộc sống
    • Những câu nói hay về cuộc sống
  • Thơ hay
  • Công Nghệ
  • Phim
  • Game
  • Tính phần trăm (%) online

October 10, 2026 by ModTN Leave a Comment

Phân trang PHP 2026: Kỹ thuật tối ưu cho website bán hàng và SEO

Có một kiểu ác mộng mà chỉ dân làm web mới thấu: trưa thứ Bảy đẹp trời, sếp nhắn tin bảo web sập, khách vào trang danh mục điện thoại hay son môi cứ xoay vòng tròn vô tận. Bạn lật đật bật máy tính lên kiểm tra, thấy máy chủ quá tải CPU ở mức một trăm phần trăm. Thủ phạm chẳng phải hacker tấn công từ chối dịch vụ (DDoS) nào xa xôi, mà đến từ chính một con bọ tìm kiếm đang cào dữ liệu ở trang danh mục thứ hai nghìn. Câu lệnh truy vấn cơ sở dữ liệu treo cứng ngắc hàng chục giây.

Mọi chuyện bắt đầu từ bài học vỡ lòng khi chúng ta mới bập bẹ học viết mã: làm danh sách thì gắn thêm chức năng phân trang php vào cho gọn. Nhưng cái cách mà hầu hết các bài hướng dẫn trên mạng dạy bạn từ mười năm trước giờ đây đang âm thầm bóp nghẹt hệ thống của bạn mỗi ngày. Nhiều anh em cứ đinh ninh phân trang là chuyện cỏ con, chỉ cần nhét vài tham số vào truy vấn là êm xuôi. Thực tế chiến trường lại khốc liệt hơn thế rất nhiều.

Ảo tưởng về LIMIT OFFSET: Khi cơ sở dữ liệu phải chạy marathon

Hồi mới vào nghề, mình cũng giống như phần lớn các bạn lập trình viên khác. Cứ hễ làm chức năng phân trang php là trong đầu tự động nảy số ra công thức thần thánh: lấy số trang hiện tại trừ một, nhân với số lượng bản ghi mỗi trang, rồi ném vào mệnh đề LIMIT kèm OFFSET trong MySQL. Viết xong thấy trang một chạy mượt mà trong mười mili-giây, trang hai cũng vèo vèo, thế là tự tin bàn giao cho khách hàng.

Đến khi dữ liệu phình to lên tầm vài trăm nghìn đơn hàng hay vài chục nghìn sản phẩm, câu chuyện lập tức đổi màu. Bạn hãy tưởng tượng cơ sở dữ liệu giống như một anh thủ kho trong một kho hàng khổng lồ chứa một triệu thùng hàng được đánh số. Khi bạn bảo anh ấy: “Lấy cho tôi hai mươi thùng ở trang năm nghìn, tương ứng với việc bỏ qua một trăm nghìn thùng đầu tiên”, chuyện gì sẽ xảy ra?

Anh thủ kho không có phép thần thông để dịch chuyển tức thời đến thùng thứ một trăm nghìn lẻ một. Cơ chế hoạt động của OFFSET buộc anh ta phải lội bộ từ thùng đầu tiên, đếm đủ một trăm nghìn thùng, vứt toàn bộ số đó sang một bên, rồi mới nhặt ra đúng hai mươi thùng tiếp theo để giao cho bạn. Càng về những trang sau, quãng đường anh ta phải lội bộ càng xa. Đến trang thứ mười nghìn, anh ta kiệt sức, máy chủ bốc khói, và người dùng của bạn nhận về lỗi quá thời gian chờ (timeout) trắng xóa màn hình.

Nhiều bạn nghĩ rằng cứ tạo chỉ mục (index) cho bảng là giải quyết được vấn đề này. Chỉ mục giúp việc tìm kiếm nhanh hơn, nhưng nó vẫn không cứu nổi việc máy chủ phải duyệt qua hàng trăm nghìn dòng trong cây chỉ mục rồi mới loại bỏ chúng. Càng nhiều dữ liệu, chi phí bộ nhớ đệm (buffer pool) bị chiếm dụng càng lớn, đẩy toàn bộ các truy vấn khác vào thế nghẽn cổ chai. Cách làm này vô tình biến một tính năng cơ bản thành một quả bom nổ chậm trên chính hệ thống của bạn.

Keyset Pagination: Lối thoát đưa tốc độ về con số mili-giây

Để giải bài toán này mà không làm khổ máy chủ, giới kỹ thuật có một lối đi khác gọi là phân trang theo khóa (keyset pagination) hay còn gọi là phân trang dựa trên con trỏ (cursor-based pagination). Nghe có vẻ đao to búa lớn, bản chất của nó lại vô cùng mộc mạc: thay vì bắt anh thủ kho đếm lại từ đầu, bạn chỉ cần đưa cho anh ta số hiệu của thùng hàng cuối cùng mà bạn vừa xem.

Lấy ví dụ cụ thể, thay vì viết một câu lệnh nặng nề như thế này:

SELECT * FROM san_pham ORDER BY id DESC LIMIT 20 OFFSET 100000;

Bạn đổi cách tiếp cận thành:

SELECT * FROM san_pham WHERE id < 900000 ORDER BY id DESC LIMIT 20;

Sự khác biệt ở đây mang tính bản chất. Với câu lệnh thứ hai, MySQL dựa thẳng vào chỉ mục của cột định danh để nhảy bổ ngay đến bản ghi có mã nhỏ hơn chín trăm nghìn, nhặt đúng hai mươi dòng kế tiếp rồi dừng lại ngay lập tức. Tốc độ thực thi ở trang đầu tiên hay trang thứ một trăm nghìn đều phẳng lì như nhau, chỉ mất khoảng vài mili-giây. Bạn vừa giải phóng cho máy chủ hàng tấn công việc vô nghĩa.

Món này cũng có cái giá của nó, không phải chiếc đũa thần áp dụng bừa bãi được đâu. Nhược điểm chí mạng của phân trang theo khóa là bạn đánh mất khả năng nhảy cóc đến một trang bất kỳ. Người dùng chỉ có thể bấm “Trang kế tiếp” hoặc “Trang trước đó”, chứ không thể một phát nhảy từ trang một sang trang năm mươi. Vì vậy, giải pháp này cực kỳ phù hợp cho bảng tin mạng xã hội, danh sách lịch sử đơn hàng, nhật ký hệ thống, hoặc danh mục sản phẩm trên thiết bị di động nơi người dùng có thói quen cuộn liên tục thay vì săm soi từng số trang.

Bẫy trùng lặp khi sắp xếp theo cột không duy nhất

Khi áp dụng kỹ thuật này vào thực tế, nhiều bạn trẻ ăn ngay một cú ngã đau điếng vì sắp xếp theo ngày tạo hoặc giá bán. Một ngày nọ, một sàn thương mại điện tử gặp sự cố hy hữu: khách hàng mua son môi phàn nàn rằng ở trang hai thấy thỏi son ba trăm nghìn đồng của hãng nọ, bấm sang trang ba vẫn thấy đúng thỏi son đó, trong khi một số sản phẩm khác lại biến mất bí ẩn.

Nguyên nhân nằm ở chỗ: có hàng trăm sản phẩm có cùng mức giá hoặc cùng thời điểm tạo đến từng giây. Khi bạn dùng điều kiện so sánh lớn hơn hoặc nhỏ hơn trên một cột không duy nhất, mốc chặn sẽ bị nhảy lung tung, dẫn đến việc bản ghi bị sót hoặc hiển thị lặp lại. Cách xử lý chuẩn chỉ là tạo một chỉ mục phức hợp gồm hai cột, kết hợp giữa cột bạn muốn sắp xếp và cột khóa chính. Khi truy vấn, chúng ta so sánh cặp giá trị để đảm bảo vị trí con trỏ luôn luôn là duy nhất trên toàn bộ tập dữ liệu.

Cơn ác mộng đếm tổng số bản ghi và nghệ thuật buông bỏ

Cơn ác mộng đếm tổng số bản ghi và nghệ thuật buông bỏ

Có một thói quen cố hữu trong tư duy lập trình: hễ làm phân trang php là phải chạy một câu lệnh đếm tổng số dòng để tính xem có tất cả bao nhiêu trang rồi vẽ ra thanh điều hướng. Chính câu lệnh tưởng chừng vô hại đó lại là thủ phạm thứ hai kéo sập website của bạn.

Hãy nhìn thẳng vào sự thật: câu lệnh đếm toàn bộ bảng dữ liệu lớn trong các hệ quản trị cơ sở dữ liệu giao dịch là một tác vụ cực kỳ tốn kém. Cơ sở dữ liệu phải quét qua từng bản ghi để xác định xem dòng đó có thực sự tồn tại và hiển thị được hay không. Càng nhiều bảng phụ được kết nối vào qua các mệnh đề JOIN, câu lệnh đếm càng trở nên nặng nề.

Khách hàng vào website của bạn để mua một chiếc áo sơ mi hay một hộp phấn, họ có thực sự quan tâm danh mục đó có chính xác năm mươi hai nghìn ba trăm bốn mươi mốt sản phẩm hay không? Câu trả lời là chẳng ai rảnh rỗi đến mức ấy. Những ông lớn thương mại điện tử hàng đầu thế giới từ lâu đã bỏ việc hiển thị chính xác tổng số trang đối với các danh mục khổng lồ. Họ chỉ hiển thị tối đa một trăm trang, hoặc đơn giản là hiển thị nút “Xem thêm” kèm theo thông báo ước lượng.

Nếu hệ thống bắt buộc phải hiển thị con số này cho bộ phận vận hành quản trị, bạn hãy dùng bộ nhớ đệm (cache) bằng Redis hoặc Memcached để lưu lại kết quả đếm trong vài tiếng đồng hồ. Thậm chí với các bảng dữ liệu quá lớn, việc đọc số dòng ước tính từ bảng thông tin hệ thống của cơ sở dữ liệu sẽ nhanh hơn hàng nghìn lần so với việc bắt máy chủ đếm thủ công từng bản ghi trong thời gian thực.

Tối ưu phân trang PHP chuẩn SEO: URL, Canonical và Rel Next/Prev

Sau khi giải quyết xong bài toán hiệu năng dưới tầng cơ sở dữ liệu, chúng ta bước lên mặt đất để đối mặt với một vấn đề nhức nhối không kém: làm sao để công cụ tìm kiếm hiểu và lập chỉ mục danh mục của bạn một cách tối ưu. Rất nhiều bạn lập trình viên làm xong phân trang nhưng để mặc cho bộ phận tối ưu hóa công cụ tìm kiếm (SEO) phải ôm đầu vì lỗi trùng lặp nội dung hoặc lãng phí ngân sách thu thập dữ liệu (crawl budget).

Sai lầm phổ biến nhất ở các dự án nội địa là việc đặt thẻ đường dẫn chuẩn (canonical) của trang hai, trang ba trỏ ngược về trang một. Người làm kỹ thuật nghĩ rằng làm vậy sẽ tránh được lỗi trùng lặp nội dung cho danh mục sản phẩm. Hậu quả là Google coi toàn bộ sản phẩm nằm từ trang hai trở đi như những nội dung rác không cần thiết, dẫn đến việc hàng nghìn sản phẩm phía sau biến mất hoàn toàn khỏi kết quả tìm kiếm.

Nguyên tắc vàng của việc xử lý thẻ đường dẫn chuẩn cho trang phân trang là: trang nào phải tự trỏ về chính nó. Trang hai phải có thẻ đường dẫn chuẩn trỏ về trang hai, kèm theo đầy đủ các tham số định danh rõ ràng. Google đủ thông minh để nhận biết đây là một chuỗi phân trang tuần tự của cùng một danh mục lớn, theo đúng các chỉ dẫn trong tài liệu của Google Search Central về cấu trúc nội dung phân trang.

Đối với các thẻ chỉ dẫn quan hệ trang trước và trang sau, dù các thuật toán tìm kiếm đã phát triển vượt bậc và không còn phụ thuộc hoàn toàn vào chúng để nhóm cụm trang như trước kia, việc khai báo mạch lạc trong mã nguồn vẫn giúp các công cụ thu thập dữ liệu hiểu được cấu trúc phân cấp website một cách trơn tru nhất.

Giữ nguyên tham số lọc: Bài học giữ chân khách hàng

Một chi tiết kỹ thuật nhỏ nhưng thể hiện sự tinh tế của người lập trình viên: đừng bao giờ làm rơi mất tham số lọc của người dùng khi họ bấm chuyển trang. Đặt trường hợp một vị khách đang tìm “giày thể thao nam dưới năm trăm nghìn đồng size 42”, họ xem hết mười sản phẩm ở trang một và bấm sang trang hai. Nếu đoạn mã PHP của bạn chỉ truyền mỗi tham số số trang mà quên gom lại các tham số truy vấn trên thanh địa chỉ, toàn bộ bộ lọc sẽ bị xóa sạch.

Khách hàng lập tức bị ném về trang hai của toàn bộ danh mục giày thể thao tổng hợp, hiển thị đủ loại giày nữ và các mức giá tiền triệu. Cảm giác bực bội đó sẽ khiến họ thoát trang ngay lập tức. Trong PHP, việc bảo lưu các tham số này cực kỳ đơn giản nếu bạn biết tận dụng các hàm xử lý mảng tham số truy vấn sẵn có để ghép nối lại đường dẫn trước khi in ra giao diện.

Khi cấu trúc nội dung và kỹ thuật phân trang trên website đã được tối ưu chỉn chu, tốc độ tải trang nhanh và bot tìm kiếm di chuyển mượt mà, đó là lúc nền móng kỹ thuật của bạn đã vững vàng. Lúc này, để các trang danh mục cạnh tranh thứ hạng ở những từ khóa khó, bạn sẽ cần thêm sức bật từ nguồn lực bên ngoài. Việc tìm kiếm một đơn vị cung cấp dịch vụ backlink uy tín, đi link thủ công mũ trắng trên các tên miền có độ uy tín cao sẽ là đòn bẩy quan trọng giúp đẩy toàn bộ dàn trang danh mục của bạn lên đỉnh bảng xếp hạng tìm kiếm.

Trải nghiệm trên di động: Ngón tay cái 44px và nút bấm tàng hình

Trải nghiệm trên di động: Ngón tay cái 44px và nút bấm tàng hình

Nhiều bạn tối ưu mã nguồn rất tâm huyết, đo kiểm trên máy tính bàn đạt điểm số xanh mướt, nhưng giao diện hiển thị trên điện thoại lại là một thảm họa công thái học. Hơn tám mươi phần trăm lượng truy cập mua sắm hiện nay đến từ màn hình cảm ứng di động. Vậy mà vào các trang bán hàng, thanh phân trang vẫn chèn một hàng dài dằng dặc từ trang một đến trang mười lăm với kích thước bé xíu.

Trên thiết bị di động, vùng chạm ngón tay cái của một người trưởng thành thường cần diện tích tối thiểu khoảng 44 pixel mỗi chiều. Khi bạn thiết kế các nút bấm số trang cao chưa đầy 30 pixel lại còn nằm san sát nhau, việc bấm nhầm sang trang bên cạnh xảy ra như cơm bữa. Người dùng bấm trượt hai lần là họ mất kiên nhẫn và tắt tab ngay lập tức.

Trên màn hình điện thoại, hãy mạnh dạn tinh giản giao diện thanh phân trang. Bạn chỉ cần giữ lại nút lùi, nút tiến, cùng với số trang hiện tại nằm giữa hai dấu ba chấm là đủ. Một giải pháp tuyệt vời hơn cho trải nghiệm mua sắm là sử dụng nút bấm “Xem thêm sản phẩm”. Nút này cho phép tải thêm dữ liệu bằng kỹ thuật bất đồng bộ (AJAX) gắn liền vào danh sách hiện tại. Người dùng vừa giữ được mạch duyệt hàng liền mạch, vừa không phải chịu cảnh tải lại toàn bộ trang web.

Nếu bạn chọn giải pháp cuộn vô hạn, hãy cẩn thận với phần chân trang (footer). Đã có vô số website gặp tình trạng khách hàng muốn tìm số điện thoại tổng đài hay chính sách đổi trả ở chân trang, nhưng cứ cuộn chuột xuống gần tới nơi thì hệ thống lại tự động tải thêm sản phẩm mới và đẩy chân trang xuống sâu hơn. Cảm giác đuổi bắt vô vọng đó gây ức chế cực kỳ lớn cho người mua hàng.

Kiểm tra lại mã nguồn của bạn ngay hôm nay

Sau tất cả những phân tích kỹ thuật vừa rồi, việc tốt nhất bạn có thể làm ngay lúc này là mở tập tin xử lý danh sách dữ liệu trong dự án của mình ra và soi lại từng dòng lệnh. Đừng đợi đến khi máy chủ cảnh báo đỏ lòm hay khách hàng than phiền mới bắt tay vào sửa chữa.

Hãy bắt đầu bằng những việc đơn giản nhất nhưng mang lại hiệu quả ngay tức thì:

  • Ép kiểu số nguyên thật chặt chẽ cho tham số trang nhận về từ người dùng để bịt kín các lỗ hổng bảo mật tiềm ẩn.
  • Kiểm tra lại xem thẻ đường dẫn chuẩn trên các trang danh mục đã tự trỏ về chính nó cùng với số trang tương ứng hay chưa.
  • Đo đạc thời gian thực thi của câu lệnh đếm tổng số dòng; nếu bảng dữ liệu đã vượt quá vài chục nghìn bản ghi, hãy chuyển ngay sang phương án lưu bộ nhớ đệm hoặc loại bỏ việc hiển thị tổng số trang ở những nơi không cần thiết.
  • Mở điện thoại cá nhân lên, vào đúng trang web đó và thử dùng ngón tay cái bấm chuyển trang xem các nút bấm có đủ độ rộng 44 pixel để thao tác thoải mái hay không.

Kỹ thuật lập trình xét cho cùng không phải là cuộc đua xem ai viết ra những cấu trúc mã phức tạp hơn. Người làm kỹ thuật giỏi là người biết chọn đúng giải pháp vừa vặn cho bài toán thực tế, giúp hệ thống vận hành êm ái, máy chủ tiết kiệm tài nguyên và mang lại trải nghiệm mượt mà nhất cho người dùng cuối.

Filed Under: Khám phá

Bình luận

Bài viết nổi bật

Kiểm Tra Tốc Độ Mạng Tại Nhà Đơn Giản Nhất

cách gỡ cài đặt Avast Free antivirus

Hướng dẫn gỡ hoàn toàn cài đặt Avast Free Antivirus trên máy tính

không cài được net framework 3.5 trên win 10

8 Cách sửa lỗi không cài được net framework 3.5 trên win 10

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Bài viết mới

  • Dịch vụ SEO Google Maps minh bạch dựa trên dữ liệu và quy trình thực tế
  • Phân trang PHP 2026: Kỹ thuật tối ưu cho website bán hàng và SEO
  • Giao diện bán hàng đẹp 2026: Tiêu chí đánh giá và tác động đến chuyển đổi
  • Cuộc sống
    • Những câu nói hay về cuộc sống
  • Thơ hay
  • Công Nghệ
  • Phim
  • Game
  • Tính phần trăm (%) online

Categories

Copyright © 2026 · Generate Pro on Genesis Framework · WordPress · Log in