Nhật ký làm Notas - Vấn đề với bộ nhớ

Nhật ký làm Notas - Vấn đề với bộ nhớ

Threads
  • Tin vui đầu ngày. Github vừa công bố rộng rãi GitHub Models đến tất cả mọi người. Nếu còn nhớ cách đây hơn 2 tháng trước, Github có chương trình đăng ký dùng thử các models của LLMs, và trường hợp của mình thì phải một tháng sau mới được duyệt cho dùng. Thì giờ đây họ đã cho mọi người dùng Github có quyền truy cập vào rồi, không cần phải đăng ký gì nữa 🥳

    GitHub Models đang là phao cứu sinh cho mình trong khi xây dựng trang blog này 😆

    GitHub Models is now available in public preview | Github Blog

    » Xem thêm
  • Hôm trước mình thấy repository này dùng TauriSvelte để viết lại ứng dụng kiểu như là Task Manager trên Window hay Monitor trên Mac á. Tò mò tải về xem thử thì bất ngờ thứ nhất là dung lượng rất nhỏ, chỉ vài MB. Tiếp theo là tốc độ khởi động cũng rất nhanh mà ứng dụng cũng rất mượt nữa chứ 🫣

    Abdenasser/neohtop

    » Xem thêm
  • Tuôi" để ý là cứ đợt nào ham đọc cái là lại lười viết, tuần nay tuôi đang đọc một lúc 3 cuốn, à phải là đọc 2 và nghe 1.

    Cuốn sách ám ảnh nhất đến thời điểm hiện tại: Đại dương đen - thuật lại 12 câu chuyện của 12 người mắc bệnh trầm cảm. Thần kinh vững, nhưng mới đọc 2 câu truyện đầu thôi mà cảm giác ngộp thở, bứt rứt thật khó tả 😰

    Câu chuyện tiếp theo đó thì mang lại cảm giác dễ thở hơn vì họ kiểm soát được bản thân. Nhưng sang tiếp câu chuyện thứ 4, thứ 5 thì lại như một có một bàn tay siết họng mình lại. Không thể nhắm mắt mà nghe được á, có gì đó rất đáng sợ.

    Một câu mà mình cảm thấy ám ảnh nhất là khi ba mẹ của người mắc trầm cảm luôn miệng hỏi tại sao con lại như thế mỗi khi sắp lên cơn và gào thét. Họ chỉ đành bất lực trả lời là "Làm sao mà con biết! Cũng giống như hỏi một người bị ốm là tại sao lại ốm? Làm sao mà biết được chứ! Có ai muốn đâu!".

    » Xem thêm

Vấn đề

Xin chào các độc giả của 2coffee.dev, một tuần nữa lại qua, thứ 7 vừa rồi Hà Nội bỗng có cơn mưa dông thật lớn, ngoài đường thì đổ cây, trong nhà thì tốc mái trước cơn thịnh nộ của thiên nhiên... nhưng tôi thì lại khá yên bình khi đang ở vùng quê Nam Định.

Cũng vì thế, tôi có ít thời gian làm Notas hơn. Nhưng không hẳn là không có gì để kể. Thậm chí câu chuyện còn thú vị hơn cả, có khi chỉ xếp sau cái tuần mà tôi hoàn thành chức năng đồng bộ bằng Adapter.

Như thường lệ, bây giờ là thời gian để kể chuyện.

Giao diện cho thiết bị di động

Giao diện dành cho thiết bị di động đã được xây dựng. Tuy chưa được chỉn chu cho lắm nhưng các tác vụ cơ bản trên màn hình nhỏ đã có thể dùng được. Nếu bạn đã nghe đến chuẩn làm ứng dụng "Mobile First" - nghĩa là ưu tiên làm giao diện cho các thiết bị di động (Mobile) thì tôi lại đang đi... ngược lại.

Thật ra Notas ban đầu được thiết kế để sử dụng trên màn hình lớn (PC) là chính, vì muốn nó hoạt động trơn chu trên PC trước rồi sau đó mới làm cho màn hình bé. Thời gian ngồi trước máy tính nhiều hơn trên điện thoại, tần suất cũng sử dụng cũng nhiều hơn cho nên việc ưu tiên không có gì là lạ.

