Nghiên cứu điển hình – HTML5 trong deviantART muro

Mike Dewey
Mike Dewey

Giới thiệu

Vào ngày 7 tháng 8 năm 2010, deviantART đã tổ chức lễ kỷ niệm 10 năm thành lập. Chúng tôi đã tổ chức sinh nhật bằng cách ra mắt một công cụ vẽ HTML5 có tên là deviantART muro. Bạn có thể sử dụng công cụ này dưới dạng một ứng dụng web độc lập cũng như một công cụ vẽ nhẹ để thêm hình ảnh vào bình luận trên diễn đàn.

Cộng đồng deviantART đã chào đón công cụ vẽ mới này với sự nhiệt tình lớn, và giờ đây, công cụ này có lưu lượng truy cập ngang bằng với một số tài sản web có quy mô khá lớn. Kể từ khi ra mắt, cứ 5 giây lại có một bức vẽ mới được gửi bằng deviantART muro. Đây chỉ là số lượng bản vẽ đã hoàn thành; còn rất nhiều bản vẽ khác đã bắt đầu nhưng chưa được lưu.

Bài viết sau đây cung cấp một số thông tin cơ bản về cách chúng tôi đang sử dụng HTML5, lý do chúng tôi chọn sử dụng các công nghệ mà chúng tôi đã sử dụng và những điều tôi khám phá được trong khi viết một trong những ứng dụng HTML5 đầy đủ đầu tiên cho một trang web lớn.

Lý lịch trích ngang của tôi

Vào cuối năm 2005, tôi là một trong những nhà phát triển chịu trách nhiệm về công cụ vẽ mà Draw Here sử dụng. Công cụ này là một công cụ "vẽ graffiti trên web" do một dấu trang khởi chạy. Lệnh này được dùng để vẽ hình ảnh trên mọi trang web. Ban đầu, Draw Here được tạo bằng SVG (Firefox 1.5 beta vừa ra mắt; đây là một trong những trình duyệt đầu tiên hỗ trợ SVG).

Trên Internet Explorer, chúng ta đang tạo SVG ở chế độ nền, nhưng đang kết xuất bản vẽ bằng VML. WebKit không hỗ trợ SVG tại thời điểm đó, vì vậy, tôi đã chuyển mã của chúng tôi để kết xuất SVG bằng canvas (đây là một công nghệ mới chỉ có trong WebKit tại thời điểm đó). Có lúc, tôi thậm chí còn tạo một cổng để mã SVG của chúng ta có thể hiển thị trên các trình duyệt cũ bằng cách sử dụng một loạt các phần tử div được dán lại với nhau. (Tất nhiên, đây chỉ là một trò đùa để cho thấy rằng bạn có thể làm được và sẽ rất chậm khi sử dụng).

Vào thời kỳ hoàng kim, Draw Here được dùng để tạo khoảng 100 bức vẽ mỗi ngày. Ứng dụng này đã đủ hoàn chỉnh để được gọi là một ứng dụng web chính thức, mặc dù chưa được hoàn thiện hoàn toàn. Vào giữa năm 2006, dự án này đã bị bỏ dở, mặc dù trang web vẫn còn hoạt động cho đến ngày nay – chủ yếu chỉ để cho vui.

Công nghệ mà deviantART muro sử dụng

Do có kinh nghiệm sử dụng nhiều công nghệ HTML5 trong thời gian đầu, nên tôi được mời làm nhà phát triển chính trên deviantART muro. Bất cứ ai đang đọc bài viết này đều có thể hiểu lý do chúng tôi quyết định sử dụng HTML5 thay vì công nghệ dựa trên trình bổ trợ như Silverlight hoặc Flash. Chúng tôi muốn một giải pháp mạnh mẽ và sử dụng các tiêu chuẩn mở.

Quyết định giữa Canvas và SVG

Chúng ta quyết định thực hiện lớp vẽ bằng canvas. Một số người có thể thắc mắc khi nào nên sử dụng canvas và khi nào nên sử dụng SVG. Có rất nhiều điểm trùng lặp trong những việc có thể làm được với hai công nghệ này – như Draw Here đã chứng minh, cả hai công nghệ đều có thể được dùng để tạo ứng dụng vẽ.

Tôi nhận thấy SVG rất phù hợp nếu bạn muốn giữ lại các tay cầm cho các đối tượng đã vẽ. Ví dụ: nếu bạn muốn người dùng có thể vẽ một đường thẳng, sau đó có thể kéo các đoạn của đường thẳng đó để thay đổi hình dạng, thì việc này sẽ khá đơn giản khi sử dụng SVG. Nhưng việc tương tự cũng rất khó xử khi sử dụng canvas.

