当前位置: 首页 > article >正文

解决Vditor加载Markdown网页很慢的问题(Vite+JS+Vditor)

1. 引言

在上一篇文章《使用Vditor将Markdown文档渲染成网页(Vite+JS+Vditor)》中,详细介绍了通过Vditor将Markdown格式文档渲染成Web网页的过程,并且实现了图片格式居中以及图片源更换的功能。不过,笔者发现在加载这个渲染Markdown网页的时候特别慢,本文就总结一下这个问题。

2. 详论

2.1 解决方案

经过笔者的调试发现,性能损耗主要是Vditor使用的一个依赖库文件lute.min.js加载很慢,这个文件大概有3.6M大小,并且放在了远端在线资源上。lute.min.js是一个Markdown引擎,Vditor默认是将其放到CDN上,具体使用的就是Cloudflare(传说中的赛博活佛😆)。理论上就是因为资源文件比较大才需要使用CDN,但是因为一些原因Cloudflare在国内的连接速度并不快。所以没办法,这里还是得将这些资源地址改回成域内,除非你有自己的CDN。

在Vditor官方论坛上找了类似的问题1,回帖指出需要按照官方的开发指南2进行CDN参数配置,如下所示:
Vditor官方的开发指南中的CDN参数配置
具体来说,就是在Vditor.preview接口中增加cdn的配置:

Vditor.preview(document.getElementById("md-content"), demoMd, {cdn: window.location.origin,    //配置CDNmarkdown: {toc: false,mark: true, //==高亮显示==footnotes: true, //脚注autoSpace: true, //自动空格,适合中英文混合排版},math: {engine: "KaTeX", //支持latex公式inlineDigit: true, //内联公式可以接数字},hljs: {style: "github", //代码段样式lineNumber: true, //是否显示行号},anchor: 2, // 为标题添加锚点 0:不渲染;1:渲染于标题前;2:渲染于标题后lang: "zh_CN", //中文theme: {current: "light", //light,dark,light,wechat},transform: (html) => {// 使用正则表达式替换图片路径,并添加居中样式及题注return html.replace(/<img\s+[^>]*src="\.\/([^"]+)\.([a-zA-Z0-9]+)"\s*alt="([^"]*)"[^>]*>/g,(match, p1, p2, altText) => {// const newSrc = `${backendUrl}/blogs/resources/images/${postId}/${p1}.${p2}`;const newSrc = `${p1}.${p2}`;const imgWithCaption = `<div style="text-align: center;"><img src="${newSrc}" class="center-image" alt="${altText}"><p class="caption">${altText}</p></div>`;return imgWithCaption;});},
});

同时,还需要进行项目的配置,让这个前端项目能找到托管的CDN资源。根据开发指南的说明,托管的CDN资源不仅仅只有lute.min.js,还有其他资源文件,因此需要将这些文件都拷贝到特定的目录。那么就需要修改项目的配置,增加一个执行拷贝任务的脚本。

2.2 开发环境

不过由于拷贝文件的指令在不同的平台终端是不同的,因此最好引入一个中间件帮助统一一下指令的行为。这里使用Shx,它可以帮助我们在npm环境中跨平台执行类似于Unix样式的指令。在终端安装Shx:

npm install shx --save-dev

修改package.json:

{"name": "my-native-js-app","private": true,"version": "0.0.0","type": "module","scripts": {"copy:vditor": "shx mkdir -p dist && shx cp -r node_modules/vditor/dist/* dist","dev": "vite","build": "vite build --emptyOutDir","preview": "vite preview"},"devDependencies": {"shx": "^0.4.0","vite": "^6.3.5"},"dependencies": {"handlebars": "^4.7.8","vditor": "^3.11.0"}
}

增加的脚本copy:vditor具体就是指令:

npm run copy:vditor

具体意思就是创建目录dist,然后将目录node_modules/vditor/dist中的所有文件复制到这个dist目录中。然后正常执行dev指令:

npm run dev

理论上copy:vditor指令是可以合并到dev指令中的,也就是每次dev之前都执行copy:vditor。不过笔者还是觉得将其作为一次性命令更好,可以让程序启动得更快。

2.3 发布环境

我们知道,如果要正式发布项目的话,就需要先进行构建:

npm run build

然后再发布:

npm run preview

因此拷贝资源操作的脚本可以合并到build这一步中。这里,笔者介绍另外一种配置项目方法,就是使用Vite的配置文件vite.config.js。package.json是Web项目的基础配置文件;vite.config.js则是Vite的配置文件,用于自定义Vite的行为:例如配置服务器端口、代理,插件支持以及环境变量等等。这里就在项目根目录新建一个vite.config.js文件,内容如下:

