· playwright / puppeteer / browser-automation

Playwright vs Puppeteer — Tự động hóa trình duyệt 2026

Playwright thắng cho E2E test suite mới. Puppeteer thắng cho script Chrome nhỏ gọn. Benchmark, chi phí migration và so sánh tính năng làm rõ sự khác biệt.

Bởi Ethan

1.936 từ · 10 phút đọc

Với E2E test suite mới, hãy chọn Playwright. Với các script Chrome ngắn, đơn mục đích, Puppeteer vẫn có chỗ đứng. Khoảng cách giữa hai thư viện này đã nới rộng đều đặn từ năm 2021, và con số download nói lên tất cả: Playwright đạt 53.5M lượt tải npm mỗi tuần, trong khi Puppeteer chỉ có 9.6M. Đây không phải một cuộc đua sít sao.

Bài này dành cho ai

Các engineer đang chọn thư viện tự động hóa trình duyệt cho dự án mới, hoặc đang duy trì một Puppeteer suite và tự hỏi liệu việc migration có đáng công không. Nếu bạn đang dùng Playwright và nó hoạt động tốt, không có gì trong bài này thay đổi quyết định của bạn.

Những gì chúng tôi đã kiểm thử

Playwright 1.60 so với Puppeteer 25.0.2, cả hai đều là phiên bản hiện tại tính đến tháng 5 năm 2026. Dữ liệu hiệu năng đến từ benchmark tự động hóa trình duyệt năm 2025 của Skyvern — thời gian thực thi wall-clock trên bốn loại kịch bản với phần cứng mà Skyvern không tiết lộ. Các quan sát về tính năng dựa trên tài liệu hiện tại và lịch sử commit GitHub của cả hai thư viện. Dữ liệu download từ npmtrends.com (trung bình tuần, tháng 5 năm 2026).

Kết quả

Nhận định nhanh

Playwright cho hầu hết các E2E testing; Puppeteer cho script Chrome nhỏ gọn. Playwright đi kèm sẵn test runner, trace viewer, hỗ trợ đa trình duyệt, và auto-waiting locator trong một gói duy nhất. Puppeteer gọn hơn, khởi động nhanh hơn, và cho phép truy cập Chrome DevTools Protocol trực tiếp hơn — những ưu điểm này chủ yếu có giá trị cho script, không phải test suite.

So sánh tính năng

Tính năngPlaywright 1.60Puppeteer 25.0.2
Hỗ trợ trình duyệtChromium, Firefox, WebKitChrome/Chromium (+ Firefox qua BiDi, thử nghiệm)
Hỗ trợ ngôn ngữJS, TypeScript, Python, Java, .NETJS, TypeScript
Test runner tích hợpCó — @playwright/testKhông — cần thêm Jest hoặc Mocha
Auto-waitingRetry dựa trên locator, web-first assertionsCơ bản; dễ bị lỗi do timing
Trace viewerTimeline đầy đủ, DOM snapshots, networkKhông có
Thực thi song songDựa trên worker, tích hợp sẵnPhụ thuộc vào external runner
Network interceptionpage.route() với conditional logicEvent-listener model
Đa trình duyệtHỗ trợ thực sựTrên thực tế chỉ hỗ trợ Chrome
Giả lập di độngChrome Android + Mobile Safari nativeChỉ scale viewport
TypeScriptMặc định khi khởi tạoHỗ trợ, nhưng không mặc định
Ghi HARFirst-class tracing API (v1.60)Không có
Accessibility snapshotsARIA snapshots với bounding boxKhông có
Screenshot/video khi failTích hợp sẵnThủ công qua page.screenshot()
Lượt tải npm mỗi tuần~53.5M~9.6M
GitHub stars~88.845~94.300

Số star của Puppeteer vẫn cao hơn — nó ra đời trước nhiều năm. Nhưng khoảng cách về lượt tải mới là tín hiệu quan trọng hơn: mức độ sử dụng phân kỳ rõ rệt sau khi lượt tải tuần của Playwright vượt Puppeteer vào năm 2023 và tiếp tục tăng tốc.

Playwright cũng là lựa chọn thay thế hàng đầu cho Cypress — nếu Cypress vẫn còn trong danh sách cân nhắc, Playwright vs Cypress 2026 chạy cùng một so sánh với các đặc thù về component testing và time-travel debugging.

Code: cùng một login test trên cả hai công cụ