Khi sử dụng canvas, bạn sẽ đưa nội dung lên canvas rồi quên mất. Một canvas trống và một canvas đã được vẽ trong một giờ hoạt động giống hệt nhau trong mã và có cùng mức sử dụng bộ nhớ. Mặc dù chương trình vẽ đường quét thường hoạt động rất tốt với công nghệ fire and forgets, nhưng nó cũng gây khó khăn cho một số việc. Ví dụ: việc tạo một hàm huỷ nhanh trong canvas khó hơn nhiều so với trong SVG. Trong SVG, bạn chỉ cần giữ một tay cầm cho vài dòng gần đây nhất mà bạn đã đặt, và việc huỷ chỉ là việc loại bỏ các đối tượng đó. Với canvas, sau khi vẽ một đường, bạn không biết đường đó nằm ở đâu, vì vậy, để xoá đường đó, bạn cần vẽ lại khu vực chứa đường đó.

Sau khi quyết định sử dụng HTML5 cho canvas, chúng tôi quyết định tận dụng một số tính năng khác của HTML5. Ví dụ về điều này là cách chúng ta sử dụng localStorage để theo dõi chế độ cài đặt bút vẽ của người dùng. Bằng cách này, sau khi thiết lập các bút vẽ theo cách họ muốn, người dùng có thể quay lại các chế độ cài đặt đó vào lần tiếp theo họ sử dụng công cụ của chúng tôi. localStorage có nghĩa là chúng ta không phải sử dụng hết cookie hoặc thực hiện bất kỳ lượt truy cập nào vào máy chủ để nhận các lựa chọn ưu tiên đó.

Sử dụng Canvas

Canvas đã phát triển rất nhiều trong 5 năm qua. Với Draw Here, chúng tôi thực sự không phát hành cổng canvas của tôi, vì hiệu suất không tốt. Tôi nghĩ rằng có thể nói rằng công cụ này hoạt động hiệu quả hơn bạn tưởng. Việc xoá một phần lớn canvas và vẽ lại các hình dạng phức tạp thường có thể diễn ra với tốc độ nhanh hơn khả năng nhận biết của con người. Điều duy nhất tôi thấy thỉnh thoảng quá chậm là sử dụng getImageData() để lấy mẫu pixel. Tốc độ của thao tác rõ ràng phụ thuộc vào kích thước canvas, nhưng trên một canvas lớn, việc thực hiện getImageData() vào sai thời điểm có thể mất đủ thời gian để người dùng cảm thấy ứng dụng phản hồi chậm.

Sau khi đọc nhiều hướng dẫn về canvas, ban đầu tôi có ấn tượng rằng đây là một công cụ nặng nên sử dụng một cách tiết kiệm, có thể một hoặc hai lần trên một trang. Tôi không biết mọi người có cảm nhận được điều này không, nhưng tôi thì có, vì vậy, tôi đã sử dụng tính năng này một cách tiết kiệm khi chúng tôi bắt đầu lập trình cho deviantART muro. Tuy nhiên, sau một thời gian, tôi nhận thấy có rất nhiều nơi mà canvas có thể giúp bạn tiết kiệm nhiều công sức. Ví dụ: bản minh hoạ cho ứng dụng của chúng ta chỉ định rằng phải có một công cụ chọn màu là hai tam giác chồng lên nhau cho thấy màu chính và màu phụ:

Công cụ chọn màu
Bộ chọn màu

Bản năng đầu tiên của tôi là bắt đầu nghĩ cách tạo ra tiện ích giao diện người dùng nhỏ này bằng HTML và CSS truyền thống. Những người giỏi hack CSS có thể chỉ ra cách thực hiện tất cả những việc này qua CSS, nhưng hình tam giác của hai phần thay đổi màu sắc khiến việc này không quá rõ ràng.

Khi nghĩ đến việc chỉ sử dụng một canvas, tôi đã tạo tiện ích này bằng một phần tử DOM duy nhất và một vài dòng JavaScript. deviantART muro sử dụng các nút canvas ở khắp mọi nơi. Mỗi lớp là một canvas và việc thay đổi thứ tự lớp chỉ là vấn đề chuyển đổi chỉ mục z. Bảng điều khiển "trình điều hướng" thu phóng hiển thị chế độ xem thu nhỏ của vùng vẽ chỉ là một canvas khác thỉnh thoảng gọi drawImage() bằng cách sử dụng canvas lớp làm hình ảnh nguồn. Ngay cả con trỏ khu vực vẽ (một vòng tròn hai tông màu điều chỉnh kích thước tuỳ thuộc vào kích thước bút vẽ và mức thu phóng) cũng là một canvas nổi bên dưới chuột.

Lý do chúng tôi sử dụng canvas linh hoạt hơn so với các công nghệ HTML5 khác là vì thư viện ExplorerCanvas của Google cho phép mô phỏng canvas trong Internet Explorer. Điều đó đưa tôi đến phần tiếp theo.