Nhìn chung việc chuyển giao diện từ PC sang Mobile cũng không có gì khó khăn cho lắm. Đặc biệt khi Tailwind hỗ trợ responsive thông qua class rất tốt, tất cả những gì cần làm chỉ là thêm tiền tố màn hình trước, sau đó đến thuộc tính CSS, thế là xong.

<div class="hidden lg:block">
...  
</div>

Như ví dụ trên, ở màn hình bé thì thẻ div sẽ bị ẩn, còn khi trên màn hình to, nó sẽ hiện ra. Thật đơn giản phải không!

Là một trong số người quan tâm về trải nghiệm người dùng, tính năng nhiều chưa hẳn là một điều tốt, tính năng phải làm sao đó dễ sử dụng, thuận tiện trong việc thao tác mới là ưu tiên hàng đầu. Ban đầu tôi đã thử giữ nguyên các UI/UX từ phiên bản PC xuống Mobile nhưng rồi nhận ra nó không hề thân thiện chút nào. Tốt hơn hết là nên sửa lại sao cho phù hợp với người dùng di động.

Giao diện Notas trên Desktop-Mobile

Ví dụ, ở PC, menu của thư mục và ghi chú được kích hoạt bằng cách chuột phải hoặc bấm vào dấu 3 chấm (...) thì trên Mobile, điều đó là không phù hợp, màn hình quá bé để hiển thị, chưa kể đến trải nghiệm "ngang ngược". Vì thế, tôi thiết kế lại menu bằng một modal hiển thị chuyên nghiệp hơn.

Điều đó tiêu tốn tương đối thời gian, vì cơ bản tôi không phải là một lập trình viên Front-end chuyên nghiệp. Phải thú thật rất nể phục những bạn làm giao diện. Không biết các bạn đã dành bao nhiêu thời gian để trau chuốt từng pixel một.

Giao diện Notas trên Mobile

Vấn đề với bộ nhớ

Nhập/Xuất dữ liệu là một tính năng hết sức cơ bản mà ứng dụng ghi chú nào cũng nên có. Nhiều lúc chúng ta muốn sao lưu lại ghi chú cho an toàn hay phục vụ một một đích cá nhân nào đó, cho nên tôi đã bổ sung thêm tính năng này vào Notas.

Nhân tiện, khi nhập/xuất xong rồi thì một ý tưởng khác chợt lóe lên: Tại sao mình không thử kiểm tra luôn hiệu năng của Notas? Bằng cách nhập vào một số lượng lớn ghi chú xem sao!

Sau khi viết một đoạn mã bằng JavaScript tạo ra một tệp JSON chứa hàng trăm ghi chú có độ dài ngẫu nhiên từ 1000 đến 2000 từ, Notas nhập vào ngay lập tức và không có gì đáng để nói. Sau khi tăng lên vài nghìn, một lỗi bỗng xuất hiện. Cụ thể là Local Storage báo... hết bộ nhớ.

Cho những ai chưa biết thì trước đó tôi sử dụng Local Storage để lưu trữ dữ liệu người dùng, rồi sau đó thông qua Adapter để đồng bộ dữ liệu lên máy chủ trực tuyến. Tuy nhiên thì Local Storage có hạn mức bộ nhớ khá thấp, chỉ vào khoảng vài MB. Nếu lưu trữ nhiều hơn thì sẽ gặp lỗi như trên.

Nhận biết được điều đó từ sớm, tôi có nghiên cứu và biết được IndexedDB là một giải pháp khác nhằm thay thế cho Local Storage. IndexedDB có dung lượng bộ nhớ lớn hơn rất nhiều (có thể lên tới 80% dung lượng ổ cứng) tùy thuộc vào trình duyệt. IndexedDB cũng được nhiều trình duyệt hiện đại ngày nay hỗ trợ. Nó cũng là một dạng cơ sở dữ liệu key-value tương tự như Local Storage.

Thư viện localForage cung cấp API tương tự như Local Storage để chuyển đổi từ Local Storage sang IndexedDB một cách nhanh chóng. Vì cú pháp đọc/ghi dữ liệu rất giống nhau cho nên không mất quá nhiều thời gian để chuyển đổi. Tất cả việc cần làm là thay thế các hàm gọi localStorage thành localForage là xong.

Thừa thắng xông lên, lần này tôi quyết định nâng lên con số 10 nghìn ghi chú. Và... bùm! Chỉ có vài nghìn ghi chú được xuất hiện trong Notas. Quái lạ, thế con số còn lại đi đâu? Chẳng lẽ có lỗi gì rồi sao?

