ClipCrafter: Cách chúng tôi loại bỏ rendering phía máy chủ để chuyển sang client-side hoàn toàn với framewebworker

05 tháng 4, 2026·6 phút đọc

ClipCrafter đã tiến hành một cuộc cách mạng hóa kiến trúc ứng dụng bằng cách loại bỏ quy trình render video tốn kém phía máy chủ, thay vào đó tận dụng sức mạnh của trình duyệt thông qua thư viện framewebworker. Việc chuyển đổi này giúp giảm kích thước Docker image tới 200MB, đơn giản hóa cơ sở hạ tầng và mang lại trải nghiệm người dùng mượt mà hơn với tiến độ cập nhật theo thời gian thực.

ClipCrafter: Cách chúng tôi loại bỏ rendering phía máy chủ để chuyển sang client-side hoàn toàn với framewebworker

ClipCrafter: Cách chúng tôi loại bỏ rendering phía máy chủ để chuyển sang client-side hoàn toàn với framewebworker

Nếu bạn từng xây dựng một ứng dụng chỉnh sửa video, bạn sẽ thấu hiểu nỗi đau này: người dùng tạo các đoạn clip, nhấn "render" (kết xuất), và sau đó... là chờ đợi. Video sẽ được tải lên máy chủ, xử lý bằng ffmpeg hoặc Remotion, và cuối cùng mới trả về. Quá trình này chậm chạp, tốn kém và mang lại trải nghiệm người dùng kém.

Tại ClipCrafter, chúng tôi đã sống chung với kiến trúc này trong nhiều tháng. Quy trình rendering của chúng tôi bao gồm các hàm nền (background functions) của Inngest, sáu tuyến API (route) chuyên dụng, một Docker image khổng lồ chứa các phụ thuộc của Chromium và Remotion, cùng một lớp runtime Deno. Mỗi lần render là một vòng lặp lên xuống máy chủ, và chi phí hạ tầng ngày càng tăng.

Tuần trước, chúng tôi đã loại bỏ tất cả.

Sự xuất hiện của framewebworker

Điểm mấu chốt rất đơn giản: trình duyệt hiện đại đủ mạnh để xử lý việc render video trực tiếp. Chúng tôi đã thay thế toàn bộ stack rendering phía máy chủ bằng framewebworker, một thư viện nhẹ xử lý các khung hình video trong Web Worker.

