Kế hoạch Frontend đột phá từ GitLab

1551

Kế hoạch frontend quy mô

Trong bài viết, chúng ta sẽ tìm hiểu kế hoạch của GitLab với Vue và webpack nhằm biến mình thành một trong những trang web nhanh và hiệu quả nhất, đặc biệt là với Frontend Developer.

Vậy GitLab dự định làm gì với Vue để đảm bảo họ sẽ ngày càng tốt hơn, nhanh hơn, và tuyệt vời hơn nữa?

Kế hoạch dưới đây tỏ ra vô cùng tham vọng và vẫn còn một số thiếu sót, nhưng GitLab tỏ ra rất tự tin về kết quả mà kế hoạch sẽ mang lại, với frontend phát triển và hiệu năng tốt hơn nữa.

Frontend mạnh mẽ hơn

Trong những ngày đầu tại GitLab, công nghệ chính (về cơ bản) là Rails với jQuerry. Nhìn chung, vẫn chưa có nhiều thay đổi lớn, với ngoại lệ là Vue. Về chi tiết, các linter mới dần xuất hiện, quản lý code tốt hơn, và nhiều điều hay ho khác.

1. Chỉ viết lại phần nào cần thiết

GitLab không có kế hoạch hoàn toàn viết lại frontend với Vue. Đó sẽ là một ý tưởng dở tệ, tất nhiên là không dở với tất cả mọi người, nhưng với startup lại không thể dở hơn. Lượng thời gian và tiền bạc đổ vào đó sẽ vô cùng kinh khủng. Code jQuerry hiện có cũng đã qua testing và đang chạy tốt. Không cần phải viết lại những chức năng đã chạy tốt nữa (nhưng nếu có lợi ích thật lớn thì sẽ cân nhắc lại).

Đồng thời, không phải phần nào cần viết mới cũng thực hiện toàn bộ với Vue. Bạn cũng không cần phải làm vậy. Nhưng, nói gì thì nói, một số đoạn Vue đơn giản sẽ được thêm vào để đạt hiệu quả tốt nhất. Như một số ví dụ dưới đây:

  1. Page issue (nơi hiển thị một issue đơn lẻ), chứa rất nhiều jQuery trên đó. GitLab hiển nhiên sẽ không viết lại hết vì code vẫn chạy tốt. Họ sẽ chỉ viết lại một số phần nhỏ bằng Vue khi một số tính năng trở nên “real-time” hơn. Hiện nay title và description sẽ là những phần đầu tiên được thay đổi theo hướng này.
  2. Phần Issue Boards, do Phil viết, cũng là một đối tượng lý tưởng cho Vue, với tính năng mới hoàn toàn và có rất nhiều bộ phận tương tác.
  3. Page issue hiên nay load tất cả comment cùng một lúc và thêm rất nhiều event listener vào page. Vì lí do về hiệu năng, page này sẽ được lợi rất lớn Vue. GitLab có thể biến phần comment thành ứng dụng Vue. Đồng thời, GitLab cũng sẽ tăng cường thêm phần UX bằng cách cho phép bạn thấy ngay comment đã được link mà không cần phải đợi chờ. Hơn nữa, còn nhiều cách khác để hiển thị lượng lớn comment, và GitLab đang cân nhắc những lựa chọn khả thi nhất.
  4. Page pineline được viết lại bằng Vue để chuẩn bị cho sự xuất hiện của bản cập nhật real time.
  5. Môi trường được viết bằng Vue.
  6. Nhiều phần sẽ được áp dụng Vue trong tương lai và một số phần đã dùng sẵn Vue rồi. Vì danh sách quá dài nên chúng tôi không tiện trình bày ở đây.

2. Thêm vào webpack

Rails đi kèm một hệ thống tuyệt vời giúp bạn gom thư viện Ruby và bundle chúng vào ứng dụng. bundle install sẽ cài đặt tất cả mọi thứ bạn cần từ Gemfile của bạn. Vậy tại sao Frontend phải nhét tất cả thư viện của mình vào thư mục vendor? GitLab không làm đủ tốt để có hệ thống giao nhận thư viện của riêng mình? Kể từ khi asset pipeline lần đầu xuất hiện, hệ sinh thái JavaScript đã trưởng thành hơn rất nhiều, giờ đây GitLab đã có npm install và nhiều công cụ bundle code cao cấp khác để khai thác.