Sau một hồi loay hoay thì hóa ra, số ghi chú còn lại không mất đi, mà chỉ là nó chưa kịp nhập vào. Hay nói cách khác, Notas vẫn đang trong quá trình nhập các ghi chú vào IndexedDB. Và nếu tôi nhớ không nhầm, phải hơn 30 phút sau, 10 nghìn ghi chú mới được nhập đầy đủ vào Notas. Wow! Tại sao lại chậm như thế?

Hóa ra câu trả lời nằm ở IndexedDB. Sau một vòng quanh các diễn đàn, rất nhiều câu chuyện đàm tiếu xoay quanh IndexedDB. Rằng tại sao nó lại chậm? Tại sao trình duyệt không có lấy nổi một cơ sở dữ liệu ra hồn? Chí ít là một cơ sở dữ liệu dạng SQL đã quá đỗi quen thuộc? (Thật ra là có đấy, WebSQL là một cơ sở dữ liệu dành cho trình duyệt, nhưng nó không được chuẩn hóa nên nhiều trình duyệt không mặn mà, thậm chí còn bị gỡ khỏi trình duyệt).

Đến đây thì phải quay lại quá khứ một tí, về trước thời điểm đặt những dòng mã đầu tiên của Notas: Tôi đã suy nghĩ về việc lựa chọn cơ sở dữ liệu. Đối với nhiều lập trình viên, SQL là ngôn ngữ truy vấn dữ liệu quá đỗi quen thuộc, nên nếu trình duyệt hoặc thư viện nào đó hỗ trợ SQL thì không còn gì để nói.

SQL.js là một trong số hiếm hoi làm được điều này. Nó được chuyển đối từ SQLite native sang dạng WebAssembly để chạy trong trình duyệt. Chỉ bằng vài đoạn mã đơn giản, giờ đây bạn đã có thể sử dụng SQLite ngay bên trong trình duyệt. Nếu thế thì chẳng phải mọi chuyện được giải quyết rồi sao?

Đáng tiếc là không! SQL.js chỉ được hỗ trợ một phần trong trình duyệt. Nó không thể đọc/ghi trực tiếp vào một tệp tin sqlite vì quyền hạn của trình duyệt không cho phép. Vì thế mọi dữ liệu sẽ bị xóa khi bạn đóng phiên hoặc làm mới trang web. Haiz! Đành phải quay về với LocalStorage, à... IndexedDB chứ.

Không đầu hàng. Tôi tiếp tục tìm kiếm giải pháp lưu trữ dữ liệu trên trình duyệt. Một cái tên khác xuất hiện: RxDB.

RxDB được giới thiệu là "The local Database for JavaScript Applications". Đúng vậy, nó cung cấp giải pháp lưu trữ dữ liệu trong trình duyệt. Và thật ngạc nhiên khi một vài tư tưởng thiết kế Notas của tôi lại khá giống với RxDB.

RxDB cũng sử dụng một lớp Interface để tương tác với cơ sở dữ liệu thật sự đằng sau nó, gọi là RxStorage. RxDB đóng vai trò là một lớp trung gian để lưu trữ dữ liệu xuống trình duyệt. Lấy ví dụ, khi bạn khai báo các model của cơ sở dữ liệu như bình thường, gọi các hàm thêm/sửa/xóa dữ liệu của RxDB như bình thường. Sau đó RxDB sẽ có các RxStorage để thay đổi dữ liệu xuống Local Storage, IndexedDB, WebSQL, hay thậm chí là trong bộ nhớ RAM của máy tính.

Ngoài ra nó cũng cung cấp giải pháp đồng bộ dữ liệu ngoại tuyến/trực tuyến, hay còn gọi là Offline Support. Tài liệu có mô tả hết sức rõ ràng cách đồng bộ dựa vào các hàm pull/push giống với ý tưởng mà Notas đã triển khai. Chỉ có điều họ làm chi tiết và phức tạp hơn để đáp ứng được phần đa nhu cầu sử dụng.

Nhưng, rất nhiều RxStorage cần phải trả tiền mới có thể sử dụng. Đơn cử như nếu muốn dùng IndexedDB, bạn vẫn cần phải trả tiền!!! Số tiền bỏ ra cũng không phải là nhỏ. Miễn phí ư? Cũng có chứ! Nhưng tính ứng dụng không cao cho lắm. Xem ra mình cũng học được một ít ở trên này rồi lại đi ra.