// vite.config.js
import { defineConfig } from "vite";
import copy from "rollup-plugin-copy";export default defineConfig(() => {return {server: {host: "0.0.0.0", // 绑定所有网络接口port: 8000, // 自定义开发服务器端口open: true, // 自动打开浏览器},build: {rollupOptions: {plugins: [copy({targets: [{ src: "node_modules/vditor/dist/*", dest: "dist/dist" }],hook: "writeBundle", // 在 writeBundle 阶段执行复制操作}),],},},preview: {host: "0.0.0.0", // 绑定所有网络接口port: 8001, // 预览服务器端口open: true, // 自动打开浏览器},};
});

在这里的配置中,server字段和preview字段分别定义了开发模式dev和发布模式preview的网络地址和端口,并且设置执行完成后自动打开默认浏览器。build字段则配置在打包(rollup)代码的时候,通过插件rollup-plugin-copy执行拷贝操作,将目录node_modules/vditor/dist下的所有文件拷贝到dist/dist目录下。当然,插件rollup-plugin-copy需要进行安装:

npm install rollup-plugin-copy --save-dev

3. 结语

笔者这里开发模式和发布模式使用了两种不同的项目配置方法,来拷贝本地资源到特定目录。通过设置域内CDN,解决Vditor加载Markdown网页很慢的问题。理论上应该有更加优雅的方式,但是笔者这里是够用了,暂时不进行进一步研究。其实项目构建配置的问题没必要特意去学,首先还是要思考如何更方便地构建项目,自然而然就会去尝试解决方案,慢慢就学会项目构建配置的技能了。

实现代码


  1. 最近使用 vditor,遇到一个问题,请求 lute.min.js 的 cdn 总是请求不通导致 markdown 用不了怎么处理 ↩︎

  2. Vditor 一款浏览器端的 Markdown 编辑器,支持所见即所得(富文本)、即时渲染(类似 Typora)和分屏预览模式 ↩︎

相关文章:

解决Vditor加载Markdown网页很慢的问题(Vite+JS+Vditor)

1. 引言 在上一篇文章《使用Vditor将Markdown文档渲染成网页(ViteJSVditor)》中&#xff0c;详细介绍了通过Vditor将Markdown格式文档渲染成Web网页的过程&#xff0c;并且实现了图片格式居中以及图片源更换的功能。不过&#xff0c;笔者发现在加载这个渲染Markdown网页的时候…...

Flowise 本地部署文档及 MCP 使用说明

一、Flowise 简介 Flowise 是一个开源的拖放式 UI 工具,用于构建自定义的 LLM 工作流程。它允许用户通过可视化界面连接不同的 AI 组件,无需编写代码即可创建复杂的 AI 应用。 二、Docker 环境安装 1. 构建 Docker 镜像 docker build -t node22-ubuntu-dev .其中Dockerfi…...

YOLO学习笔记 | 一种用于海面目标检测的多尺度YOLO算法

多尺度YOLO算法用于海面目标检测 核心挑战分析 恶劣天气:雨雾、低光照干扰图像质量波浪干扰:动态背景产生大量噪声多尺度目标:船只(大)、浮标(小)等尺度差异大目标遮挡:波浪导致目标部分遮挡算法原理 多尺度YOLO架构(基于YOLOv5改进): graph TD A[输入图像] --&g…...

鸿蒙5.0项目开发——横竖屏切换开发

横竖屏切换开发 【高心星出品】 文章目录 横竖屏切换开发运行效果窗口旋转配置module.json5的orientation字段调用窗口的setPreferredOrientation方法案例代码解析Index1页面代码&#xff1a;EntryAbility在module.json5的配置信息&#xff1a;Index页面的代码信息&#xff1…...

Triton推理服务器部署YOLOv8(onnxruntime后端和TensorRT后端)

文章目录 一、Trition推理服务器基础知识1)推理服务器设计概述2)Trition推理服务器quickstart(1)创建模型仓库(Create a model Repository)(2)启动Triton (launching triton)并验证是否正常运行(3)发送推理请求(send a inference request)3)Trition推理服务器架…...

TDengine 的 AI 应用实战——电力需求预测

作者&#xff1a; derekchen Demo数据集准备 我们使用公开的UTSD数据集里面的电力需求数据&#xff0c;作为预测算法的数据来源&#xff0c;基于历史数据预测未来若干小时的电力需求。数据集的采集频次为30分钟&#xff0c;单位与时间戳未提供。为了方便演示&#xff0c;按…...

NLP学习路线图(二十一): 词向量可视化与分析

