The fact that SVG is both a “graph” and fully programmable gives it a lot of imagination in web development. In addition to the usual charts, ICONS, etc., there are other interesting places. This article will discuss the application of SVG image compression. Common application scenarios are as follows:

  • High definition vector graphics. Geometric shapes such as logos, ICONS or complex structures composed of geometric shapes are much smaller than JPG or PNG in SVG code text. Microsoft searched for the logo, cn.bing.com/
  • The animation. CSS animation, as far as possible with CSS to do, the need for a lot less code; But there are often some things CSS can’t do, such as path animation. If you use GIF or video, the resources are much larger. This is a good time to use SVG;
  • Use SVG as a “clipping path”, and work with JPEG to achieve a “hollowing” effect. In most cases, this combination will be much smaller than using PNG directly.

The core of this paper is the application of the third scheme.

demand

Activity requirements, develop a feature as shown below

Figure 1: Effect drawing

After each user sweepstakes, they can get a different word. Popover is a reusable component that pulls out the generic UI, which is

Figure 2: Reusable UI

This image is in PNG format and 84K in size. PNG is used because its four corners need to be hollowed out. Our goal is to compress the Png image, for example, into a JPG image, which is much smaller.

Optimize the first wave: mask-image

The PNG image above is large, but it is much smaller in JPG. A JPG of the same size, almost indistinguishable to the naked eye, 29K size, 34 percent of Png. However, it does not support transparency, the four corners can not do hollow effect.

Figure 3: JPG version

At this point you can use the CSS attribute mask-image, which sets the image of the mask layer on the element. Using a mask, you can cut out the parts you don’t need. But it requires an additional mask diagram:

Figure 4: Mask diagram

Because it’s a solid color image, even though it’s PNG, it’s very small, only 3K.

The code is as follows:

.dia{
	background: url(./bg.jpg);
	background-size: 100%;
	-webkit-mask-image: url(./mask.png);
	-webkit-mask-size: 100%;
	mask-image: url(./mask.png);
	mask-size: 100%;
}
Copy the code

The total resource required for this solution is 29+3= 32K, 38% of the original solution. The demo source code

Optimize the second wave: SVG intervention

The above solution is good enough, but there is a more “small” solution: replace mask diagrams with SVG. Since SVG is “pictures,” it can do some of the work of pictures. The mask diagram above is a very simple geometry that can be replaced directly with SVG.

The mask. SVG file contains the following contents:

<svg viewBox="0 0 566 700">
	<path id="baseShape" fill="red" d="M25 0H516a25,25 0 0 0 25,25v650a25,25 0 0 0-25,25 H-650a25,25 0 0 0-25, -25V-650a25,25 0 0, 0-25, -25V-650a25,25 0 0, 0-25, -25V-650a25,25 0 0, 0-25, -25z"></path>
</svg>
Copy the code

Then adjust the content of the CSS file above:

.dia{
	background: url(./bg.jpg);
	background-size: 100%;
	-webkit-mask-image: url(./mask.svg);
	-webkit-mask-size: 100%;
	mask-image: url(./mask.svg);
	mask-size: 100%;
}
Copy the code

After one operation, mask. PNG is no longer needed, a 100-byte SVG file is added, and the resources are slightly reduced. The demo source code

Optimization third wave: Direct drawing of SVG

We have already used SVG, so let’s use SVG to the extreme, and even draw popover backgrounds in SVG.

If you look at Figure 2, you can draw the outline and edges of the background using SVG. (Of course, the middle piece can also be made in SVG, but it is a bit more complicated).

<svg viewBox="0 0 566 700" xmlns="http://www.w3.org/2000/svg">
	<defs>
		<path id="baseShape" d="M25 0H516a25,25 0 0 0 25,25v650a25,25 0 0 0-25,25 H-650a25,25 0 0 0-25, -25V-650a25,25 0 0, 0-25, -25V-650a25,25 0 0, 0-25, -25V-650a25,25 0 0, 0-25, -25z"></path>
	</defs>
	<use id="bg" href="#baseShape" fill="#db3e4a" />
	<use id="line" href="#baseShape" stroke="#e09b6c" fill="transparent" stroke-width="1" x="11" y="11" style="The transform: scale (0.96, 0.97);" />
	<image id="card" x="95" y="78" href="./card.jpg" height="382" width="420"></image>
</svg>
Copy the code

Because the contour and the edge shape are the same, the path is pulled away to make a reusable component. This path is reused for both backgrounds and edges. Then I covered it with the smallest size.

In this way, the final total of resources is 21K. The demo source code

extension

SVG can be embedded directly in HTML inline, in which case:

  • You can share CSS with pages
  • Manipulating the DOM through JS
  • You can directly use vue, React library, easy to display.