Nhưng mọi chuyện chưa hẳn là kết thúc. Khi cánh cửa này đóng lại thì cánh cửa khác sẽ mở ra. Cụ thể một bài viết A future for SQL on the web từ năm 2021 của một lập trình viên. Anh ta đã quá chán nản với IndexedDB và tự tạo ra một thư viện hỗ trợ SQL ngay trong trình duyệt.

Bằng việc kết hợp SQL.js và IndexedDB. James Long đã tận dụng IndexedDB thành "ổ cứng" để làm nơi lưu trữ dữ liệu cho thư viện SQL.js - vốn là SQLite. Đúng vậy, nghĩa là giờ đây bạn hoàn toàn có thể đọc/ghi dữ liệu với SQL ngay trong trình duyệt, dĩ nhiên nó được lưu trữ bền vững ngay cả khi tắt máy.

Anh ta còn chỉ ra một điều hết sức vô lý là mặc dù tận dụng IndexedDB để lưu trữ nhưng tốc độ truy vấn của SQLite trên này vẫn nhanh hơn hàng chục lần so với IndexedDB. Cũng có thể vì thế mà cái tên "absurd" được đặt luôn cho thư viện.

Như vậy, Notas có hy vọng tối ưu được hiệu năng trong thời gian sắp tới. Nhưng đó có thể là một nhiệm vụ ưu tiên sau khi được ra mắt. Tôi sẽ hoàn thành Notas với IndexedDB trước để kịp ra mắt với bạn đọc. Chắc sẽ hiếm lắm mới có một người tạo ra 10 nghìn ghi chú trong thời gian ngắn.

Kế hoạch tuần tới

Tuần tiếp theo sẽ là thời gian để hoàn thiện UI/UX trên cả PC lẫn Mobile. Vì nhiều tính năng vẫn còn đang chưa đầy đủ, nhiệm vụ của tôi là làm cho các luồng sử dụng về một thể thống nhất. Ngoài ra, tôi sẽ tối ưu lại mã, xóa bớt mã thừa hoặc cấu trúc lại.

Còn bạn, có câu hỏi hay thắc mắc gì về quá trình làm Notas nữa hay không? Hãy để lại bình luận cho tôi và mọi người biết nhé!

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.
Author

Xin chào, tôi tên là Hoài - một anh Dev kể chuyện bằng cách viết ✍️ và làm sản phẩm 🚀. Với nhiều năm kinh nghiệm lập trình, tôi đã đóng góp một phần công sức cho nhiều sản phẩm mang lại giá trị cho người dùng tại nơi đang làm việc, cũng như cho chính bản thân. Sở thích của tôi là đọc, viết, nghiên cứu... Tôi tạo ra trang Blog này với sứ mệnh mang đến những bài viết chất lượng cho độc giả của 2coffee.dev.Hãy theo dõi tôi qua các kênh LinkedIn, Facebook, Instagram, Telegram.

Bạn thấy bài viết này có ích?
Không

Bình luận (3)

Nội dung bình luận...
Avatar
Ẩn danh6 tháng trước
anh Hoài cho em hỏi 2coffee.dev của mình đang dùng DB gì thế ạ? Ngoài ra anh deploy nó ra sao? Có bao giờ mình bị quá tải chưa?
Trả lời
Avatar
Xuân Hoài Tống6 tháng trước
Hi e, blog a dùng PostgreSQL dựa trên supabase.com. Đây là một dạng dịch vụ Cloud nên không cần phải quan tâm đến triển khai máy chủ. E có thể đọc thêm bài viết https://2coffee.dev/bai-viet/hoan-tat-chuyen-doi-blog-thanh-web-is-on-the-edge để biết chi tiết hơn về cách a vận hành. Còn về quá tải thì a chưa bị bao giờ nha.
Avatar
Anh (Daniel) Le6 tháng trước
app của bạn trông giống giống takenote.dev 🙃
Trả lời
Avatar
Xuân Hoài Tống6 tháng trước
Mình mới vào xem, công nhận giống thật 🤣
Avatar
thanh trần7 tháng trước
bia thôi =))
Trả lời
Avatar
Xuân Hoài Tống7 tháng trước
Ôcê bạn ơi