Cùng kịch bản, cùng assertions. Đây là cách rõ nhất để thấy API của hai thư viện khác nhau ở đâu.

Puppeteer

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  await page.goto('https://example.com/login');

  await page.type('#email', '[email protected]');
  await page.type('#password', 'secret');
  await page.click('button[type="submit"]');

  await page.waitForNavigation({ waitUntil: 'networkidle2' });
  const url = page.url();
  console.assert(url.includes('/dashboard'));

  await browser.close();
})();

Playwright (@playwright/test)

import { test, expect } from '@playwright/test';

test('login redirects to dashboard', async ({ page }) => {
  await page.goto('https://example.com/login');

  await page.getByLabel('Email').fill('[email protected]');
  await page.getByLabel('Password').fill('secret');
  await page.getByRole('button', { name: 'Sign in' }).click();

  await expect(page).toHaveURL(/\/dashboard/);
});

Ba điểm khác biệt thực sự quan trọng:

  • Chiến lược selector: Selector #emailbutton[type="submit"] của Puppeteer sẽ hỏng khi DOM thay đổi. getByLabelgetByRole của Playwright gắn với accessibility tree — chúng sống sót qua các lần refactor markup mà không cần viết lại test.
  • Auto-waiting: expect(page).toHaveURL() retry cho đến khi assertion pass hoặc timeout. Không cần gọi thủ công waitForNavigation. Đây là sự khác biệt giữa một test dễ flaky sau 2 giây và một test xử lý được mạng 4G chậm mà không bị fail bất thường.
  • Cấu trúc: Đoạn code Puppeteer là một IIFE độc lập — một script. Đoạn Playwright là một test hoàn chỉnh với error reporting, isolation, và parallelism có sẵn.

Dữ liệu hiệu năng

Benchmark năm 2025 của Skyvern đo thời gian wall-clock cho bốn loại kịch bản (phần cứng không tiết lộ):

Kịch bảnPuppeteerPlaywrightNhanh hơn
Script ngắn đơn trang~3.2s~4.5sPuppeteer (~30%)
Luồng nhiều navigation4.784s4.513sPlaywright
Kịch bản E2E đầy đủ~8.2s~8.1sNgang nhau
Tác vụ scraping~6.7s~7.2sPuppeteer

Ưu thế tốc độ ~30% của Puppeteer cho script ngắn là có thật. Nhưng nó cũng hẹp: lợi thế này biến mất ngay khi network latency và thời gian tải trang chiếm phần lớn runtime. Trong một CI suite 50 test, tính năng parallelism tích hợp của Playwright — nhiều browser context dùng chung một browser process — thường cho tổng thời gian tốt hơn Puppeteer khi phối hợp với Jest workers.

Bảng trên cũng bỏ qua một chi phí ẩn: retry khi test flaky. Các test fail không ổn định do waitForTimeout trong Puppeteer thường chạy nhất quán trong Playwright vì auto-waiting được tích hợp vào mọi assertion. Overhead từ retry cộng dồn qua hàng trăm CI run; một test flaky retry hai lần mỗi run sẽ tích lũy rất đáng kể.

Chạy Playwright test suite trên trình duyệt thực trong cloud: Dùng thử BrowserStack miễn phí 30 ngày.

Chi phí migration: Puppeteer → Playwright

Hầu hết các pattern Puppeteer đều chuyển đổi trực tiếp. Đây là bản dịch API, không phải viết lại từ đầu:

PuppeteerPlaywright
require('puppeteer')import { chromium } from 'playwright'
browser.newPage()context.newPage() (context-first model)
page.type('#email', val)page.getByLabel('Email').fill(val)
page.waitForNavigation({ waitUntil: 'networkidle2' })await expect(page).toHaveURL(...)
page.waitForTimeout(2000)await expect(locator).toBeVisible()
page.on('request', handler)await page.route('**/api/*', handler)
page.screenshot()page.screenshot() (giống hệt)

Ước tính công sức từ kinh nghiệm cộng đồng:

  • Suite nhỏ (<50 test, được duy trì tích cực): 1–2 tuần. Lợi ích — debug với trace viewer và coverage đa trình duyệt — đến ngay sau khi chuyển đổi.
  • Suite lớn ổn định (500+ test đang xanh): Không cần vội. Puppeteer vẫn nhận cập nhật bảo mật. Migration có giá trị nếu coverage đa trình duyệt hoặc chẩn đoán test flaky là pain point thực sự; ngược lại, thời gian hoàn vốn sẽ rất dài.

