优秀的编程知识分享平台

网站首页 > 技术文章 正文

最小化包含内联CSS和HTML的自定义元素

nanyue 2024-10-21 06:19:52 技术文章 28 ℃

在本文中,我们看看开发人员使用JavaScript和正则表达式在他的网站上缩小元素的过程。阅读更多!

我创建了一个ShareButton Web组件,虽然效果并不好,但我喜欢它,并在创建Web组件时了解了很多关于Web组件的生态系统。

这个项目的主要目标是将所有内容封装在一个ES6类中。我这样做是因为我不想从我的元素发出任何非开发人员控制的Web请求。我认为我已经实现了这个目标,但是代码的可读性受损,因为我不得不内联定义元素的HTML和CSS。

它看起来很像这样:

const overlay = document.createElement('div');

overlay.id = 'overlay';

overlay.innerHTML = `

<div id="urlbar">

<input type="url" id="url" />

<button id="copy" aria-label="Copy to clipboard">

<slot name="clipboard">

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">

<path fill="none" d="M0 0h24v24H0z"/>

<path d="M16 1H4C3 1 2 2 2 3v14h2V3h12V1zm3 4H8C7 5 6 6 6 7v14c0 1 1 2 2 2h11c1 0 2-1 2-2V7c0-1-1-2-2-2zm0 16H8V7h11v14z"/>

</svg>

</slot>

</button>

<button id="mailto" aria-lable="Mail to">

<slot name="mailto">

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">

<path fill="none" d="M0 0h24v24H0z"/>

<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 id="android" aria-label="Share on Android">

<slot name="android">

<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">

<path fill="none" d="M0 0h24v24H0z"/>

<path d="M6 18c0 .6.5 1 1 1h1v3.5c0 .8.7 1.5 1.5 1.5s1.5-.7 1.5-1.5V19h2v3.5c0 .8.7 1.5 1.5 1.5s1.5-.7 1.5-1.5V19h1c.6 0 1-.5 1-1V8H6v10zM3.5 8C2.7 8 2 8.7 2 9.5v7c0 .8.7 1.5 1.5 1.5S5 17.3 5 16.5v-7C5 8.7 4.3 8 3.5 8zm17 0c-.8 0-1.5.7-1.5 1.5v7c0 .8.7 1.5 1.5 1.5s1.5-.7 1.5-1.5v-7c0-.8-.7-1.5-1.5-1.5zm-5-5.8L16.8 1c.2-.3.2-.6 0-.8-.2-.2-.5-.2-.7 0l-1.3 1.4C13.7 1.2 13 1 12 1c-1 0-2 .2-2.7.6L7.8 0H7v1l1.5 1C7 3.2 6 5 6 7h12c0-2-1-3.8-2.5-4.8zM10 5H9V4h1v1zm5 0h-1V4h1v1z"/>

</svg>

</slot>

</button>

</div>

<div class="buttons">

<slot name="buttons"></slot>

</div>`;

这并不坏,但这也意味着我的元素不可能被最大限度地缩小。事实上,除了聚合物工具(专注于解析HTML导入)之外,我找不到任何有关部署经过优化的自定义元素(如果我错了,请告诉我)的工具或指导。

我不认为作为一名元素作者,我应该将整个构建链和工具生态系统强加给我的元素用户。我也相信我应该能够为用户提供尽可能小的内置文件,为用户提供默认的快速体验,而无需跳过这些环节。

我不希望任何超级复杂的基础架构将单独的CSS和JS文件合并到一个输出中; 我只想让自定义元素的开发版本与我部署的版本完全相同......只是更小。

我希望通过这篇文章,至少你可以看到我的过程,并了解我如何缩小我的自定义元素。

压缩ES6类

我用过babili。这是一个压缩ES6类的非常整洁的工具。它仍然是试验性的,但我没有遇到任何重大问题。

npm install babili --save-dev

您可以通过许多不同的方式运行它,我选择通过STDOUT将数据传输到它。

