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.preview接口中增加cdn的配置:

Vditor.preview(document.getElementById("md-content"), demoMd, {
cdn: window.location.origin, //配置CDN
markdown: {
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. ExtJs 通过分析源代码解决动态加载Controller的问题

    通过分析源代码解决动态加载Controller的问题 最近在研究ExtJs(4.2.0)的MVC开发模式,具体Extjs的MVC如何使用这里不解释,具体参见ExtJs的官方文档.这里要解决的问题是如何 ...

  2. iOS-仿支付宝加载web网页添加进度条

    代码地址如下:http://www.demodashi.com/demo/11727.html 目前市场上APP常会嵌入不少的h5页面,参照支付宝显示web页面的方式, 做了一个导航栏下的加载进度条. ...

  3. .NET混合开发解决方案11 WebView2加载的网页中JS调用C#方法

    系列目录     [已更新最新开发文章,点击查看详细] WebView2控件应用详解系列博客 .NET桌面程序集成Web网页开发的十种解决方案 .NET混合开发解决方案1 WebView2简介 .NE ...

  4. 关于android 加载https网页的问题

    我在加载https网页时出现空白, 因此,我就百度一下,可以发现: webView.setWebViewClient(new WebViewClient(){ @Override public voi ...

  5. 使用jquery的load方法设计动态加载,并解决被加载页面JavaScript失效问题

    一.问题分析 对于后台系统,相比大家都有所印象,知道其中的布局结构,如图: 在这种布局中我们需要将header,sidebar,footer分开,而且对于中间部分的content内容需要动态变化,即根 ...

  6. Scrapy爬取Ajax(异步加载)网页实例——简书付费连载

    这两天学习了Scrapy爬虫框架的基本使用,练习的例子爬取的都是传统的直接加载完网页的内容,就想试试爬取用Ajax技术加载的网页. 这里以简书里的优选连载网页为例分享一下我的爬取过程. 网址为: ht ...

  7. JQuery加载html网页

    在ASP.NET MVC环境中,使用jQuery脚本去实现加载html网页. 一般情况之下,在ASP.NET MVC项目中,你不能在~/Views目录之下添加或是创建任何html为后缀的网页.但这也不 ...

  8. Android:webView加载h5网页视频,播放不了,以及横屏全屏的问题和实现自定义加载进度条的效果

    1.webView加载h5网页视频,播放不了,android3.0之后要在menifest添加硬件加速的属性 android:hardwareAccelerated="true". ...

  9. Django加载静态网页模板

    Django加载静态网页模板 步骤: 第一步:在子系统blog根目录下新建模版目录templates,里面新建一个login.html <!DOCTYPE html> <html l ...

  10. 解决HTML加载时,外部js文件引用较多,影响页面打开速度问题

    解决HTML加载时,外部js文件引用较多,影响页面打开速度问题   通常HTML文件在浏览器中加载时,浏览器都会按照<script>元素在页面中出现的先后顺序,对它们依次加载,一旦加载的j ...

随机推荐

  1. 【自编RSG插件】梁结构生成插件QGToolBox

    正在学习基于ABAQUS-PYTHON的GUI开发,出于练手的想法,编写了一个简单的插件. 实现功能: 基于nodes. rods的table,完成桁架结构的几何建模. GUI界面: RSG Buil ...

  2. windows使用Makefile时自动给可执行文件加上.exe后缀

    APP := main 在使用makefile的时候,一般通过变量设置自己想要编译出来的可执行文件的名字 在windows平台编译出来的可执行文件是需要.exe后缀的 识别当前操作系统 通过识别当前的 ...

  3. vuepress-reco搭建与部署指南

    个人博客:槿苏的知识铺 一.前言   在技术飞速发展的今天,高效地编写.维护和呈现文档已成为开发者不可或缺的能力.无论是开源项目.团队协作还是个人知识沉淀,一套结构清晰.体验优雅的文档系统都能显著提升 ...

  4. Ubuntu安装GPU驱动+CUDA+cuDNN的安装方法

    一台有GPU的虚拟机如果没有安装CUDA的驱动,是需要我们手动去进行安装的,介绍Ubuntu操作系统的安装教程. 1. 下载安装文件 NVIDIA CUDA Toolkit Archive 点击上面链 ...

  5. 多态的前提--java进阶day02

    1.多态的前提条件 第一点和第二点都很好理解,第三点父类引用指向子类对象是什么意思?以下图进行讲解 我们以前的写法,如下图,叫做子类引用指向子类 那父类引用呢?就是把左边换成父类Animal即可 因为 ...

  6. java的数据类型之基本类型

    强类型语言 要求变量的使用要严格符合规定,所有变量都必须先定义后使用.如果没有按照指定要求使用变量,则该变量将报错.java就是强类型语言. java的两大数据类型 1.基本类型 2.引用类型 其中基 ...

  7. 超简单电脑本地部署deepseek,另附”一键使用脚本“撰写与联网使用方法

    在电脑上部署deepseek,总共分三步 1.打开ollama官网点击Download按钮 2.在ollama官网搜索deepseek-r1模型,选择对应规模,并复制ollama命令,比如这里,我的o ...

  8. 关于TFDMemtable的使用场景【3】处理数据

    原因很多: 1.通过TFDMemtable处理数据时,避免影响数据感知 2.处理速度很快. ------------------------------ 从Tdataset读取数据: Procedur ...

  9. 太赞了!两个技巧帮你记住复杂 Linux 命令!

    Linux 经历这么多个年头了,其中命令越来越多,又加上参数的多种多样,就算是实打实的高手也没有十足的把握能把各种命令运用得炉火纯青,就别说那些初学者了. 面对这些复杂难记的命令,网上的一些工具如 K ...

  10. 探秘Transformer系列之(25)--- KV Cache优化之处理长文本序列

    探秘Transformer系列之(25)--- KV Cache优化之处理长文本序列 目录 探秘Transformer系列之(25)--- KV Cache优化之处理长文本序列 0x00 概述 0x0 ...