Với sự kết hợp của webpack vào cấu trúc, GitLab sẽ được nhiều lợi ích bất ngờ.

  1. Các thư viện JavaScript hiện không được bundle trực tiếp với mã nguồn của GitLab hoặc đính kèm trong gem wrapper, như jquery-ui hay bootstrap-rails được đính kèm dưới dạng ruby gem, và GitLap hoàn toàn kiểm soát được gem maintainer để giúp thư viện JavaScript luôn được cập nhật.
  2. Khi code được chia sẻ chung giữa các file với nhau, GitLab có thể đảm bảo họ không load lodash hai lần. Nếu cả hai file đều load lodash, chúng ta chỉ nên load đoạn code cho lodash một lần duy nhất. Lodash không những sẽ không được đính kèm hai lần, nhưng với tree shaking chỉ những component của lodash mà GitLab sử dụng sẽ được đính kèm thay vì cả một thư viện.
  3. GitLab có thể thêm hot module replacement để đẩy nhanh quá trình phát triển với Vue. Đây sẽ là hỗ trợ rất lớn cho quá trình phát triển GitLab vì việc refresh page thông cũng đã mất kha khá thời gian rồi.
  4. GitLab hiện nay đã có thể quản lý dependences chính xác hơn. Thay đổi này sẽ rất hữu ích cho các frontender muốn đóng góp GitLab. Devs sẽ không cần phải tìm hiểu những lua rua Rails JavaScript. GitLab cũng có thể lựa chọn bằng tay họ sẽ sử dụng đóng góp nào.
  5. SVGs sẽ thành công rất lớn.
    1. webpack bundle SVGs trực tiếp vào Javascript.
    2. Ngay lúc này, SVGs đã có mặt trong một thư mục cụ thể trong Rails. GitLab sử dụng Rails helper để pull in SVGs. Với webpack chúng ta có thể pull in từng SVGs một vì webpack sẽ compile trước assest.
    3. GitLab không phải fetch SVGs với một HTTP request.
    4. GitLab không phải thực hiện mấy cái của nợ HTML hidden element rắc rối.
    5. GitLab Không phải lo lắng về SVGs trong CSS. Bạn không thể thay đổi màu của SVGs trong CSS.
  6. GitLab sử dụng rất nhiều Ruby để xử lý các vấn đề Javascript và CSS. Giờ đây, họ còn có thể nhanh chóng giải quyết những vấn đề này với frontend tool của riêng mình.
  7. Với CommonsChunkPlugin của webpack, GitLab chia tất cả thư viện common vendor thành từ file riêng biệt. Vì những file này rất ít khi thay đổi, chúng có thể được cache trong hệ thống lâu hơn.
  8. Với tính năng code splitting của webpack bạn có thể load đúng JS bạn cần để boot. Sau đó, bạn sẽ chạy require.ensure() hoặc System.import(). Với cách làm này, chúng ta có thể yêu cầu webpack chỉ request đúng JS bạn cần và giữ kích thước file thật bé. Ví dụ, nếu chúng ta có modal.js cho modal. Nếu ai đó chưa từng dùng qua modals, code sẽ không load. Ngay khi “ai đó” mở một modal, JS được load theo yêu cầu.
  9. GitLab giờ đã có thể quản lý global scope hiệu quả, với import x from y thay vì phải bắt scripts pollute cả global scope và chuyền một mớ class qua lại window.gl.lol.
  10. GitLab giờ đây có thể giảm nhẹ Vue bundle. Đây là kết quả từ việc precompile template và omit template compiler từ production code.

3. Loại bỏ Turbolinks

GitLab từng sử dụng TurboLinks, và vừa xóa bỏ nó đi với linked merge request, merge vào lúc 2017/02/03.

Turbolinks cho ta những gì?