在自然语言处理&#xff08;NLP&#xff09;的世界里&#xff0c;词向量&#xff08;Word Embeddings&#xff09;犹如一场静默的革命。它将原本离散、难以捉摸的词语&#xff0c;转化为稠密、富含语义的连续向量&#xff0c;为机器理解语言铺平了道路。然而&#xff0c;这些向…...

【分布式技术】KeepAlived高可用架构科普

KeepAlived高可用架构 Keepalived 架构详解一、核心架构组件二、VRRP 协议详解1. **VRRP 核心概念**2. **VRRP 工作流程**3. **VRRP 通信机制** 三、高可用架构模型四、健康检查机制五、配置文件详解配置文件关键参数说明&#xff1a; 六、高可用实现流程七、脑裂问题与解决方案…...

如何配置mvn镜像源为华为云

如何配置mvn镜像源为华为云 # 查找mvn 配置文件 mvn -X help:effective-settings | grep settings.xml# 配置mvn镜像源为华为云&#xff0c;/home/apache-maven-3.9.5/conf/settings.xml文件路径需要根据上一步中查询结果调整 cat > /home/apache-maven-3.9.5/conf/setting…...

Linux平台排查CPU占用高的进程和线程指南

基础排查工具 1. top命令 - 实时进程监控 top操作指令&#xff1a; 按 P&#xff1a;按CPU使用率排序按 1&#xff1a;显示每个CPU核心的使用情况按 H&#xff1a;切换显示线程视图按 M&#xff1a;按内存使用排序按 q&#xff1a;退出 2. htop命令 - 增强版top&#xff08…...

多模态大语言模型arxiv论文略读(105)

UnifiedMLLM: Enabling Unified Representation for Multi-modal Multi-tasks With Large Language Model ➡️ 论文标题&#xff1a;UnifiedMLLM: Enabling Unified Representation for Multi-modal Multi-tasks With Large Language Model ➡️ 论文作者&#xff1a;Zhaowei…...

简述MySQL 超大分页怎么处理 ?

针对MySQL超大分页&#xff08;深度分页&#xff09;的性能问题&#xff0c;核心优化方案如下&#xff1a; 1. ‌子查询 覆盖索引&#xff08;延迟关联&#xff09;‌ ‌原理‌&#xff1a; 子查询仅扫描‌覆盖索引‌&#xff08;如主键&#xff09;&#xff0c;避免回表操作…...

Pyhton中的命名空间包(Namespace Package)您了解吗?

在 Python 中&#xff0c;命名空间包&#xff08;Namespace Package&#xff09; 是一种特殊的包结构&#xff0c;它允许将模块分散在多个独立的目录中&#xff0c;但这些目录在逻辑上属于同一个包命名空间。命名空间包的核心特点是&#xff1a;没有 __init__.py 文件&#xff…...

Java设计模式之备忘录模式详解

Java设计模式之备忘录模式详解 一、备忘录模式核心思想 核心目标&#xff1a;捕获对象内部状态并在需要时恢复&#xff0c;同时不破坏对象的封装性。如同游戏存档系统&#xff0c;允许玩家保存当前进度并在需要时回退到之前的状态。 二、备忘录模式类图&#xff08;Mermaid&am…...

Azure DevOps Server 2022.2 补丁(Patch 5)

微软Azure DevOps Server的产品组在4月8日发布了2022.2 的第5个补丁。下载路径为&#xff1a;https://aka.ms/devops2022.2patch5 这个补丁的主要功能是修改了代理(Agent)二进制安装文件的下载路径&#xff1b;之前&#xff0c;微软使用这个CND(域名为vstsagentpackage.azuree…...

手摸手还原vue3中reactive的get陷阱以及receiver的作用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、实例是什么&#xff1f;二、new Prxoy三、实现代码1.引入代码2.读入数据 总结 前言 receiver不是为解决get陷阱而生&#xff0c;而是为解决Proxy中的this绑…...

小明的Java面试奇遇之互联网保险系统架构与性能优化

一、文章标题 小明的Java面试奇遇之互联网保险系统架构与性能优化&#x1f680; 二、文章标签 Java,Spring Boot,MyBatis,Redis,Kafka,JVM,多线程,互联网保险,系统架构,性能优化 三、文章概述 本文模拟了程序员小明在应聘互联网保险系统开发岗位时&#xff0c;参与的一场深…...

C++学习-入门到精通【13】标准库的容器和迭代器

