img 加載 svg占位符
by José M. Pérez
由JoséM.Pérez
如何使用SVG作為占位符以及其他圖像加載技術 (How to use SVG as a Placeholder, and Other Image Loading Techniques)
I’m passionate about image performance optimisation and making images load fast on the web. One of the most interesting areas of exploration is placeholders: what to show when the image hasn’t loaded yet.
我對圖像性能優化和使圖像快速加載到網絡上充滿熱情。 探索最有趣的領域之一是占位符:尚未加載圖像時顯示的內容。
During the last days I have come across some loading techniques that use SVG, and I would like to describe them in this post.
在最后幾天,我遇到了一些使用SVG的加載技術,我想在這篇文章中對其進行描述。
In this post we will go through these topics:
在本文中,我們將介紹以下主題:
- Overview of different types of placeholders 不同類型的占位符概述
- SVG-based placeholders (edges, shapes and silhouettes) 基于SVG的占位符(邊緣,形狀和輪廓)
- Automating the process. 自動化過程。
不同類型的占位符概述 (Overview of different types of placeholders)
In the past I have written about placeholders and lazy-load of images, and also talked about it. When doing lazy-loading of images it’s a good idea to think about what to render as a placeholder, since it can have a big impact in user’s perceived performance. In the past I described several options:
過去, 我寫過關于占位符和圖像的延遲加載的文章 ,并且也對此進行了討論 。 在進行圖像的延遲加載時,考慮作為占位符呈現什么是一個好主意,因為它可能會對用戶的感知性能產生很大的影響。 過去,我描述了幾種選擇:
Several strategies to fill the area of an image before it loads.
在加載圖像之前填充圖像區域的幾種策略。
Keeping the space empty for the image: In a world of responsive design, this prevents content from jumping around. Those layout changes are bad from a user’s experience point of view, but also for performance. The browser is forced to do layout re calculations every time it fetches the dimensions of an image, leaving space for it.
保留圖像的空白空間 :在響應快速的設計世界中,這可以防止內容跳來跳去。 從用戶體驗的角度來看,這些布局更改是不好的,而且對于性能而言也是如此。 瀏覽器每次獲取圖像尺寸時都必須進行布局重新計算,從而留出空間。
Placeholder: Imagine that we are displaying a user’s profile image. We might want to display a silhouette in the background. This is shown while the main image is loaded, but also when that request failed or when the user didn’t set any profile picture at all. These images are usually vector-based, and due to their small size are a good candidate to be inlined.
占位符 :假設我們正在顯示用戶的個人資料圖像。 我們可能要在背景中顯示一個剪影。 在加載主圖像時,請求失敗或用戶根本沒有設置任何個人資料圖片時,都會顯示此內容。 這些圖像通常基于矢量,并且由于其較小的尺寸,因此很適合內聯。
Solid colour: Take a colour from the image and use it as the background colour for the placeholder. This can be the dominant colour, the most vibrant… The idea is that it is based on the image you are loading and should help making the transition between no image to image loaded smoother.
純色 :從圖像中獲取顏色,并將其用作占位符的背景色。 這可能是占主導地位的顏色,也是最鮮艷的顏色……其想法是,它基于您正在加載的圖像,并且應該有助于使無圖像到圖像加載之間的過渡更加平滑。
Blurry image: Also called blur-up technique. You render a tiny version of the image and then transition to the full one. The initial image is tiny both in pixels and kBs. To remove artifacts the image is scaled up and blurred. I have written previously about this on How Medium does progressive image loading, Using WebP to create tiny preview images, and More examples of Progressive Image Loading .
模糊圖像 :也稱為模糊技術。 您渲染圖像的一個很小的版本,然后過渡到完整版本。 初始圖像的像素和kBs都很小。 要消除偽影,請按比例放大和模糊圖像。 我之前已經寫過有關媒介如何進行漸進式圖像加載 , 使用WebP創建微小的預覽圖像以及更多漸進式圖像加載示例的文章 。
Turns out there are many other variations and lots of smart people are developing other techniques to create placeholders.
事實證明,還有許多其他變體,許多聰明人正在開發其他技術來創建占位符。
One of them is having gradients instead of solid colours. The gradients can create a more accurate preview of the final image, with very little overhead (increase in payload).
其中之一是使用漸變色而不是純色。 漸變可以創建最終圖像的更準確的預覽,而開銷很少(有效負載增加)。
Another technique is using SVGs based on the image, which is getting some traction with recent experiments and hacks.
另一種技術是基于圖像使用SVG,這在最近的實驗和黑客攻擊中獲得了一定的吸引力。
基于SVG的占位符 (SVG-based placeholders)
We know SVGs are ideal for vector images. In most cases we want to load a bitmap one, so the question is how to vectorise an image. Some options are using edges, shapes and areas.
我們知道SVG非常適合矢量圖像。 在大多數情況下,我們希望加載一個位圖,因此問題是如何對圖像進行矢量化處理。 一些選項使用邊緣,形狀和區域。
邊緣 (Edges)
In a previous post I explained how to find out the edges of an image and create an animation. My initial goal was to try to draw regions, vectorising the image, but I didn’t know how to do it. I realised that using the edges could also be innovative and I decided to animate them creating a “drawing” effect.
在上一篇文章中,我解釋了如何找出圖像的邊緣并創建動畫。 我的最初目標是嘗試繪制區域,對圖像進行矢量化處理,但我不知道該怎么做。 我意識到使用邊緣也可能是創新的,因此我決定對它們進行動畫處理,以產生“繪畫”效果。
Drawing images using edge detection and SVG animationBack in the days SVG was barely used and supported. Some time after we started using them as an alternative to classic…medium.com
使用邊緣檢測和SVG動畫繪制圖像 在過去,SVG幾乎沒有被使用和支持。 在我們開始將它們用作經典替代品之后的一段時間。
形狀 (Shapes)
SVG can also be used to draw areas from the image instead of edges/borders. In a way, we would vectorise a bitmap image to create a placeholder.
SVG還可以用于從圖像而不是邊緣/邊界繪制區域。 在某種程度上,我們將對位圖圖像進行矢量化處理以創建占位符。
Back in the days I tried to do something similar with triangles. You can see the result in my talks at CSSConf and Render Conf.
過去,我曾嘗試對三角形進行類似的處理。 您可以在CSSConf和Render Conf的演講中看到結果。
The codepen above is a proof of concept of a SVG-based placeholder composed of 245 triangles. The generation of the triangles is based on Delaunay triangulation using Possan’s polyserver. As expected, the more triangles the SVG uses, the bigger the file size.
上面的代碼筆是對由245個三角形組成的基于SVG的占位符的概念證明。 三角形的生成基于Possan的polyserver的 Delaunay三角剖分 。 如預期的那樣,SVG使用的三角形越多,文件大小越大。
Primitive和SQIP,一種基于SVG的LQIP技術 (Primitive and SQIP, a SVG-based LQIP technique)
Tobias Baldauf has been working on another Low-Quality Image Placeholder technique using SVGs called SQIP. Before digging into SQIP itself I will give an overview of Primitive, a library on which SQIP is based.
Tobias Baldauf一直在研究另一種使用稱為SQIP的SVG的低質量圖像占位符技術。 在深入研究SQIP本身之前,我將概述Primitive ,這是SQIP所基于的庫。
Primitive is quite fascinating and I definitely recommend you to check it out. It converts a bitmap image into a SVG composed of overlapping shapes. Its small size makes it suitable for inlining it straight into the page. One less roundtrip, and a meaningful placeholder within the initial HTML payload.
Primitive非常吸引人,我絕對建議您檢查一下。 它將位圖圖像轉換為由重疊形狀組成的SVG。 它的小尺寸使其適合直接插入頁面。 往返次數減少了一個,并且在初始HTML有效負載中具有有意義的占位符。
Primitive generates an image based on shapes like triangles, rectangles and circles (and a few others). In every step it adds a new one. The more steps, the resulting image looks closer to the original one. If your output is SVG it also means the size of the output code will be larger.
圖元基于三角形,矩形和圓形(以及其他一些形狀)生成圖像。 在每一步中,它都會添加一個新的。 步驟越多,生成的圖像看起來就越接近原始圖像。 如果您的輸出是SVG,這也意味著輸出代碼的大小將更大。
In order to understand how Primitive works, I ran it through a couple of images. I generated SVGs for the artwork using 10 shapes and 100 shapes:
為了了解Primitive的工作原理,我通過幾個圖像對其進行了介紹。 我使用10種形狀和100種形狀為藝術品生成了SVG:
When using 10 shapes the images we start getting a grasp of the original image. In the context of image placeholders there is potential to use this SVG as the placeholder. Actually, the code for the SVG with 10 shapes is really small, around 1030 bytes, which goes down to ~640 bytes when passing the output through SVGO.
當使用10個形狀的圖像時,我們開始掌握原始圖像。 在圖像占位符的上下文中,有可能使用此SVG作為占位符。 實際上,具有10種形狀的SVG的代碼確實很小,大約1030字節,當通過SVGO傳遞輸出時,該代碼減少到640字節左右。
<svg xmlns=”http://www.w3.org/2000/svg" width=”1024" height=”1024"><path fill=”#817c70" d=”M0 0h1024v1024H0z”/><g fill-opacity=”.502"><path fill=”#03020f” d=”M178 994l580 92L402–62"/><path fill=”#f2e2ba” d=”M638 894L614 6l472 440"/><path fill=”#fff8be” d=”M-62 854h300L138–62"/><path fill=”#76c2d9" d=”M410–62L154 530–62 38"/><path fill=”#62b4cf” d=”M1086–2L498–30l484 508"/><path fill=”#010412" d=”M430–2l196 52–76 356"/><path fill=”#eb7d3f” d=”M598 594l488–32–308 520"/><path fill=”#080a18" d=”M198 418l32 304 116–448"/><path fill=”#3f201d” d=”M1086 1062l-344–52 248–148"/><path fill=”#ebd29f” d=”M630 658l-60–372 516 320"/></g></svg>
The images generated with 100 shapes are larger, as expected, weighting ~5kB after SVGO (8kB before). They have a great level of detail with a still small payload. The decision of how many triangles to use will depend largely on the type of image (eg contrast, amount of colours, complexity) and level of detail.
如預期的那樣,使用100個形狀生成的圖像較大,在SVGO之后權重約為5kB(之前為8kB)。 它們的細節水平很高,有效載荷仍然很小。 使用多少個三角形的決定將在很大程度上取決于圖像的類型(例如,對比度,顏色數量,復雜性)和細節級別。
It would be possible to create a script similar to cpeg-dssim that tweaks the amount of shapes used until a structural similarity threshold is met (or a maximum number of shapes in the worst case).
可以創建類似于cpeg-dssim的腳本,該腳本可調整使用的形狀數量,直到滿足結構相似性閾值(或在最壞的情況下,最大數量的形狀)。
These resulting SVGs are great also to use as background images. Being size-constrained and vector-based they are a good candidate for hero images and large backgrounds that otherwise would show artifacts.
這些生成的SVG也非常適合用作背景圖像。 由于尺寸受限制且基于矢量,因此它們是英雄圖像和大背景(否則會顯示偽影)的理想選擇。
品質保證計劃 (SQIP)
In Tobias’ own words:
用托比亞斯自己的話說 :
SQIP is an attempt to find a balance between these two extremes: it makes use of Primitive to generate a SVG consisting of several simple shapes that approximate the main features visible inside the image, optimizes the SVG using SVGO and adds a Gaussian Blur filter to it. This produces a SVG placeholder which weighs in at only ~800–1000 bytes, looks smooth on all screens and provides an visual cue of image contents to come.
SQIP試圖在這兩個極端之間找到平衡:它使用基本體生成由幾個簡單形狀組成的SVG,這些形狀近似于圖像內部可見的主要特征,使用SVGO優化SVG并為其添加高斯模糊濾鏡。 這樣就產生了一個SVG占位符,該占位符僅重約800-1000字節,在所有屏幕上看起來都很平滑,并提供了即將出現的圖像內容的可視提示。
The result is similar to using a tiny placeholder image for the blur-up technique (what Medium and other sites do). The difference is that instead of using a bitmap image, eg JPG or WebP, the placeholder is SVG.
結果類似于使用微小的占位符圖像進行模糊處理( Medium和其他站點執行的操作)。 區別在于,占位符是SVG,而不是使用位圖圖像(例如JPG或WebP)。
If we run SQIP against the original images we’ll get this:
如果我們對原始圖像運行SQIP,則會得到以下信息:
The output SVG is ~900 bytes, and inspecting the code we can spot the feGaussianBlur
filter applied to the group of shapes:
輸出的SVG約為900字節,通過檢查代碼,我們可以發現應用于形狀組的feGaussianBlur
濾波器:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 2000"><filter id="b"><feGaussianBlur stdDeviation="12" /></filter><path fill="#817c70" d="M0 0h2000v2000H0z"/><g filter="url(#b)" transform="translate(4 4) scale(7.8125)" fill-opacity=".5"><ellipse fill="#000210" rx="1" ry="1" transform="matrix(50.41098 -3.7951 11.14787 148.07886 107 194.6)"/><ellipse fill="#eee3bb" rx="1" ry="1" transform="matrix(-56.38179 17.684 -24.48514 -78.06584 205 110.1)"/><ellipse fill="#fff4bd" rx="1" ry="1" transform="matrix(35.40604 -5.49219 14.85017 95.73337 16.4 123.6)"/><ellipse fill="#79c7db" cx="21" cy="39" rx="65" ry="65"/><ellipse fill="#0c1320" cx="117" cy="38" rx="34" ry="47"/><ellipse fill="#5cb0cd" rx="1" ry="1" transform="matrix(-39.46201 77.24476 -54.56092 -27.87353 219.2 7.9)"/><path fill="#e57339" d="M271 159l-123–16 43 128z"/><ellipse fill="#47332f" cx="214" cy="237" rx="242" ry="19"/></g></svg>
SQIP can also output an image tag with the SVG contents Base 64 encoded:
SQIP還可以輸出帶有SVG內容Base 64編碼的圖像標簽:
<img width="640" height="640" src="example.jpg” alt="Add descriptive alt text" style="background-size: cover; background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAw…<stripped base 64>…PjwvZz48L3N2Zz4=);">
剪影 (Silhouettes)
We just had a look at using SVGs for edges and primitive shapes. Another possibility is to vectorise the images “tracing” them. Mikael Ainalem shared a codepen a few days ago showing how to use a 2-colour silhouette as a placeholder. The result is really pretty:
我們只是看看如何將SVG用于邊緣和原始形狀。 另一種可能性是矢量化圖像以“跟蹤”它們。 Mikael Ainalem幾天前分享了一個Codepen,展示了如何使用2色輪廓作為占位符。 結果非常漂亮:
The SVGs in this case were hand drawn, but the technique quickly spawned integrations with tools to automate the process.
在這種情況下,SVG是手工繪制的,但是該技術很快催生了與工具的集成,以使過程自動化。
Gatsby, a static site generator using React supports these traced SVGs now. It uses a JS PORT of potrace to vectorise the images.
Gatsby是使用React的靜態站點生成器,現在支持這些跟蹤的SVG。 它使用potrace的JS PORT對圖像進行矢量化。
Craft 3 CMS, which also added support for silhouettes. It uses a PHP port of potrace.
Craft 3 CMS ,還增加了對輪廓的支持。 它使用potracePHP端口 。
image-trace-loader, a Webpack loader that uses potrace to process the images.
image-trace-loader ,一個Webpack加載器,使用potrace處理圖像。
It’s also interesting to see a comparison of the output between Emil’s webpack loader (based on potrace) and Mikael’s hand-drawn SVGs.
看到Emil的webpack loader(基于potrace)和Mikael的手繪SVG之間的輸出比較也很有趣。
I assume the output generated by potrace is using the default options. However, it’s possible to tweak them. Check the options for image-trace-loader, which are pretty much the ones passed down to potrace.
我假設potrace生成的輸出使用默認選項。 但是,可以對其進行調整。 檢查image-trace-loader的選項,這些選項幾乎是傳遞給potrace的選項 。
摘要 (Summary)
We have seen different tools and techniques to generate SVGs from images and use them as placeholders. The same way WebP is a fantastic format for thumbnails, SVG is also an interesting format to use in placeholders. We can control the level of detail (and thus, size), it’s highly compressible and easy to manipulate with CSS and JS.
我們已經看到了用于從圖像生成SVG并將其用作占位符的不同工具和技術。 與WebP是用于縮略圖的奇妙格式一樣 ,SVG也是在占位符中使用的有趣格式。 我們可以控制細節級別(從而控制大小),它的高度可壓縮性并且易于使用CSS和JS進行操作。
額外資源 (Extra Resources)
This post made it to the top of Hacker News. I’m very grateful for that, and for all the links to other resources that have been shared in the comments on that page. Here are a few of them!
這篇文章登上了Hacker News的頂部 。 對此,以及該頁面評論中共享的其他資源的所有鏈接,我深表感謝。 這里有幾個!
Geometrize is a port of Primitive written in Haxe. There is also a JS implementation that you can try out directly on your browser.
Geometrize是用Haxe編寫的Primitive的一部分。 還有一個JS實現 ,您可以直接在瀏覽器上試用。
Primitive.js, which is a port of Primitive in JS. Also, primitive.nextgen, which is a port of the Primitive desktop app using Primitive.js and Electron.
Primitive.js ,它是JS中Primitive的一部分。 另外, primary.nextgen ,它是使用Primitive.js和Electron的Primitive桌面應用程序的端口。
There are a couple of Twitter accounts where you can see examples of images generated with Primitive and Geometrize. Check out @PrimitivePic and @Geometrizer.
有幾個Twitter帳戶,您可以在其中查看使用Primitive和Geometrize生成的圖像的示例。 查看@PrimitivePic和@Geometrizer 。
imagetracerjs, which is a raster image tracer and vectorizer written in JavaScript. There are also ports for Java and Android.
imagetracerjs ,這是用JavaScript編寫的光柵圖像跟蹤器和矢量化器。 還有用于Java和Android的端口。
Canvas-Graphics, a partial implementation of the JS Canvas API in PHP around GD.
Canvas-Graphics ,是GD中PHP的JS Canvas API的部分實現。
相關文章 (Related Posts)
If you have enjoyed this post, check out these other posts I have written about techniques loading images:
如果您喜歡這篇文章,請查看我寫的有關加載圖像技術的其他文章:
How Medium does progressive image loadingRecently, I was browsing a post on Medium and I spotted a nice image loading effect. First, load a small blurry image…medium.comUsing WebP to create tiny preview imagesFollowing with the image optimization topic, I am going to have a deeper look to Facebook’s technique to create preview…medium.comMore examples of Progressive Image LoadingIn a past post I dissected a technique used by Medium to display images, transitioning from a blurry image to the final…medium.com
Medium如何進行漸進式圖像加載 最近,我在Medium上瀏覽了一篇文章,發現了很好的圖像加載效果。 首先,加載一個小的模糊圖像… medium.com 使用WebP創建微小的預覽圖像 在討論圖像優化主題之后,我將對Facebook的創建預覽 圖像 的技術進行更深入的研究 。過去的帖子中,我剖析了Medium用于顯示圖像的技術,從模糊的圖像過渡到最終的圖像。
You can read more of my articles on jmperezperez.com.
您可以在jmperezperez.com上閱讀我的更多文章。
翻譯自: https://www.freecodecamp.org/news/using-svg-as-placeholders-more-image-loading-techniques-bed1b810ab2c/
img 加載 svg占位符