【Tiptap】怎样高效存储内容?

Tiptap中,你可以将内容存为HTML格式,也可以存为JSON格式,哪种效率高呢?答案是后者。为什么呢?

For saving TipTap content, the JSON representation is overwhelmingly the best practice.

Let's break down why and clarify what "document" might mean in this context:

1. JSON (the output of editor.getJSON()) - BEST PRACTICE

  • What it is: This is the native, internal representation of your content in TipTap (which uses ProseMirror under the hood). It's a structured JSON object that describes the document's nodes, marks, and their attributes.

    json 复制代码
    {
      "type": "doc",
      "content": [
        {
          "type": "heading",
          "attrs": {
            "level": 1
          },
          "content": [
            {
              "type": "text",
              "text": "My Awesome Document"
            }
          ]
        },
        {
          "type": "paragraph",
          "content": [
            {
              "type": "text",
              "text": "This is some "
            },
            {
              "type": "text",
              "marks": [
                {
                  "type": "bold"
                }
              ],
              "text": "bold"
            },
            {
              "type": "text",
              "text": " and "
            },
            {
              "type": "text",
              "marks": [
                {
                  "type": "italic"
                }
              ],
              "text": "italic"
            },
            {
              "type": "text",
              "text": " text."
            }
          ]
        }
      ]
    }
  • Why it's best practice:

    • Lossless: It perfectly preserves all semantic information, custom node types, custom attributes, and editor state. When you load this JSON back into TipTap, you get the exact same document you saved.
    • Perfect Round-Trip: Essential for re-editing. You can reliably save, close, and re-open the editor with the exact previous state.
    • Semantic Data: The structured JSON is more than just presentation; it describes the meaning and hierarchy of your content, which can be useful for other programmatic operations (e.g., searching, transformation, analysis).
    • Often Smaller: For complex documents, the JSON can sometimes be more compact than the equivalent HTML.
    • Source of Truth: It's the canonical representation of your content from TipTap's perspective.
  • When to use it: Always use this for your primary storage in a database or file system if you ever intend to re-load the content back into an editor for modification.

2. Rendered HTML (the output of editor.getHTML()) - NOT for Primary Storage

  • What it is: This is the HTML string generated by TipTap from its internal JSON representation, designed for display in a web browser.

    html 复制代码
    <h1>My Awesome Document</h1>
    <p>This is some <strong>bold</strong> and <em>italic</em> text.</p>
  • Why it's generally NOT best practice for primary storage:

    • Lossy: HTML primarily focuses on presentation. It often loses semantic information or specific attributes that might be present in your TipTap/ProseMirror JSON (especially if you have custom extensions). For example, a custom CalloutBlock with an id attribute might just become a <div> in HTML, losing its distinct type and ID.
    • Poor for Re-editing: While TipTap can parse HTML back into its editor, it's not a perfect round-trip. The editor has to "guess" how to map generic HTML tags back to its structured nodes and marks. This can lead to inconsistencies or loss of specific features when you re-import, particularly with custom extensions.
    • Sanitization Required: If you store and then render user-generated HTML, you must sanitize it to prevent XSS (Cross-Site Scripting) vulnerabilities. This adds an extra layer of complexity and potential for errors.
  • When you do need HTML:

    • Display: You absolutely need HTML to display the content on a public webpage.
    • SEO: Search engines consume HTML.
    • Caching: You might cache the rendered HTML to avoid re-rendering every time content is requested.

Best Practice Recommendation: Store Both (but JSON is primary)

The most robust and flexible approach is often to store the JSON as your primary content source and generate/store HTML for display purposes.

Here's how that usually looks:

  1. Database Storage:

    • Create a column (e.g., content_json) in your database table (e.g., posts, pages) to store the TipTap JSON. Use a TEXT or JSONB (PostgreSQL) type for this.
    • Optionally, create another column (e.g., content_html) to store the pre-rendered HTML. This saves you from converting JSON to HTML on every page load.
  2. Saving Content:

    • When the user saves their content in TipTap:
      • Get the JSON: const contentJson = editor.getJSON();
      • Get the HTML: const contentHtml = editor.getHTML();
      • Important: Before saving contentHtml to the database or displaying it, always sanitize it using a library like DOMPurify to prevent XSS.
      • Save both contentJson and contentHtml to your database.
  3. Loading Content for Editing:

    • When you want to load content back into TipTap for editing:
      • Fetch content_json from your database.
      • Use editor.setContent(contentJson, false); to load the content into the editor. (The false flag tells it not to emit an update event immediately).
  4. Loading Content for Display:

    • When you want to display the content on a webpage:
      • Fetch content_html from your database.
      • Render it directly (since you've already sanitized it upon saving).

Summary:

  • For robust editing and future extensibility: Store JSON (editor.getJSON()). This is the single source of truth for your TipTap content.
  • For displaying content on a webpage: Use HTML (editor.getHTML()), but always sanitize it.
  • Ideal Workflow: Store both, with JSON as the primary, re-editable format, and HTML as a pre-rendered, sanitized version for efficient display.
相关推荐
亮子AI1 小时前
【Tiptap】如何使用 ordered list?
数据结构·list·tiptap
亮子AI5 天前
【Tiptap】怎样输入/粘贴 Markdown 到编辑器里?
编辑器·tiptap
亮子AI12 天前
【Tiptap】如何实现增量更新?
tiptap
HBR666_2 个月前
AI编辑器(FIM补全,AI扩写)简介
前端·ai·编辑器·fim·tiptap
HBR666_2 个月前
AI编辑器(二) ---调用模型的fim功能
前端·ai·编辑器·fim·tiptap
不老刘4 个月前
Tiptap(基于 Prosemirror)vs TinyMCE:哪个更适合你的技术栈?
编辑器·tinymce·tiptap·prosemirror