cat xyz | babili

这很有效,但它将字符串留下,因为它假定(正确)这些字符串的输出和格式是有意的。如果我想让元素尽可能小,那么我需要缩小嵌入到元素中的CSS和HTML。

那么你如何解决这样的问题呢?

我选择了打破压缩HTML并将CSS压缩成两个额外步骤的问题。

压缩内联CSS

我无法轻松找出一种可扩展的方式来推断字符串是CSS,并且需要压缩,所以我上了旧学校并复制了我在Google Web Starter Kit中看到的一些东西 - 自定义标记,用于定义需要的东西被处理。

自定义标记只是浏览器忽略的普通注释,但是缩小器也会被删除。

我编写了这个简单的脚本,它从STDIN中读取,加载整个文件,然后查找自定义注释,然后使用简单的正则表达式在运行替换函数之前查找注释和内容,然后再打印整个输出回STDOUT。

它包括clean-css,它似乎会做的伎俩。

const CleanCSS = require('clean-css');

const process = require('process');

let input = '';

process.stdin.on('readable', () => {

let chunk = process.stdin.read();

if(chunk != null) input += chunk;

})

process.stdin.on('end', () => {

let cssRe = /\/\*compress\*\/(.|[\n\r])+?\/\*endcompress\*\//;

let compressedOutput = input.replace(cssRe, (match, p1, offset, string) => {

let output = new CleanCSS({}).minify(match);

return output.styles;

});

process.stdout.write(compressedOutput);

process.exit();

});

我不得不加强我的内联CSS /*compress*/和/*endcompress*/注释,这对于任何阅读源代码的开发人员来说都可能有点混乱,但它确实给了我很大的灵活性。

压缩内联HTML

我为HTML缩小做了完全相同的事情。这个html-minifier软件包非常整齐,我玩弄了一些理想的默认设置,运行良好。

const minify = require('html-minifier').minify;

const process = require('process');

let input = '';

process.stdin.on('readable', () => {

let chunk = process.stdin.read();

if(chunk != null) input += chunk;

})

process.stdin.on('end', () => {

let cssRe = /<!--compress-->(.|[\n\r])+?<!--endcompress-->/;

let compressedOutput = input.replace(cssRe, (match, p1, offset, string) => {

return minify(match, { removeAttributeQuotes: true, removeComments: true, collapseWhitespace: true });

});

process.stdout.write(compressedOutput);

process.exit();

});

连接在一起

共享按钮具有build压缩CSS和HTML 的自定义脚本,最后它执行ES6缩小操作,并确保用于分发和包含的文件尽可能小。

"scripts": {

"build": "cat share-button.js | node build/compress-css.js | node build/compress-html.js | babili > dist/share-button.min.js"

}

将它整合到我的博客中

我打算写一篇关于部署Web组件的咆哮,但最后它非常简单。

1.从我的项目中安装元素。

npm install sharebutton --save

2.将它添加到我的构建部署中。

install:

- npm install

- cp node_modules/sharebutton/dist/share-button.min.js static/javascripts/share-button.js

下一步是什么?

我认为这是值得的。该元素现在是7917字节与11700字节,大约减小了33%(gzip,与2742比较是2792字节),所以我现在很高兴(尽管我认为我可以做得更好)。我现在也有一个可以用于其他元素的进程,并且所有内容都封装在这个包中。

我支持自己进入一个角落,选择内联CSS和HTML,但我仍然认为这是构建自定义元素的最佳解决方案。

这里介绍的解决方案将在缩小元素方面做得很好,但是它不会做得很好,例如,因为自定义元素对外部元素不透明,所以我可以在缩小CSS选择器,ID等方面做得更好。 。但CSS,HTML和JS没有足够的耦合度,足以让我有信心做到这一点。

我很乐意在这个过程中得到你的想法,如果你做了类似的事情,并有更好的结果。

Tags:

最近发表
标签列表