请在2024年Clojure状态调查中分享您的看法!

欢迎!请查看关于页面以获取更多有关这个工作如何运作的信息。

+2
ClojureScript
编辑

我在用cljs开发一个react native应用,并将产品目录作为transit json存储在数据库中。到目前为止工作得很顺利,但随着我们的圣诞产品上线,现在它在Android上已接近6MB的极限。

我曾想过使用键缓存可能会有帮助,但担心会牺牲响应性。

目前,为了保持UI的响应性,我将每个产品的数据存储为单独的transit映射(js是单线程的,我需要保持反序列化和序列化块小,以免在用户想要按按钮时遇到反序列化一个庞大的数据结构)。

我认为这意味着我不能使用transit键缓存,因为重复的键要到下一个产品才会出现。

有没有办法以某种方式共享键缓存或更好地减少transit json的体积?

1 个答案

+1

编辑了

一种方法是在常见的键的基础上,定义自定义产品语义类型,并加入额外的键。
https://github.com/cognitect/transit-format#extensibility

通过这种方法,您可以节省一些空间,但可能需要付出一些维护工作以及额外的CPU时间(这对于您一次处理多个 smirk 文档可能是可接受的)。

以下是一个仅用 Product 包装产品映射的示例,这样就不必在代码库的其余部分使用记录。

(ns foo
  (:require 
   [cognitect.transit :as tr])
  (:import
   [com.cognitect.transit WriteHandler]
   [java.io ByteArrayOutputStream]))

(defrecord Product [m])
(def product-tag "pro")
(def common-keys [:product/foo :product/bar :product/baz])
(def custom-writers
  {Product (reify WriteHandler
             (getVerboseHandler [_] nil)
             (stringRep [_ kw] nil)
             (tag [_ _] product-tag)
             (rep [_ p] (let [common (mapv (:m p) common-keys)
                              custom (reduce dissoc (:m p) common-keys)]
                          (into [custom] common))))})

(def custom-readers
  {product-tag (fn [rep]
                 (let [[m & common-vals] rep]
                   (merge m (zipmap common-keys common-vals))))})

(defn write [writers product]
  (let [out (ByteArrayOutputStream. 4096)
        wr  (tr/writer out :json writers)]
    (tr/write wr product)
    (.toString out)))

(write {:handlers custom-writers}
  (Product. {:product/foo 1 :product/bar 2 :product/baz 3 :custom/foo 4}))
;; "[\"~#pro\",[[\"^ \",\"~:custom/foo\",4],1,2,3]]"

(write {}
  (Product. {:product/foo 1 :product/bar 2 :product/baz 3 :custom/foo 4}))
;; "[\"^ \",\"~:m\",[\"^ \",\"~:product/foo\",1,\"~:product/bar\",2,\"~:product/baz\",3,\"~:custom/foo\",4]]"

(write {}
  {:product/foo 1 :product/bar 2 :product/baz 3 :custom/foo 4})
;; "[\"^ \",\"~:product/foo\",1,\"~:product/bar\",2,\"~:product/baz\",3,\"~:custom/foo\",4]"
...