Với TurboLinks, click vào link sẽ không chuyển bạn đến một trang mới trong trình duyệt mặc định theo hướng được (GET) request. Thay vào đó, Turbolink sẽ thay thế tag body của ứng dụng với nội dung mới. Tất cả Javascripts của bạn sẽ được tải cùng một lúc, khi sử dụng asset pipeline. Thao tác này thường chỉ load một số HTML và Javascripts nhỏ. Trên GitLab, tất cả các trang sẽ tải trung bình 20kb cho mỗi lần page load, so với tổng hơn 800kb dung lượng file Javascripts đầy đủ. Turbolinks là một giải pháp hay cho rất nhiều project. Khi bạn bắt đầu sử dụng Javascript phức tạp hơn, tình hình sẽ trở nên vô cùng rắc rối nếu với Turbolinks. Gitlab đã thực hiện những thử nghiệm về tốc độ page, khi có Turbolinks và khi không có Turbolinks. Những thử nghiệm này đã chỉ ra rằng page không sử dụng Turbolinks sẽ có hiệu suất tốt hơn. GitLab cũng phát hiện ra rằng Turbolinks làm việc tốt hơn khi không phải quản lý quá nhiều event listener. Hơn nữa, với webpack giúp chia Javascript giữa các page, GitLab sẽ có thể tăng tốc page nhanh hơn trong tương lai. Đặc biệt, GitLab giờ đây đã có thể loại bỏ bớt rất nhiều code đảm nhiệm việc xử lý tất cả vấn đề của Turbolink trước đó.

Tham gia ngay để biết thêm về cuộc chiến

Vấn đề GitLab cần giải quyết

Khi JS được load một lần cho nhiều page, event trở thành vấn đề khá nan giải. Nếu bạn đang sử dụng gem 'jquery-turbolinks' như GitLab đang dùng, thì hàm $ ready sẽ fire với mỗi lần page load mặc dù page, theo định nghĩa truyền thống, không hề load. Việc viết Javascript riêng cho từng page mà không kẹp vào cả ứng dụng là một cơn ác mộng. GitLab vẫn làm vậy và chạy ổn, nhưng mà, sao hay vậy? Thật ra chả có lý do nào để GitLab kẹp một mớ JS trên mỗi page cả.

Bất kỳ external link nào cũng sẽ load nhanh hơn, như vậy GitLab phải thật chú ý vào hiệu năng.

Nếu bạn không cẩn thận, event của bạn sẽ được load nhiều lần và như vậy sẽ fire nhiều lần. Ví dụ như trong đoạn code sau:

Click event trên sẽ được load trên mỗi page, và vì vậy sẽ fire nhiều lần mỗi khi click .some-element.

Giải pháp

Có một số giải pháp để khác phục vấn đề này, hay dở đều có.

  1. Đừng tạo event trong các callback $ ready.
  2. Đi theo giải pháp “bốc mùi” sau:

Đây còn gọi là phương pháp die live. Code jQuery cũ rích mà người ta hay dùng để viết die().live() khắp mọi nơi.

  1. Viết thêm một event manager để đại diện cho tất cả events được thêm vào.
  2. Bỏ Turbolinks đi và đảm bảo bạn chỉ load code nào cần thiết trên mỗi page.

GitLab đang nhắm vào giải phấp số 4 vì nhiều lý do.

The Bonus

Sau khi bỏ đi Turbolinks, GitLab sẽ có thể làm được rất nhiều thứ hay ho. GibLab có thể làm mỗi page tự live được. Sau đó, một số page cụ thể có thể trở thành ứng dụng Vue của riêng mình, ví dụ như, file browser hay merge request page chẳng hạn. Đoạn code cho file viewer sẽ không phải được load trên mỗi page mỗi, và những page khác cũng tương tự. Đây không phải là cái gì mới mẻ cả, mà chỉ là lập trình web cơ bản mà thôi.

Conclusion

Có nhiều lời bàn tán rằng GitLab nên biến mình thành ứng dụng một trang, nhưng có vẻ như khả năng maintain khó khăn cùng hiệu năng kém là trở ngại quá lớn cho yêu cầu này.

Như vậy, đây chính là một bước đi nhỏ cho GitLab, và bước nhảy lớn cho frontend team. Trong tương lại, hy vọng GitLab sẽ tiếp tục phát triển với nhiều tính năng và lợi ích hơn nữa cho cộng đồng developer trên toàn thế giới.

Techtalk via GitLab

CHIA SẺ