Internet Explorer (IE)

Lý do chính khiến nhiều trang web lớn chưa sử dụng HTML5 là vì họ không muốn mất người dùng Internet Explorer. Tôi chắc chắn rằng câu hỏi đầu tiên trong tâm trí của hầu hết các nhà phát triển khi họ nghe nói rằng deviantART đã tạo một ứng dụng vẽ bằng HTML5 là "Đã làm gì với IE?"

Ban đầu, chúng tôi quyết định sẽ nỗ lực hết sức để mọi thứ hoạt động trong Internet Explorer, nhưng chúng tôi đã thực hiện kiểu phát triển web ít phổ biến nhất. Vì cộng đồng web đã áp dụng phương pháp một trang web không thể khởi chạy cho đến khi trang web đó trông giống nhau trên mọi trình duyệt đã biết, nên người dùng không thể biết được thời điểm trình duyệt của họ bị thiếu. Đối với người dùng thông thường, các vấn đề về tốc độ được đổ lỗi cho kết nối Internet của họ và mọi trang đều hiển thị ít nhiều giống nhau. Vì vậy, họ quyết định chọn trình duyệt yêu thích dựa trên những chi tiết nhỏ tuỳ ý trong giao diện người dùng, chẳng hạn như màu của nút quay lại.

Chúng tôi quyết định sẽ tạo bất kỳ tính năng thú vị nào nảy ra trong đầu bằng cách sử dụng thông số kỹ thuật HTML5, cố gắng làm cho tính năng đó hoạt động trong Internet Explorer. Nếu không hoạt động được, chúng tôi sẽ chỉ bật lên một cửa sổ bật lên giải thích rằng tính năng này không hoạt động vì trình duyệt của họ chưa triển khai tiêu chuẩn web.

Ban đầu, chúng tôi đã cố gắng làm cho mọi thứ hoạt động với ExplorerCanvas (exCanvas) của Google. Nó có khả năng bắt chước canvas một cách đáng ngạc nhiên đối với hầu hết các trường hợp. Tuy nhiên, phương thức này cũng có một nhược điểm. Mỗi nét vẽ trên canvas là một đối tượng DOM trong bản dịch VML cơ bản. Đối với hầu hết những việc bạn có thể thử với canvas, điều này là ổn, nhưng một số bút vẽ của deviantART muro tạo hình dạng từ việc xếp nhiều nét vẽ lên nhau. Khi Internet Explorer gặp phải VML có hàng nghìn nút trong đó – ngay cả trên một máy tính nhanh – trình duyệt này sẽ gặp sự cố và ngừng hoạt động. Do đó, đối với nhiều lệnh gọi vẽ, chúng ta thực sự phải nhập và lập trình trong VML thực tế, đồng thời sử dụng các thủ thuật để nối các nút với nhau và sử dụng lệnh di chuyển để chỉ định vị trí có khoảng trống. Rất nhiều các nút điều khiển nhỏ và những thứ khác trong giao diện sử dụng thẻ canvas, vì những mục sử dụng nhỏ đó thường hoạt động tốt với exCanvas.

Ngoài việc làm cho một số tính năng hoạt động với exCanvas, chúng tôi đề xuất người dùng có thể tiếp tục sử dụng phiên bản Internet Explorer nếu họ đã cài đặt trình bổ trợ Google Chrome Frame. Google Chrome Frame là một trình bổ trợ nhúng công cụ kết xuất của Google Chrome vào Internet Explorer. Từ quan điểm của người dùng, họ vẫn đang sử dụng trình duyệt mà họ quen thuộc; nhưng ở bên trong, trang của chúng ta được hiển thị bằng các tính năng HTML5 của Chrome và JavaScript nhanh hơn.

Tôi biết rằng việc chuyển đổi các ứng dụng để hoạt động với Chrome Frame sẽ rất dễ dàng, nhưng tôi không nhận ra nó đơn giản đến mức nào. Bạn chỉ cần thêm một thẻ meta và… thế là xong, mọi thứ bắt đầu hoạt động trong IE.

Tóm tắt

Thật vui khi được làm việc với các công nghệ mới trong quy cách HTML5, và tôi có thể nói rằng mọi thứ tôi đã sử dụng đều sẵn sàng cho thời gian vàng. Ngay cả khi cần mọi thứ hoạt động hoàn hảo trên IE, bạn vẫn có thể làm được nhiều việc đáng ngạc nhiên khi kết hợp canvas và exCanvas. Và thật đáng ngạc nhiên là bạn cũng có thể viết một lớp dịch giữa SVG và VML. Khi bắt đầu sử dụng công nghệ này, bạn sẽ cảm thấy như bước vào một thế giới hoàn toàn mới.

Tài liệu tham khảo