C学习-入门到精通【13】标准库的容器和迭代器 目录 C学习-入门到精通【13】标准库的容器和迭代器一、标准模板库简介1.容器简介2.STL容器总览3.近容器4.STL容器的通用函数5.首类容器的通用typedef6.对容器元素的要求 二、迭代器简介1.使用istream_iterator输入&#xff0c;使用…...

C# 面向对象特性

面向对象编程的三大基本特性是&#xff1a;封装、继承和多态。下面将详细介绍这三大特性在C#中的体现方式。 封装 定义&#xff1a;把对象的数据和操作代码组合在同一个结构中&#xff0c;这就是对象的封装性。 体现方式&#xff1a; 使用访问修饰符控制成员的可见性 通过属…...

ElasticStack技术之logstash介绍

一、什么是Logstash Logstash 是 Elastic Stack&#xff08;ELK Stack&#xff09;中的一个开源数据处理管道工具&#xff0c;主要用于收集、解析、过滤和传输数据。它支持多种输入源&#xff0c;如文件、网络、数据库等&#xff0c;能够灵活地对数据进行处理&#xff0c;比如…...

前端与后端

实例一 处理登录页面请求 # 处理登录页面请求 app.route(/c, methods[GET, POST]) # /c是网页地址 def login(): usernameaa passwordbb print(username,password) if request.method POST: username request.form.get(yhm) password requ…...

CI/CD 持续集成、持续交付、持续部署

CI/CD 是 持续集成&#xff08;Continuous Integration&#xff09; 和 持续交付/持续部署&#xff08;Continuous Delivery/Deployment&#xff09; 的缩写&#xff0c;代表现代软件开发中通过自动化流程快速、可靠地构建、测试和发布代码的实践。其核心目标是 减少人工干预、…...

代码随想录60期day54

岛屿dfs #include<iostream> #include<vector> using namespace std;int dir[4][2] {0,1,1,0,-1,0,0,-1};void dfs(const vector<vector<int>>&grid,vector<vecotr<bool>>&visited,int x,int y){for(int i 0 ; i < 4; i){in…...

关于easyx头文件

一、窗口创建 &#xff08;1&#xff09;几种创建方式 #include<easyx.h>//easyx的头文件 #include<iostream> using namespace std;int main() {//创建一个500*500的窗口//参数为&#xff1a;长度&#xff0c;宽度&#xff0c;是否显示黑框&#xff08;无参为不…...

Java 中执行命令并使用指定配置文件的最佳实践

在Java开发中&#xff0c;有时需要从Java应用程序中执行系统命令&#xff0c;并使用指定的配置文件来控制这些命令的行为。本文将详细介绍在Java中执行命令并使用指定配置文件的最佳实践&#xff0c;包括如何设置环境变量、重定向输入输出以及处理可能出现的异常。 一、基本实…...

django入门-orm数据库操作

一&#xff1a;下载数据库依赖项mysqlclient pip install mysqlclient 二&#xff1a;django配置文件配置数据库链接 路径&#xff1a;mysite2\mysite2\settings.py DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: data, # 数据库名称USER: root, …...

​​食品电商突围战!品融电商全平台代运营,助您抢占天猫京东抖音红利!

​​食品电商突围战&#xff01;品融电商全平台代运营&#xff0c;助您抢占天猫京东抖音红利&#xff01;​​ ​​一、食品电商的黄金时代&#xff1a;机遇与挑战并存​​ 随着消费升级和线上渗透率的持续攀升&#xff0c;食品行业正迎来前所未有的发展机遇。2023年&#xff…...

Termux下如何使用MATLAB

实际上&#xff0c;termux 目前无法运行MATLAB&#xff0c;但是可以运行MATLAB的平替octave &#xff0c;可以完全在终端环境运行&#xff0c;方便运算和查看模型拟合结果等&#xff0c;完全兼容MATLAB命令。 食用方法&#xff1a; //pkg install wget wget https://its-poin…...

STM32外部中断(EXTI)以及旋转编码器的简介

一、外部中断机制概述 中断是指当主程序执行期间出现特定触发条件&#xff08;即中断源&#xff09;时&#xff0c;CPU将暂停当前任务&#xff0c;转而执行相应的中断服务程序&#xff08;ISR&#xff09;&#xff0c;待处理完成后恢复原程序的运行流程。该机制通过事件驱动…...

双擎驱动:华为云数字人与DeepSeek大模型的智能交互升级方案

一、技术融合概述 华为云数字人 华为云数字人&#xff0c;全称&#xff1a;数字内容生产线 MetaStudio。数字内容生产线&#xff0c;提供数字人视频制作、视频直播、智能交互、企业代言等多种服务能力&#xff0c;使能千行百业降本增效。另外&#xff0c;数字内容生产线&#…...