Việc chuyển đổi này chạm đến hầu hết mọi lớp của ứng dụng. Dưới đây là những gì đã thay đổi trong Pull Request lớn nhất của quý này (#214):

Những gì chúng tôi đã loại bỏ

  • Tất cả các hàm render nền của Inngest
  • Sáu tuyến API dành cho việc điều phối render
  • Các gói bundler và renderer của Remotion
  • Chromium và các phụ thuộc cấp hệ thống từ Docker image
  • Runtime Deno khỏi worker container
  • Các cột dữ liệu liên quan đến render thông qua một lần di chuyển (migration) dữ liệu mới

Điểm cuối cùng đáng được nhấn mạnh. Chúng tôi không chỉ đổi thư viện — chúng tôi đã loại bỏ toàn bộ một danh mục trạng thái máy chủ. Không còn cần theo dõi các công việc render, thăm dò (polling) trạng thái hoàn thành hay xử lý các lỗi render phía backend nữa.

Những gì chúng tôi đã thêm

Thay thế cho tất cả những thứ trên là một React hook duy nhất: useClientStitch. Nó gọi API của framewebworker trực tiếp trong trình duyệt, truyền các đoạn video cùng với chú thích (caption overlay) và dữ liệu thời lượng. Việc render diễn ra trong một Web Worker, do đó luồng chính (main thread) vẫn phản hồi nhanh nhạy.

// Trước đây: điều phối máy chủ phức tạp
const response = await fetch('/api/render', {
  method: 'POST',
  body: JSON.stringify({ clipIds, options })
});
// Sau đó phải thăm dò trạng thái hoàn thành...

// Sau khi thay đổi: render trực tiếp phía client
const { render } = useClipRender();
await render(segments, {
  onProgress: (progress) => updateUI(progress)
});

Sự khác biệt về trải nghiệm của nhà phát triển thực sự là ngày và đêm.

Tiếp theo: Giao diện tiến độ chi tiết

Khi việc render được chuyển sang client-side, chúng tôi có thể làm điều gì đó trước đây gần như không thể: hiển thị tiến độ chi tiết, thực tế. Trong mô hình máy chủ, điều tốt nhất chúng tôi có thể cung cấp là "đang xử lý..." với có thể là một phần trăm cập nhật mỗi vài giây.

Với framewebworker chạy cục bộ, chúng tôi đã xây dựng RenderStatusPanel (PR #216) hiển thị tiến độ của từng đoạn clip với các biểu tượng quay và dấu kiểm, thanh tiến độ tổng thể với ước tính thời gian hoàn thành (ETA) được tính toán dựa trên thời gian đã trôi qua, và dữ liệu RichProgress thực tế với các chỉ số từng clip.

Chúng tôi đã chuyển từ một vòng xoay tải mơ hồ thành một phân tích chi tiết chính xác về những gì đang xảy ra và khi nào nó sẽ kết thúc.

Tinh chỉnh API

Việc chuyển đổi không chỉ diễn ra trong một PR. Sau khi hoán đổi ban đầu, chúng tôi đã cải thiện sự tích hợp qua một số thay đổi tiếp theo.

PR #217 đã nâng cấp framewebworker lên v0.1.1 và kết nối các kiểu RichProgress thực tế, loại bỏ mô phỏng tiến trình cục bộ của chúng tôi. Sau đó, PR #218 đã chuyển từ API stitch() sang một hàm render() mới tải một video duy nhất một lần thay vì tải lại cho mỗi đoạn. Điều này giới thiệu buildVideoSegments() để ánh xạ các clip sang các đoạn framewebworker với chú thích và thời gian.

Kết quả

Kích thước Docker Image

Việc loại bỏ Chromium, Remotion và Deno đã "cắt gọn" khoảng 200 MB khỏi Docker image của worker (PR #215). Triển khai nhanh hơn, chi phí lưu trữ thấp hơn.

Hạ tầng

Sáu tuyến API và toàn bộ hạ tầng công việc nền: đã biến mất. Máy chủ của chúng tôi đơn giản hơn, rẻ hơn để vận hành và ít chế độ thất bại hơn.

Trải nghiệm người dùng

Quá trình render bắt đầu ngay lập tức — không cần tải lên, không cần xếp hàng, không cần thăm dò trạng thái. Người dùng nhìn thấy chính xác những gì đang diễn ra với trạng thái từng clip và ETA thực.

Bài học kinh nghiệm cho dự án của bạn

Nếu bạn đang xây dựng một ứng dụng xử lý phương tiện, hãy xem xét liệu trình duyệt có thể làm được nhiều hơn bạn nghĩ hay không. Web Workers và các API hiện đại như OffscreenCanvas và WebCodecs đang thu hẹp khoảng cách với việc xử lý phía máy chủ cho nhiều trường hợp sử dụng.

Những câu hỏi then chốt cần đặt ra: Mọi người dùng có cần render không, hay chỉ một số ít? (Nếu phần lớn người dùng đều render, client-side sẽ tiết kiệm khổng lồ chi phí máy chủ). Việc render của bạn bị ràng buộc bởi CPU hay GPU? (Trình duyệt có quyền truy cập GPU). Bạn có chấp nhận thời gian render hơi dài hơn để đổi lấy hạ tầng bằng không không?

Đối với ClipCrafter, câu trả lời cho cả ba câu hỏi trên đã làm cho việc render phía client trở thành một lựa chọn chiến thắng rõ ràng.

ClipCrafter là một công cụ cắt video mã nguồn mở. Hãy kiểm tra kho lưu trữ tại github.com/clipcrafterapp/clipcrafter-app và dành cho nó một ngôi sao nếu bạn quan tâm đến loại kỹ thuật này.

Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