Điểm khó nhất là chuyển đổi sang context model (hierarchy browser → context → page của Playwright so với API lấy page làm trung tâm của Puppeteer) và viết lại các selector. Selector tốn nhiều thời gian nhất nhưng cho ra kết quả bền vững nhất — selector getByLabelgetByRole khó bị phá vỡ hơn nhiều so với CSS selector. Node.js 20+ là yêu cầu cho Playwright 1.60; kiểm tra yêu cầu hệ thống trước khi bắt đầu.

Đang dùng Puppeteer và muốn có cloud infrastructure mà không cần đổi công cụ? Chạy Puppeteer test trên LambdaTest.

Với tầng unit testing chạy song song với E2E suite, Vitest vs Jest 2026 trình bày quyết định tương tự cho component test và unit test.

Khi nào nên chọn cái nào

Chọn Playwright khi

  • Xây dựng E2E test suite mới — đây là lựa chọn mặc định năm 2026
  • Cần coverage đa trình duyệt (Firefox, Safari qua WebKit)
  • Team làm việc với Python, Java, hoặc .NET bên cạnh JavaScript
  • Muốn debug theo trace trong CI — trace viewer tích hợp rút ngắn thời gian điều tra test flaky từ hàng giờ xuống vài phút
  • Cần parallel test isolation mà không phải cấu hình thêm external test runner
  • Test hành vi mobile viewport với Chrome Android thực hoặc Mobile Safari emulation

Chọn Puppeteer khi

  • Viết script Chrome đơn mục đích — chụp screenshot, xuất PDF, tự động hóa form, scraping
  • Script ngắn và mang tính tạm thời — ưu thế khởi động ~30% cộng dồn khi bạn chạy hàng nghìn job
  • Cần truy cập Chrome DevTools Protocol trực tiếp — tích hợp CDP của Puppeteer chi tiết hơn so với các abstraction của Playwright
  • Puppeteer test suite lớn, ổn định, đang xanh — chi phí migration vượt giá trị trừ khi coverage đa trình duyệt hoặc trace debugging là pain point thực sự
  • Đang chạy pipeline PDF hoặc screenshot khối lượng cao nơi overhead mỗi thao tác tăng theo số lượng

Playwright vs Puppeteer: kết luận

Dùng Playwright cho test suite. Dùng Puppeteer cho script.

Đội ngũ Puppeteer ban đầu rời Google năm 2019 để xây dựng Playwright tại Microsoft, mang theo những bài học từ những hạn chế của Puppeteer. Kết quả là một thư viện đi kèm những thứ mà Puppeteer yêu cầu bạn phải tự lắp ghép: test runner, parallel workers, trace viewer, và hỗ trợ đa trình duyệt trong một gói nhất quán. Khoảng cách download 5.6 lần là phán quyết của thị trường về sự khác biệt đó.

Puppeteer không bị khai tử — nó vẫn nhận cập nhật bảo mật, khởi động nhanh hơn cho script Chrome nhỏ gọn, và một suite 500 test ổn định đang xanh và không bị chặn không cần migration theo lịch. Với bất kỳ công việc mới nào bắt đầu vào năm 2026, Playwright là lựa chọn mặc định đúng đắn.

Lưu ý

Các con số hiệu năng đến từ benchmark năm 2025 của Skyvern; workload của bạn có thể khác tùy theo độ phức tạp của test, điều kiện mạng, và phần cứng. Số lượt tải là trung bình tuần trên npmtrends (tháng 5 năm 2026). Số GitHub star là snapshot tại một thời điểm.

BrowserStack và LambdaTest là đối tác affiliate. So sánh tính năng và benchmark trên dựa trên dữ liệu độc lập đã công bố; quan hệ affiliate không ảnh hưởng đến kết quả của công cụ nào trong bảng so sánh.

Tài liệu tham khảo

  1. Playwright docs — Introduction
  2. Playwright release notes — v1.60
  3. Puppeteer documentation — pptr.dev
  4. github.com/microsoft/playwright
  5. github.com/puppeteer/puppeteer
  6. npmtrends.com — playwright vs puppeteer
  7. Skyvern — Puppeteer vs Playwright Complete Performance Comparison (2025)
  8. BrowserStack — Playwright vs Puppeteer 2026
  9. Autonoma — Why Playwright Has Already Won (2026)
  10. Leapcell — From Puppeteer to Playwright: Migration Guide