Lưu trữ dữ liệu hình ảnh cho ứng dụng web ngoại tuyến (cơ sở dữ liệu lưu trữ phía máy khách)


105

Tôi có một ứng dụng web ngoại tuyến sử dụng appcaching. Tôi cần cung cấp cho nó khoảng 10MB - 20MB dữ liệu mà nó sẽ lưu (phía máy khách) bao gồm chủ yếu là các tệp hình ảnh PNG. Hoạt động như sau:

  1. Tải xuống và cài đặt ứng dụng web trong appcache (sử dụng tệp kê khai)
  2. Yêu cầu ứng dụng web từ tệp dữ liệu PNG của máy chủ (làm thế nào? - xem các lựa chọn thay thế bên dưới)
  3. Đôi khi ứng dụng web đồng bộ lại với máy chủ và cập nhật / xóa / bổ sung một phần nhỏ vào cơ sở dữ liệu PNG
  4. FYI: Máy chủ là máy chủ JSON REST, có thể đặt tệp vào wwwroot để nhận

Đây là phân tích hiện tại của tôi về "cơ sở dữ liệu" dựa trên ứng dụng khách để xử lý lưu trữ blob nhị phân

XEM CẬP NHẬT ở dưới cùng

  • AppCache (thông qua tệp kê khai, thêm tất cả PNG và sau đó cập nhật theo yêu cầu)
    • CON: bất kỳ thay đổi nào của một mục trong cơ sở dữ liệu PNG sẽ có nghĩa là tải xuống hoàn toàn tất cả các mục trong tệp kê khai (Thực sự là tin xấu!)
  • Lưu trữ web
  • PhoneGap & SQLLite
    • CON: Nhà tài trợ sẽ từ chối nó vì một ứng dụng gốc yêu cầu chứng nhận
  • Tệp ZIP
    • Máy chủ tạo một tệp zip, đặt tệp đó vào wwwroot và thông báo cho máy khách
    • người dùng phải giải nén theo cách thủ công (Ít nhất đó là cách tôi thấy nó) và lưu vào hệ thống tệp khách hàng
    • Ứng dụng web sử dụng API FileSystem để tham chiếu các tệp
    • CON: ZIP có thể quá lớn (zip64?), Mất nhiều thời gian để tạo
    • CON: Không chắc liệu FileSystem API luôn có thể đọc ra khỏi hộp cát hay không (tôi nghĩ vậy)
  • USB hoặc thẻ SD (trở lại thời kỳ đồ đá ....)
    • Người dùng sẽ là cục bộ của máy chủ trước khi ngoại tuyến
    • Vì vậy, chúng tôi có thể yêu cầu anh ta lắp thẻ SD, để máy chủ lấp đầy nó bằng các tệp PNG
    • Sau đó người dùng sẽ cắm nó vào máy tính xách tay, máy tính bảng
    • Ứng dụng web sẽ sử dụng FileSystem API để đọc các tệp
    • CON: Không chắc liệu FileSystem API luôn có thể đọc ra khỏi hộp cát hay không (tôi nghĩ vậy)
  • WebSQL
    • CON: w3c đã bỏ nó (khá tệ)
    • Tôi có thể coi một trình bao bọc Javascript sử dụng IndexedDB và WebSQL như một dự phòng
  • API hệ thống tệp
    • Chrome hỗ trợ đọc / ghi các đốm màu
    • CON: không rõ về IE và FireFox (IE10, có msSave không chuẩn)
    • caniuse.com báo cáo hỗ trợ IOS và Android (nhưng một lần nữa, đây chỉ là r / w của JSON, hay nó bao gồm API blob đầy đủ để viết?
    • CON: Mọi người FireFox không thích FileSystem API và không rõ họ có hỗ trợ lưu các đốm màu hay không: https://hacks.mozilla.org/2012/07/why-no-filesystem-api-in-firefox/
    • PRO: Phần lớn nhanh hơn so với IndexedDB cho blobs theo jsperf http://jsperf.com/indexeddb-vs-localstorage/15 (trang 2)
  • IndexedDB
    • Hỗ trợ tốt trong IE10, FireFox (lưu, đọc các đốm màu)
    • Tốc độ tốt và quản lý dễ dàng hơn hệ thống tệp (xóa, cập nhật)
    • CHUYÊN NGHIỆP: xem kiểm tra tốc độ: http://jsperf.com/indexeddb-vs-localstorage/15
    • Xem bài viết này về cách lưu trữ và hiển thị hình ảnh trong IndexedDB: https://hacks.mozilla.org/2012/02/storing-images-and-files-in-indexeddb/
    • CON: Tôi đã xác nhận rằng Chrome chưa hỗ trợ tính năng viết bằng blob (lỗi hiện tại, nhưng không rõ khi nào nó sẽ được sửa)
    • CẬP NHẬT: Các nhà phát triển Chrome xác nhận rằng họ đang làm việc trên điều này cho cả máy tính để bàn và Android! chưa có mốc thời gian.
  • Trình bao bọc JavaScript của LawnChair http://brian.io/lawnchair/
    • CHUYÊN NGHIỆP: trình bao bọc rất sạch cho IndexedDB, WebSQL hoặc bất kỳ cơ sở dữ liệu nào bạn có (hãy nghĩ đến polyfill)
    • CON: không thể lưu trữ các đốm màu nhị phân, chỉ có dữ liệu: uri (mã hóa base64) (có thể là lỗ hổng nghiêm trọng do chi phí mã hóa)
  • IndexedDB JQUERY polyFill https://github.com/axemclion/jquery-indexeddb
    • Parashuram đã viết một trình bao bọc JQUERY đẹp cho giao diện IndexedDB thô
    • CHUYÊN NGHIỆP: đơn giản hóa đáng kể khi sử dụng IndexedDB, tôi đã hy vọng thêm một miếng đệm / polyfill cho Chrome FileSystemAPI
    • CON: Nó sẽ xử lý các đốm màu, nhưng tôi không thể làm cho nó hoạt động
  • idb.filesystem.js http://ericbidelman.tumblr.com/post/21649963613/idb-filesystem-js-bringing-the-html5-filesystem-api
    • Eric Bidelman @ Google đã viết một PolyFill API FileSystem được thử nghiệm tốt sử dụng DB được lập chỉ mục như một dự phòng
    • CHUYÊN NGHIỆP: API FileSystem rất thích hợp để lưu trữ các đốm màu
    • CHUYÊN NGHIỆP: hoạt động tốt trên FireFox và Chrome
      • CHUYÊN NGHIỆP: tuyệt vời để đồng bộ hóa với CouchDB dựa trên đám mây
    • CON: không rõ tại sao, nhưng nó không hoạt động trên IE10
  • Thư viện JavaScript PouchDB http://pouchdb.com/
    • tuyệt vời để đồng bộ CouchDB với một DB cục bộ (sử dụng WebSQL hoặc IndexedDB (mặc dù không phải là vấn đề của tôi)
    • CON: KHÔNG CÓ Ý kiến, PouchDB hiện hỗ trợ các đốm màu nhị phân cho tất cả các trình duyệt gần đây (IE, Chrome, Firefox, Chrome trên thiết bị di động, v.v.) cũng như nhiều trình duyệt cũ hơn. Đó không phải là trường hợp lần đầu tiên tôi làm bài đăng này.

LƯU Ý: để xem dữ liệu: mã hóa uri của PNG, tôi đã tạo một ví dụ tại: http://jsbin.com/ivefak/1/edit

Các tính năng mong muốn / hữu ích / chưa được cải thiện

  • Không có ứng dụng gốc (EXE, PhoneGap, ObjectiveC, v.v.) trên máy khách (ứng dụng web thuần túy)
  • Chỉ cần chạy trên Chrome, FireFox, IE10 mới nhất cho máy tính xách tay
  • Rất muốn có giải pháp tương tự cho Máy tính bảng Android (IOS cũng tốt) nhưng chỉ cần một trình duyệt để hoạt động (FF, Chrome, v.v.)
  • Dân số DB ban đầu nhanh
  • YÊU CẦU: Tải ảnh rất nhanh bằng ứng dụng web từ bộ nhớ (DB, tệp)
  • Không dành cho người tiêu dùng. Chúng tôi có thể hạn chế trình duyệt và yêu cầu người dùng thực hiện thiết lập và tác vụ đặc biệt, nhưng hãy giảm thiểu điều đó

Triển khai IndexedDB

  • Có một bài viết tuyệt vời về cách IE, FF và Chrome triển khai nội bộ điều này tại: http://www.aaron-powell.com/web/indexeddb-storage
  • Nói ngắn gọn:
    • IE sử dụng định dạng cơ sở dữ liệu giống như Exchange và Active Directory cho IndexedDB
    • Firefox đang sử dụng SQLite, do đó, loại triển khai cơ sở dữ liệu NoSQL trong cơ sở dữ liệu SQL
    • Chrome (và WebKit) đang sử dụng cửa hàng Khoá / Giá trị có di sản trong BigTable

Kết quả hiện tại của tôi

  • Tôi đã chọn sử dụng phương pháp IndexedDB (và polyfill với FileSystemAPI dành cho Chrome cho đến khi chúng hỗ trợ blob)
  • Đối với việc tìm nạp các ô, tôi đã gặp khó khăn vì những người JQUERY đang say sưa thêm cái này vào AJAX
  • Tôi đã sử dụng XHR2-Lib của Phil Parsons, rất giống với JQUERY .ajax () https://github.com/pmp/xhr2-lib
  • Hiệu suất cho 100 MB tải xuống (IE10 4s, Chrome 6s, FireFox 7s).
  • Tôi không thể tải bất kỳ trình bao bọc IndexedDB nào hoạt động cho các đốm màu (xe cỏ, PouchDB, jquery-indexeddb, v.v.)
  • Tôi đã cuộn trình bao bọc của riêng mình và hiệu suất là (IE10 2s, Chrome 3s, FireFox 10s)
  • Với FF, tôi cho rằng chúng ta đang gặp vấn đề về hiệu suất khi sử dụng DB quan hệ (sqllite) cho một bộ lưu trữ không phải sql
  • LƯU Ý, Chrome có các công cụ gỡ lỗi nổi bật (tab nhà phát triển, tài nguyên) để kiểm tra trạng thái của IndexedDB.

Kết quả CUỐI CÙNG được đăng dưới đây như câu trả lời

Cập nhật

PouchDB hiện hỗ trợ các đốm màu nhị phân cho tất cả các trình duyệt gần đây (IE, Chrome, Firefox, Chrome trên thiết bị di động, v.v.) cũng như nhiều trình duyệt cũ hơn. Đó không phải là trường hợp lần đầu tiên tôi làm bài đăng này.


1
webstorage không hỗ trợ json nhưng chuỗi, vì vậy bạn có thể mã hóa base64 imagez của mình và phân phát chúng trở lại dưới dạng dataurls.
mpm

Được, nhưng có lẽ không tối ưu (hoặc trong hạn ngạch) cho 20 MB hình ảnh, thực sự là các ô bản đồ trơn trượt, cần được ứng dụng bản đồ LEAFLET tìm nạp và hiển thị nhanh chóng khi bạn thu phóng và xoay.
Dr.YSG

Nghiên cứu bạn đã thực hiện khá hữu ích.
Bogdan Kulynych

ý của tôi là bạn không cần phải xử lý các đốm màu nhị phân nếu bạn đang sử dụng hình ảnh png.
mpm

Bạn nói đúng, bạn có phiền không nếu tôi cập nhật tài liệu để phản ánh ý kiến ​​đóng góp của bạn?
Dr.YSG

Câu trả lời:


25

Kết quả Bộ nhớ cache blob ngoại tuyến cho bản đồ trơn trượt PNG

Thử nghiệm

  • 171 tệp PNG (tổng cộng 3,2MB)
  • Nền tảng đã thử nghiệm: Chrome v24, FireFox 18, IE 10
  • Cũng nên hoạt động với Chrome & FF dành cho Android

Tìm nạp từ máy chủ web

  • sử dụng XHR2 (được hỗ trợ trên hầu hết các trình duyệt) để tải xuống blob từ máy chủ web
  • Tôi đã sử dụng XHR2-Lib của Phil Parsons, rất giống với JQUERY .ajax ()

Lưu trữ

Trưng bày

  • Tôi đang sử dụng Tờ rơi http://leafletjs.com/ để hiển thị các ô bản đồ
  • Tôi đã sử dụng plugin lớp ngói chức năng của Ishmael Smyrnow để tìm nạp lớp xếp từ DB
  • Tôi đã so sánh lớp lát nền dựa trên DB với một bộ nhớ hoàn toàn cục bộ (localhost: //)
  • Không có sự khác biệt đáng chú ý về hiệu suất! giữa việc sử dụng IndexedDB và các tệp cục bộ!

Các kết quả

  • Chrome: Tìm nạp (6.551 giây), Lưu trữ (8.247 giây), Tổng thời gian đã trôi qua: (13.714 giây)
  • FireFox: Tìm nạp (0,422 giây), Lưu trữ (31,519 giây), Tổng thời gian đã trôi qua: (32,836 giây)
  • IE 10: Tìm nạp (0,668 giây), Lưu trữ: (0,896 giây), Tổng thời gian đã trôi qua: (3,758 giây)

4

Đối với các yêu cầu của bạn, tôi khuyên bạn nên phát triển một polyfill mới dựa trên hai cái khác: FileSystem API thành IndexedDBIndexedDB cho WebSQL - là lựa chọn tốt nhất.

Cái trước sẽ cho phép hỗ trợ lưu trữ các đốm màu trong Chrome (FileSystem API) và Firefox (IndexedDB), trong khi cái sau sẽ cung cấp hỗ trợ cho Android và iOS ( WebSQL ). Điều cần thiết là làm cho những polyfills này hoạt động cùng nhau và tôi cho rằng nó không khó.

NB: Vì tôi không thể tìm thấy bất kỳ thông tin nào trên web về điều này, bạn nên kiểm tra xem việc lưu trữ các đốm màu bằng cách sử dụng polyfill WebSQL có hoạt động trên iOS và Android hay không. Có vẻ như nó sẽ hoạt động mặc dù:

var sql = ["CREATE TABLE", idbModules.util.quote(storeName), "(key BLOB", createOptions.autoIncrement ? ", inc INTEGER PRIMARY KEY AUTOINCREMENT" : "PRIMARY KEY", ", value BLOB)"].join(" ")

Nguồn


Tôi đang nghiêng về đề xuất của bạn, nhưng tôi đang chờ nghe từ những người khác. Tôi không có android tiện dụng, nhưng sẽ rất tốt nếu tạo jsBin hoặc jsFiddle và xem những gì hoạt động trên Android.
Dr.YSG

1
Hai đốm màu này khác nhau. Sqlite blob là bộ đệm mảng trong javascript, trong khi js blob không có tương đương trong sqlite. Blob không thể chuyển đổi thành bộ đệm mảng, mặc dù nó có thể được nhân bản về cấu trúc.
Kyaw Tun

2

Tôi có các ví dụ về bộ nhớ đệm bản đồ ( ví dụ mở, khám phá các vùng và thu phóng, chuyển đổi ngoại tuyến và các vùng đã khám phá sẽ khả dụng).

map.js- lớp bản đồ cho các ô ngoại tuyến, storage.js- triển khai lưu trữ dựa trên IndexedDb và WebSQL (nhưng điều này chỉ kiểm tra việc triển khai với hiệu suất kém).

  • Đối với các tệp trang web (html, css, js và v.v.), tôi thích sử dụng bộ đệm ứng dụng hơn.
  • Để lưu trữ, tôi thích sử dụng Indexed DB (hỗ trợ blob), Web SQL (chỉ base64), FileWriter (hỗ trợ blob, nhưng chỉ chrome). Thành thật mà nói, lưu trữ là một vấn đề lớn cho điều này. Bạn cần giải pháp giá trị quan trọng nhanh nhất sẽ kết hợp tất cả. Tôi nghĩ rằng quyết định tốt là sử dụng giải pháp tồn tại.
  • Để tìm nạp, tôi đã sử dụng canvas với CORS. Nhưng tôi đang nghĩ về WebWorkers và XHR2 và điều này có thể tốt hơn canvas thay vì canvas vì canvas có một số vấn đề với CORS trong các trình duyệt khác nhau và các trình duyệt khác (ví dụ: tiêu đề này được lưu trữ không tốt trong opera ).

Thông tin bổ sung về quy mô của thành phố 2 tỷ dân ( Minsk ):

  • Thu phóng - 9, ô - 2, kích thước - 52 kb, trước đó - 52 kb;
  • Thu phóng - 10, ô - 3, kích thước - 72 kb, trước đó - 124 kb;
  • Thu phóng - 11, ô - 7, kích thước - 204 kb, trước đó - 328 kb;
  • Thu phóng - 12, ô - 17, kích thước - 348 kb, trước đó - 676 ​​kb;
  • Thu phóng - 13, ô - 48, kích thước - 820 kb, trước đó - 1,5 mb;
  • Zoom - 14, ô - 158, kích thước - 2,2 mb, trước đó - 3,7 mb;
  • Zoom - 15, ô - 586, kích thước - 5,5 mb, trước đó - 9,3 mb;
  • Thu phóng - 16, ô - 2264, kích thước - 15 mb, trước đó - 24,3 mb;

Tôi cho rằng đó là những ô JPG ở định dạng EGPS3857 trơn trượt phải không? vì tôi đang sử dụng tờ rơi và thực hiện các ngày raster nên tôi phải sử dụng PNG. cũng xem bản demo của tôi về việc sử dụng PouchDB (sử dụng IDB bên dưới). stackoverflow.com/questions/16721312/…
Dr.YSG

Ồ vâng, bạn đang nhanh chóng lưu vào bộ nhớ đệm, nhưng bạn có biết tôi có thể đến đâu để lấy bản đồ OSM dựng sẵn (toàn thế giới) xuống để thu phóng 10 hoặc 11 hoặc 12 không? Chúng tôi sẽ giữ điều này trên máy chủ ngoại tuyến của chúng tôi.
Dr.YSG

Không, được sử dụng PNGvới phép chiếu mặc định (EGPS: 3857) nhưng không quan trọng JPEGhoặc PNGvì nó được sử dụng bởi imgthẻ hoặc canvas. Với ví dụ của tôi, bạn chỉ có thể tải trước các ô nếu bạn biết các phím ô ( storage.add('x_y_z', 'data:image/png;base64,...')cho mỗi ô được lưu trữ), nhưng bạn luôn có thể lấy chúng nếu biết chỉ giới hạn (đa giác) và thu phóng.
tbicr

Tôi muốn đảm bảo rằng chúng tôi không gặp vấn đề về ngôn ngữ. Bạn có bất kỳ nơi nào mà chúng tôi có thể nhận được một bộ OSM trên toàn thế giới các ô trượt (PNG hoặc JPG) để thu phóng cấp độ 10 không?
Dr.YSG

Bạn có thể nhận dạng xếp tile.osm.org(trình kết xuất mapnik). Ví dụ http://tile.openstreetmap.org/10/590/329.png( zoom/ x/ y.png). Các ô này có Access-Control-Allow-Origin: *tiêu đề để bạn có thể lấy chúng bằng ajax hoặc lấy dữ liệu uri (base64) bằng canvas. Bạn đã có thể tải về gạch với bạn manifest.json {id: 0-0-0}, nhưng bạn phải chắc chắn rằng có quyền zoom, x, ytrình tự.
tbicr

1

Một vài năm trước (không chính xác là thời kỳ đồ đá), tôi đang sử dụng một ứng dụng java đã ký tên sẽ truy vấn máy chủ của nó để đồng bộ hóa / cập nhật các yêu cầu, tải xuống các tệp thích hợp từ máy chủ và lưu chúng trên hệ thống tệp của người dùng (không phải cơ sở dữ liệu). Giải pháp đó có thể phù hợp với bạn, mặc dù bạn sẽ cần người viết applet và ký tên vào nó. Đối với các giải pháp cơ sở dữ liệu, một applet như vậy có thể sử dụng jdbc có sẵn cho hầu hết các cơ sở dữ liệu sử dụng localhost trên một cổng phù hợp (ví dụ: 3306 cho MySQL). Tôi tin rằng thẻ applet không được chấp nhận trong Html5 nhưng nó vẫn hoạt động. Không có kinh nghiệm về máy tính bảng Android, vì vậy không thể nhận xét về phần đó.


1
Tôi bắt đầu lập trình FORTRAN vào năm 1968 bằng cách sử dụng một cú đấm thẻ. Vì vậy, các giải pháp thời kỳ đồ đá không phải là mới đối với tôi.
Dr.YSG
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.