Một codebase cho cả web, iOS và Android: tiêu chí lựa chọn
Native, hybrid và web khác nhau ở điểm nào
Khác biệt nằm ở chỗ ai là bên vẽ ra màn hình. Native được viết riêng bằng bộ công cụ của iOS và của Android. Web do trình duyệt vẽ. Hybrid xuất phát từ một bộ mã và nhắm tới cả hai nền tảng. Hầu hết khác biệt về thời gian, chi phí bảo trì và hiệu năng đều sinh ra từ cấu trúc này.
Với hướng native, đội phát triển viết một bộ mã cho iOS và một bộ mã cho Android. Cùng một màn hình đăng nhập được làm hai lần, cùng một lỗi được sửa hai lần, cùng một thay đổi yêu cầu được áp dụng hai lần. Đổi lại, sản phẩm dùng được ngay các tính năng mà hệ điều hành vừa công bố, và cách vận hành của giao diện ít khi lệch khỏi thói quen của nền tảng đó.
Web thì không có bước cài đặt. Người dùng mở đường dẫn là thấy bản mới nhất, còn đội phát triển phát hành mà không phải chờ duyệt trên cửa hàng ứng dụng. Nếu tính cả cách bố trí co giãn theo kích thước màn hình và cách gắn biểu tượng lên màn hình chính để mở như một ứng dụng, sẽ có nhiều dịch vụ chỉ cần web là đủ. Tuy nhiên thông báo đẩy, xử lý nền và một số quyền truy cập cảm biến còn phụ thuộc vào chính sách của trình duyệt và hệ điều hành, nên cần kiểm tra trước.
Trong thực tế, từ hybrid gộp chung ít nhất ba cách làm khác nhau. Cách thứ nhất là dựng màn hình bằng công nghệ web rồi cho chạy bên trong một lớp vỏ ứng dụng. Cách thứ hai là bộ mã dùng chung gọi tới đúng các thành phần giao diện thật của từng nền tảng. Cách thứ ba là framework tự vẽ toàn bộ màn hình bằng công cụ đồ họa của riêng nó. Ba hướng này khác nhau về hiệu năng, về tốc độ bắt kịp tính năng mới của hệ điều hành, và về cách xử lý thiết kế.
Vì vậy, chỉ nhìn tên framework ghi trong báo giá thì rất dễ quyết định sai. Tên tuổi lên xuống theo vài năm, và mỗi phiên bản lại có tính chất khác nhau. Những câu hỏi giữ được giá trị lâu hơn nằm ở chỗ khác. Ai vẽ màn hình trong cách làm này, khi hệ điều hành ra tính năng mới thì bao lâu nữa sản phẩm của chúng ta dùng được, và khi có sự cố thì phải tìm nguyên nhân ở tầng nào.
Khi nào hybrid phù hợp và khi nào không
Tiêu chí nằm ở tính chất của màn hình. Nếu phần lớn màn hình là danh sách, biểu mẫu, tìm kiếm và dữ liệu lấy từ máy chủ thì một bộ mã chung rất phù hợp. Ngược lại, nếu sản phẩm phải vẽ từng khung hình, đọc cảm biến liên tục hoặc dùng tính năng mới của hệ điều hành ngay ngày ra mắt thì nên làm riêng theo nền tảng.
Nhóm phù hợp có thể nói cụ thể hơn. Đó là các dịch vụ lấy việc đọc và ghi dữ liệu làm trọng tâm: đặt chỗ, đặt hàng, chấm công, tuyển dụng, quản lý hội viên, công cụ nội bộ của doanh nghiệp. Cũng thuộc nhóm này là sản phẩm còn đang dò phản ứng thị trường nên tính năng thay đổi liên tục, sản phẩm cần lên hai cửa hàng cùng thời điểm, và đội ngũ ít người nên một người phải phụ trách nhiều màn hình. Trong những điều kiện đó, chi phí kéo song song hai bộ mã lớn hơn phần lợi thu được.
Nhóm không phù hợp cũng khá rõ. Đó là khi chất lượng vẽ hình chính là bản chất sản phẩm: chỉnh sửa camera theo thời gian thực, biên tập video và âm thanh, đồ họa ba chiều và trò chơi. Xử lý nền như ghi vị trí theo từng giây hoặc duy trì kết nối lâu với thiết bị Bluetooth cũng khó. Những lĩnh vực có yêu cầu bảo mật được quy định chi tiết như tài chính hay y tế, và những tổ chức vốn đã có sẵn đội iOS và đội Android riêng, thường không có lý do phải gộp lại.
Vùng ở giữa mới là vùng rộng nhất. Bản đồ, thanh toán, thông báo đẩy, xác thực sinh trắc học và tải tệp thường đã có sẵn cách kết nối, nhưng chất lượng và tình trạng bảo trì thì mỗi thứ một khác. Tính năng càng bắt buộc thì càng phải kiểm chứng bằng bản chạy thật trước khi ký hợp đồng. Dựng một màn hình có gắn tính năng đó rồi chạy trên máy thật chỉ mất vài ngày, và vài ngày ấy đủ để đổi hướng cho nhiều tháng sau.
Cũng không nhất thiết phải xem đây là bài toán chọn một bỏ hai. Cách làm phổ biến là để phần lớn màn hình dùng mã chung và tách riêng một hai màn hình nặng thành mô đun theo nền tảng. Thứ tự mở web trước để đón người dùng rồi làm ứng dụng sau khi đã thấy nhu cầu rõ ràng cũng thường hiệu quả. Thay vì chốt tất cả ngay từ đầu, nên trì hoãn những quyết định khó đảo ngược lại càng lâu càng tốt.
Một bộ mã thật sự tiết kiệm được điều gì
Thứ tiết kiệm được không phải số dòng code mà là những phán đoán bị lặp lại. Hiệu quả đến từ chỗ không phải diễn giải cùng một yêu cầu hai lần, tái hiện cùng một lỗi hai lần hay nghiệm thu cùng một thay đổi hai lần. Quan niệm mã giảm một nửa thì thay đổi nhiều theo loại màn hình, nhưng phần chống lặp này gần như luôn còn lại.
Làm hai bộ không phải là gấp đôi công việc mà thường nhiều hơn gấp đôi một chút. Mỗi lần yêu cầu thay đổi, phải đối chiếu xem hai bản cài đặt có hiểu cùng một nghĩa hay không, và nếu hai bản chạy khác nhau thì lại thêm một cuộc họp để xác định bên nào đúng. Những khác biệt tưởng như nhỏ tích lại sẽ làm nội dung hỗ trợ khách hàng và bộ kịch bản kiểm thử tách đôi, đến mức về sau chính đội ngũ cũng lúng túng không biết nên giải thích theo nền tảng nào.
Đoạn phát huy tác dụng mạnh nhất không phải giai đoạn xây dựng ban đầu mà là giai đoạn sau đó. Một dịch vụ luôn có thời gian sửa chữa dài hơn thời gian tạo ra nó. Hệ điều hành lên phiên bản mỗi năm, chính sách thay đổi, số màn hình tăng dần. Trong quãng dài này, điều kiện chỉ phải trông coi một bộ mã giống như mỗi tháng được hoàn lại một ít tiền lãi.
Ngược lại, cũng cần biết rõ những khoản không hề được tiết kiệm. Việc duyệt trên cửa hàng vẫn phải làm riêng từng bên. Kiểm thử trên máy thật vẫn phải làm ở cả hai phía. Thói quen giao diện của hai nền tảng khác nhau nên phần xử lý thiết kế vẫn còn, còn máy chủ và cơ sở dữ liệu vốn đã dùng chung từ đầu nên không nằm trong phần tiết kiệm. Đa ngôn ngữ, khả năng tiếp cận, gửi thông báo và tự động hóa phát hành cũng vậy. Phần giảm được nhờ một bộ mã chỉ là một phần của toàn bộ tiến độ, không phải tất cả.
Yeowubie Interaction cũng lặp lại phán đoán này trên chính sản phẩm của mình. Dịch vụ chấm công onSpots có mặt trên cả iOS và Android, hỗ trợ tiếng Anh, tiếng Việt và tiếng Hàn. Trong điều kiện đó, chi phí lặp phát sinh ở đâu là chuyện rất rõ ràng. Sửa một câu chữ là phải kiểm tra trên ba ngôn ngữ và hai nền tảng, và số lần kiểm tra tăng lên theo phép nhân. Khi quyết định cấu trúc, vấn đề chúng tôi thật sự phải xử lý cũng là phép nhân này chứ không phải hiệu năng.
Cái giá phải trả về hiệu năng và tính năng thiết bị
Ở phần lớn ứng dụng nghiệp vụ, thứ quyết định cảm giác nhanh chậm không phải cách kết xuất mà là tốc độ phản hồi của máy chủ, kích thước ảnh và cách xử lý danh sách. Dù vậy vẫn có chỗ khác biệt lộ ra: thời gian từ lúc chạm đến lúc dùng được, độ mượt khi lướt danh sách dài, hiệu ứng chuyển màn hình và dung lượng tệp cài đặt.
Mỗi hướng trả một cái giá khác nhau. Cách chạy công nghệ web bên trong ứng dụng phát sinh chi phí trung chuyển mỗi khi qua lại với tính năng thiết bị như camera hay tệp, và khi lượng dữ liệu đi qua đoạn đó lớn thì biểu hiện thành hiện tượng khựng. Cách để framework tự vẽ màn hình thì ít chịu gánh nặng đó, nhưng có thể còn khác biệt nhỏ ở phông chữ mặc định của hệ điều hành, thao tác chọn văn bản và khả năng phối hợp với công cụ đọc màn hình. Không thể khẳng định bên nào tốt hơn, mà phải xem màn hình định làm nhạy cảm với gánh nặng nào.
Về tính năng thiết bị, vấn đề thực tế hay gặp là độ trễ hỗ trợ. Khi hệ điều hành ra tính năng mới, native dùng được ngay, còn trên bộ mã chung thì phải chờ đến khi có phần nối trung gian. Nhiều phần nối như vậy do cộng đồng duy trì, và nếu người duy trì buông tay thì đến một lúc nào đó việc cập nhật dừng lại. Khi ấy vẫn phải tự viết mã riêng cho từng nền tảng. Đây chính là lý do vì sao chọn một bộ mã chung thì trong đội vẫn cần một mức kiến thức nhất định về iOS và Android.
Còn một khoản chi định kỳ nữa cần đưa vào tính toán. Khi framework lên phiên bản lớn, các phần nối và thư viện phải dịch chuyển theo, và công việc đó chiếm chỗ trong lịch mà không tạo ra tính năng mới. Nếu không dự trù khoản này trong ngân sách, phiên bản sẽ tụt lại dần, mà càng tụt lại thì càng khó nâng lên.
Tốt nhất là không đóng đinh bằng con số. Hiệu năng của framework thay đổi theo phiên bản, theo thiết bị và theo cách dựng màn hình, nên bảng so sánh của hôm qua chưa chắc còn đúng hôm nay. Cách chúng tôi khuyến nghị đơn giản hơn: dựng trước một hai màn hình được dự đoán là nặng nhất rồi chạy thử trên đúng dòng máy mục tiêu. Nếu phần đông người dùng dùng máy phổ thông thì càng không nên kết luận chỉ dựa trên một chiếc máy cấu hình cao. Phép đo đó trả lời cho quyết định của bạn trực tiếp hơn bất kỳ tài liệu nào.
Danh sách câu hỏi cần kiểm tra trước khi quyết định
Đây là những câu hỏi đặt quyết định lên nền sự thật thay vì lên tài liệu. Sản phẩm làm việc gì, ai duy trì nó và trong bao lâu, người dùng đang cầm thiết bị nào. Khi ba trục này hội tụ, cách làm thường tự thu hẹp lại. Còn nếu câu trả lời phân tán, chính chỗ đó là chỗ cần dựng bản thử để kiểm chứng.
Về phía sản phẩm, hãy hỏi như sau. Đồ họa thời gian thực, xử lý camera và theo dõi vị trí liên tục chiếm bao nhiêu phần trong tổng số màn hình. Sản phẩm có phải hoạt động cả khi mất mạng không. Trong nhóm thông báo đẩy, thanh toán, bản đồ và xác thực sinh trắc học thì đâu là thứ bắt buộc, và thứ đó đã được kiểm chứng trên cách làm này chưa. Liệu bản đầu tiên có thể ra mắt chỉ bằng web mở qua đường dẫn mà chưa cần đăng ký cửa hàng không. Có quy định pháp lý hay yêu cầu bảo mật nào bắt buộc một cách triển khai cụ thể không.
Câu hỏi phía tổ chức thì thực tế hơn nữa. Đội hiện tại đang thành thạo công nghệ nào. Ở địa phương của chúng ta có tuyển được nhân sự đó một cách ổn định không. Trong hai năm sau khi ra mắt, ai là người giữ bộ mã này. Nếu thuê ngoài thì phạm vi bàn giao và quyền sở hữu mã nguồn được ghi thế nào trong hợp đồng. Việc nâng phiên bản framework do ai làm và làm vào lúc nào. Chọn công nghệ mà chưa trả lời được năm câu này thì kết cục là một ứng dụng làm tốt nhưng không có người trông coi.
Phía người dùng cũng cần kiểm tra. Đừng phỏng đoán thiết bị thật của người dùng, hãy xác nhận bằng dữ liệu. Nếu đã có dịch vụ web thì câu trả lời nằm trong nhật ký truy cập, còn nếu chưa có thì hỏi trực tiếp vài người dùng đầu tiên là đủ. Có cần hỗ trợ nhiều ngôn ngữ không, và về sau số ngôn ngữ có khả năng tăng lên không, cũng nên chốt ngay từ bây giờ. Ngôn ngữ và nền tảng là hai trục nhân với nhau, nên thêm vào muộn thì chi phí đội lên rất nhanh.
Cuối cùng, hãy chừa đường quay lại. Nếu tách riêng phần vẽ giao diện với phần xử lý dữ liệu thì sau này khi phải chuyển một màn hình sang mã riêng theo nền tảng, bạn không phải làm lại từ đầu. Yeowubie Interaction làm sản phẩm của mình song song với việc phát triển cho khách hàng ở cả Hàn Quốc và Việt Nam, và đã đi qua quyết định này nhiều lần. Điều xác nhận được sau mỗi lần đều giống nhau. Không có một cách làm đúng tuyệt đối, chỉ có cách làm hợp với sản phẩm này và đội ngũ này. Và câu trả lời ấy thường xuất hiện trên thiết bị thật trước khi xuất hiện trong phòng họp.