ソースを参照

perf: reduce pull-many queries for get-page-blocks (#4253)

perf: reduce pull-many queries for get-page-blocks
Tienson Qin 3 年 前
コミット
2d622be63a
2 ファイル変更32 行追加9 行削除
  1. 25 6
      src/main/frontend/db/model.cljs
  2. 7 3
      src/main/frontend/db/react.cljs

+ 25 - 6
src/main/frontend/db/model.cljs

@@ -438,7 +438,7 @@
     (when block-db-id
       (some->
        (react/q repo-url [:frontend.db.react/block-refs-count block-db-id]
-         {:query-fn (fn [_db]
+         {:query-fn (fn [_db _tx-report _result]
                       (count (:block/_refs (db-utils/entity repo-url block-db-id))))}
          nil)
        react))))
@@ -467,10 +467,29 @@
          (some->
           (react/q repo-url [:frontend.db.react/page-blocks page-id]
             {:use-cache? use-cache?
-             :query-fn (fn [db]
-                         (let [datoms (d/datoms db :avet :block/page page-id)
-                               block-eids (mapv :e datoms)
-                               blocks (db-utils/pull-many repo-url pull-keys block-eids)]
+             :query-fn (fn [db tx-report result]
+                         (let [[tx-id->block cached-id->block] (when (and tx-report result)
+                                                                 (let [tx-block-ids (distinct (mapv :e (:tx-data tx-report)))
+                                                                       blocks (->> (db-utils/pull-many repo-url pull-keys tx-block-ids)
+                                                                                   (remove nil?))]
+                                                                   [(zipmap (mapv :db/id blocks) blocks)
+                                                                    (zipmap (mapv :db/id @result) @result)]))
+                               datoms (d/datoms db :avet :block/page page-id)
+                               tx-merged-blocks (when (and tx-id->block result)
+                                                  (let [result (reduce (fn [acc datom]
+                                                                         (let [id (:e datom)
+                                                                               block (or (get tx-id->block id)
+                                                                                         (get cached-id->block id))]
+                                                                           (if block
+                                                                             (conj! acc block)
+                                                                             (reduced nil))))
+                                                                       (transient [])
+                                                                       datoms)]
+                                                    (when result (persistent! result))))
+                               blocks (or
+                                       tx-merged-blocks
+                                       (let [block-eids (mapv :e datoms)]
+                                          (db-utils/pull-many repo-url pull-keys block-eids)))]
                            (map (fn [b] (assoc b :block/page bare-page-map)) blocks)))}
             nil)
           react))))))
@@ -1013,7 +1032,7 @@
             filter-fn   (fn [datom]
                           (some (fn [p] (re-find p (:v datom))) patterns))]
         (->> (react/q repo [:frontend.db.react/page-unlinked-refs page-id]
-                      {:query-fn (fn [db]
+                      {:query-fn (fn [db _tx-report _result]
                                    (let [ids
                                          (->> (d/datoms db :aevt :block/content)
                                               (filter filter-fn)

+ 7 - 3
src/main/frontend/db/react.cljs

@@ -173,6 +173,10 @@
         (js/console.error e)
         old-db))))
 
+(defn get-query-cached-result
+  [k]
+  (:result (get @query-state k)))
+
 (defn q
   [repo k {:keys [use-cache? transform-fn query-fn inputs-fn disable-reactive?]
            :or {use-cache? true
@@ -181,14 +185,14 @@
   (let [kv? (and (vector? k) (= :kv (first k)))
         k (vec (cons repo k))]
     (when-let [conn (conn/get-conn repo)]
-      (let [result-atom (:result (get @query-state k))]
+      (let [result-atom (get-query-cached-result k)]
         (when-let [component *query-component*]
           (add-query-component! k component))
         (if (and use-cache? result-atom)
           result-atom
           (let [result (cond
                          query-fn
-                         (query-fn conn)
+                         (query-fn conn nil nil)
 
                          inputs-fn
                          (let [inputs (inputs-fn)]
@@ -312,7 +316,7 @@
                       new-result (->
                                   (cond
                                     query-fn
-                                    (let [result (query-fn db)]
+                                    (let [result (query-fn db tx result)]
                                       (if (coll? result)
                                         (doall result)
                                         result))