服务器主节点,子节点
在Express应用程序中实现Highlight.js,以实现超快速的预渲染代码突出显示
我们正在建设
一个简单的服务器端Node / Express代码,可将Markdown内容转换为带有突出显示的代码块的完全格式化HTML。
我们使用的技术
Markdown是一种轻量级的标记语言,具有纯文本格式语法。 它的设计允许将其转换为多种输出格式。
Highlight.js是用JavaScript编写的语法突出显示工具。 它既可以在浏览器中也可以在服务器上使用。 它几乎可以与任何标记一起使用,不依赖于任何框架,并且具有自动语言检测功能。
统一是一个友好的界面,由为创建和处理内容而构建的插件生态系统支持。
统一插件: remark-parse , remark-rehype , rehype-stringify , rehype-highlight
为什么要使用服务器端代码突出显示?
在Regbrain,我们决定实施服务器端代码突出显示功能,以延长主网站的加载时间。 我们不断以Lighthouse为基准对我们的网站进行基准测试,并争取获得最佳性能得分。
加载JavaScript以在浏览器中突出显示代码需要花费太多时间。 首先,必须提取JavaScript文件,然后浏览器重新粉刷内容,从而导致网站速度变慢。 为了提高速度,我们决定在服务器上实现代码突出显示,现在我们将完全格式化的html发送到浏览器。
此时,您可能想知道, 突出显示代码服务器端的性能如何? 稍后,我们将更详细地探讨这一点,但首先,让我们逐步了解我们的技术解决方案。
服务器端代码突出显示
我们的文章是用markdown编写的,因此我们的工作流需要将原始markdown用作输入并提供完全格式化的html。 我们按照以下步骤进行操作:
1.获取降价内容
2.使用remark-parse将markdown转换为markdown语法树
3.使用remark-rehype将markdown语法树转换为html语法树
4.遍历html语法树以使用rehype-highlight将代码突出显示应用于<code>标记内的内容
5.使用rehype-stringify将html语法树转换为字符串以发送到客户端
我们使用统一的框架和插件实现了上述所有目标,如下所示:
导入所需的库
我们获取统一的框架和所需的插件
let unified = require ( 'unified' )
let markdown = require ( 'remark-parse' )
let remark2rehype = require ( 'remark-rehype' )
let highlight = require ( 'rehype-highlight' )
let html = require ( 'rehype-stringify' )
创建一个统一的处理器
我们创建一个处理器,将上述所有插件整合在一起,以实现从markdown到完全突出显示的html的转换链:
let processor = unified()
// Transform markdown into a markdown syntax tree
.use(markdown)
// Transform markdown syntax tree to html syntax tree
.use(remark2rehype)
// Traverse html syntax tree to apply code highlighting to content within code tags
.use(highlight)
// Transform html syntax tree to string to send to the client
.use(html)
转变!
现在,我们有了可以解析任何降价输入的处理器 ,如下所示:
let input = some markdown content
let output = await processor.process(input)
Express JS路由器实施示例
我们在Express应用中执行上述步骤,如下所示:
let express = require ( 'express' )
let router = express.Router()
let unified = require ( 'unified' )
let markdown = require ( 'remark-parse' )
let remark2rehype = require ( 'remark-rehype' )
let html = require ( 'rehype-stringify' )
let highlight = require ( 'rehype-highlight' )
router.get( '/:slug' , async function ( req, res, next ) {
let input = await article.from.database.in.markdown()
let processor = unified()
.use(markdown)
.use(remark2rehype)
.use(highlight)
.use(html)
let output = await processor.process(input)
res.render( 'article' , output)
})
module .exports = router
不要忘记CSS
我们需要做的最后一件事是在页面上包含突出显示CSS样式。 最简单的方法是将它们简单地链接为外部样式,但是由于获取外部样式会阻止页面呈现,因此这会损害我们的网站加载速度。 为了避免性能下降,我们将所有css作为内部样式包含在页面上。
<!doctype html>< html >
<head>
<style>
{all page's style including highlightjs css}
</style>
</head>
<body>
</body>
</ html >
再谈性能问题
我们如何使服务器端渲染性能更好? 即使上面的代码突出显示与发送“干净的” html相比,服务器速度有所降低,我们仍在下面实现了许多其他层,这使我们可以实现出色的页面加载速度:
AMP-默认情况下,我们将主要内容作为AMP页面提供。 这意味着Google和Bing可以缓存我们的页面并在移动设备上真正快速地提供它。
没有外部样式或JavaScript(异步AMP除外) -我们不使用任何阻塞的外部资源,例如样式,图像或JavaScript文件。 遵循AMP规范已经强制执行此操作,但是即使我们未实现AMP,这也是提高页面加载速度的好方法。 我们所有CSS都是内部的。 我们准备CSS服务器端,并使其特定于我们要避免的内容类型,以避免包括未使用的样式(...在合理范围内...)。
缩小 -我们使用css和html缩小来进一步减小页面的大小。
CDN-我们使用全球内容分发网络并配置我们的HTTP标头以获得CDN缓存的好处 ,我们还为CDN配置资产压缩。
通过上面的设置,我们可以在最小的AWS EC2实例上甚至服务十个Express应用程序,与分别托管单个应用程序作为服务的多种选择相比,这确实具有成本吸引力。
翻译自: https://hackernoon.com/server-side-code-highlighting-in-node-4f10h4289
服务器主节点,子节点