diff --git a/server/modules/rendering/html-core/renderer.js b/server/modules/rendering/html-core/renderer.js
index a1f3690f..33cf949e 100644
--- a/server/modules/rendering/html-core/renderer.js
+++ b/server/modules/rendering/html-core/renderer.js
@@ -24,7 +24,7 @@ module.exports = {
for (let child of _.reject(this.children, ['step', 'post'])) {
const renderer = require(`../${_.kebabCase(child.key)}/renderer.js`)
- renderer.init($, child.config)
+ await renderer.init($, child.config)
}
// --------------------------------
diff --git a/server/modules/rendering/html-image-prefetch/definition.yml b/server/modules/rendering/html-image-prefetch/definition.yml
new file mode 100644
index 00000000..bf7a65df
--- /dev/null
+++ b/server/modules/rendering/html-image-prefetch/definition.yml
@@ -0,0 +1,8 @@
+key: htmlImagePrefetch
+title: Image Prefetch
+description: Prefetch remotely rendered images (korki/plantuml)
+author: requarks.io
+icon: mdi-cloud-download-outline
+enabledDefault: false
+dependsOn: htmlCore
+props: {}
diff --git a/server/modules/rendering/html-image-prefetch/renderer.js b/server/modules/rendering/html-image-prefetch/renderer.js
new file mode 100644
index 00000000..12733e3a
--- /dev/null
+++ b/server/modules/rendering/html-image-prefetch/renderer.js
@@ -0,0 +1,30 @@
+const request = require('request-promise')
+
+const prefetch = async (element) => {
+ const url = element.attr(`src`)
+ let response
+ try {
+ response = await request({
+ method: `GET`,
+ url,
+ resolveWithFullResponse: true
+ })
+ } catch (err) {
+ WIKI.logger.warn(`Failed to prefetch ${url}`)
+ WIKI.logger.warn(err)
+ return
+ }
+ const contentType = response.headers[`content-type`]
+ const image = Buffer.from(response.body).toString('base64')
+ element.attr('src', `data:${contentType};base64,${image}`)
+ element.removeClass('prefetch-candidate');
+}
+
+module.exports = {
+ async init($) {
+ const promises = $('img.prefetch-candidate').map((index, element) => {
+ return prefetch($(element))
+ }).toArray()
+ await Promise.all(promises)
+ }
+}
diff --git a/server/modules/rendering/markdown-kroki/renderer.js b/server/modules/rendering/markdown-kroki/renderer.js
index 0b10c2ae..f066bf4c 100644
--- a/server/modules/rendering/markdown-kroki/renderer.js
+++ b/server/modules/rendering/markdown-kroki/renderer.js
@@ -120,7 +120,7 @@ module.exports = {
token = state.push('kroki', 'img', 0)
// alt is constructed from children. No point in populating it here.
- token.attrs = [ [ 'src', `${server}/${diagramType}/svg/${result}` ], [ 'alt', '' ], ['class', 'uml-diagram'] ]
+ token.attrs = [ [ 'src', `${server}/${diagramType}/svg/${result}` ], [ 'alt', '' ], ['class', 'uml-diagram prefetch-candidate'] ]
token.block = true
token.children = altToken
token.info = params
diff --git a/server/modules/rendering/markdown-plantuml/renderer.js b/server/modules/rendering/markdown-plantuml/renderer.js
index 10ee0479..62a56a7a 100644
--- a/server/modules/rendering/markdown-plantuml/renderer.js
+++ b/server/modules/rendering/markdown-plantuml/renderer.js
@@ -116,7 +116,7 @@ module.exports = {
token = state.push('uml_diagram', 'img', 0)
// alt is constructed from children. No point in populating it here.
- token.attrs = [ [ 'src', `${server}/${imageFormat}/${zippedCode}` ], [ 'alt', '' ], ['class', 'uml-diagram'] ]
+ token.attrs = [ [ 'src', `${server}/${imageFormat}/${zippedCode}` ], [ 'alt', '' ], ['class', 'uml-diagram prefetch-candidate'] ]
token.block = true
token.children = altToken
token.info = params