Applicable restrictions on base64 encoding of images

Introduction

Ever since Steve · Saunders ( Steve Souders ) started promoting Web since the performance, we think deeply, extra HTTP requests will add a lot of overhead, and if possible, we should combine them to significantly reduce The load time of the page.

The actual meaning is to combine our JavaScript and CSS files, which is relatively easy and straightforward, but the more difficult problem is how to deal with images.

Elves

Image sprites are a concept in video games: the idea is to stuff a large number of image assets into a file, and rearrange various " viewports " to view only specific segments of the file at a time. For example, a simple sprite containing two images might have a viewport that only looks at the top of the sprite (image # 1 ), and another viewport that only looks at its bottom half (image # 2 ).

On the network side, this means that these multiple requests have now been combined into one request. This is good because it saves the overhead of additional HTTP requests and the overhead of setting the image file header each time .

But there are some disadvantages to using image sprites:

  • Difficult to maintain and update: Without the help of certain tools, manually editing the image sprites and putting them together is a troublesome thing
  • Increased memory consumption (may be very large): This is usually ignored. Reducing the time to transfer images will come at the cost of larger memory and CPU footprint, especially for large sprites and sprites with a lot of blank space.
  • Bleeding: For sprites that don’t have too much white space to separate the image, there is an increased possibility that nearby images will seep into other elements, because in this case the bleeding is only visible on iOS (but looks good on Chrome and Safari) . Please note the leakage under the CNN logo:

Data URI and Base64 encoding

Data URI (see this , this and this ) and Base64 encoding are closely integrated. This method allows you to embed images directly in HTML , CSS or JavaScript .

Just like sprite , you can save HTTP requests, but there are some disadvantages:

  • The base64 encoding makes the file size approximately 33% larger than its original binary representation , which means more data needs to be transferred (this can be very painful on mobile networks)
  • IE6 or IE7 does not support data URI, IE8 limits the maximum 32K
  • Base64-encoded data may require longer processing time than binary data (does anyone want to study this?) (again, this may be particularly painful for mobile devices with limited CPU and memory) (side note: CSS background-image seems Actually faster than the img tag )

Although the numbers vary greatly depending on the type of content, the claim of "33 % or more " is now generally accepted. This is exactly what I want to test, albeit in a very limited and unscientific way.

Before testing, I want to keep in mind some unverified intuitions (these intuitions are not entirely my own, but seem to be ideas that can be seen everywhere). These are a few questions before I want to test:

  • Is the base64 encoding using gzip compression roughly equal to the original file size of the binary file?
  • Is base64 encoding best for small images?
  • Is base64 encoding best for small and simple icons, but not for pictures and photos?
  • When merging multiple files together, is base64 encoding the best?

I also want to test: whether compressed binary image data makes a big difference. I know that text can be compressed well, but, for example, is it even worth compressing JPEG files with Gzip ?

I ran three tests: one with a set of small UI icons, one with a set of small photos, and the other with a larger set of identical photos. Although my tests are by no means extensive, they do indicate that care should be taken when making assumptions about base64 .

Just a note about the tables: they are comparing the binary form (original png or jpeg ) with the base64 form that will be displayed in the CSS style sheet , and comparing each table with their compressed form, which is most likely a transmission wire . The CSS indicates that there are some actual declarations that look like this:

1
2
3
4
5
6
.address-book--arrow {
        
        
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAp1JREFUeNqEU21IU1EYfu7unW5Ty6aBszYs6MeUjGVYokHYyH5E1B9rZWFEFPQnAwmy6Hc/oqhfJsRKSSZGH1JIIX3MNCsqLTD9o1Oj6ebnnDfvvefezrnbdCHhCw/n433P8z7nPe/hBEEAtX0U7hc164uwuvVSXKwZLoOmaRDim+7m9vZa0WiEKSUFFpNpCWlmMyypqTDRuYn6t3k8vmQ2gRDCxs0t9fW45F52aBTROJLtZl7nEZad2m+KtoQCQ0FBARyOCGRZ/q92I1WgqqXlfdd95VsrK8/pChIEqqpCkiQsiCII0aBQZZoWl8lzFDwsFjMl0DBLY8Lj41hBwK4jSQrWOIphL6xYyhwJDWGo6wFSaH1Y3PTCAsITE1oyAa8flhWkbSiCLX8vun11eiGIpiJ/z2nYdx5HqLdVV7elrOzsuqysL3rmBIGiKPizKCHHWY4PLVeQbnXAdegqdhy+hu8dDTBnbqQJZJ1A7u+vz7RaiymWCZgCRSF6Edk8b9cx+B/W6WuVxPaZnyiqXoPpyUmVYvkKTIFClHigEieKjYuSvETUllaF4GAUM1NT6ooaJDKx+aDfC9fByxj90REb+9ppmIoAscH/6leg8MS9DJXPAM9xHCM443K57C6biMjcHDaVVCHw9RmCA2/RGC5C00AqXk/m4p20HZK4CM/J3Zk9n0ecMBhDQnJHcrTisyMfdQXOilrdMfxcwoHq/fg5R59TiQV3hYGKo6X2J/c7LyQIjOx9GXhOw/zoJ8wEevRGyp53o/lGMNYsBgPtEwLecwov7/jGDKa1twT6o3KpL4MdZgGsWZLtfPr7f1q58k1JNHy7YYaM+J+K3Y2PmAIbRavX66229hrGVvvL5uzsHDEUvUu+NT1my78CDAAMK1a8/QaZCgAAAABJRU5ErkJggg==);  
  width: 16px;
  height: 16px;
  background-repeat: no-repeat;
}

Okay, start testing!

Test # 1 : Five 16×16 icons in the Fugue Icon Set ( PNG )

file

Duality

Binary compression

CSS + Base64

CSS + Base64 compression

abacus

1443

1179

2043

1395

Acorn

1770

1522

2478

1728

Address Book Arrow

763

810

1153

948

Address book exclamation mark

795

848

1199

988

Address book minus sign

734

781

1113

919

total

5,505

5,140

7,986

5,978

Merge files

(5,505)

4,128

7,986

4,423

  • All numbers are in bytes
    ** The numbers in parentheses represent actual but impractical data. Unfortunately, images cannot be combined and delivered in binary form.

Takeaway:

  • Binary files are always smaller.
  • Sometimes, compression can make the file larger.
  • Gzip compression on the base64 version makes the file size close to the size of the original binary file, but this ignores the fact that the binary file is also compressed. Gzipped binaries (how to deliver them to the client) are always smaller than Gzipped base64 images
  • Combining files together can greatly reduce file size.

In fact, developers have two options: provide users with 5140 bytes in five separate HTTP requests , or provide users with 4423 bytes ( CSS with base64- encoded image data ) in one HTTP request . Base64 is clearly the winner here, and it seems to confirm that the compression effect of the small icon is very good.

Test # 2 : Five Flickr 75×75 pictures ( JPEG )

file

Duality

Binary compression

CSS + Base64

CSS + Base64 compression

1 piece

6734

5557

9095

6010

2

5379

4417

7287

4781

3

25626

18387

34283

20103

4

7031

6399

9491

6702

5

5847

4655

7911

5077

total

50,617

39,415

68,067

42,673

Merge files

(50,617)

36,838

68,067

40,312

Takeaway:

  • (Same points as test #1)
  • In addition, after using base64 encoding and compression, the size of the photo will not be too large. This is reasonable.

Indeed, developers can 5 be delivered separate requests 39,415 bytes, or a delivery request of 40,312 bytes. There is not much difference in file size here, but when we talk about 40kb , it's better to be 1 request.

Test # 3 : Five Flickr 240×160 pictures ( JPEG )

file

Duality

Binary compression

CSS + Base64

CSS + Base64 compression

1 piece

24502

23403

32789

23982

2

20410

19466

27333

19954

3

43833

36729

58561

38539

4

31776

31180

42485

31686

5

21348

20208

28581

20761

total

141,869

130,986

189,749

134,922

Merge files

(141,869)

129,307

189,749

133,615

Takeaway:

  • (Same points as test #1)
  • Larger photos seem to bring Gzipped binary and Gzipped base64 file sizes closer, making the difference very small

开发人员必须在5HTTP请求中传递130,986字节,或在一个HTTP请求中传递133,615字节之间进行选择。任何好的Souders追随者都会选择一个请求,但是在这里我会小心……

注意:事情并不总是像看起来那样

这里有一个很大的警告:在5个单独的请求中交付图像可能实际上对感知性能更有利。

为什么?因为133,615字节可将一个包中的所有内容全部交付给最终用户,而最终用户在整个过程中都将盯着空白的占位符。如果5base64图像全部出现在一个请求中,则该请求必须先完成,然后屏幕上才会显示任何内容。所有5张图像都从空白占位符变为几乎立即从base64解码并显示在适当位置。

将此与5个最有可能并行执行的请求进行比较,并通过在下载时显示部分图像,向用户提供实际指示,指示正在下载实际图像内容(也可以尝试回退为渐进式JPEG -实际上,任何事情都会比空白屏幕更好。这就是为什么以良好的老式方式加载图像实际上可能对感知性能有利的原因。无论如何,它们很可能将以并行方式加载,因此额外的HTTP请求实际上可能并没有真正起作用。更不用说让浏览器管理每个文件的缓存,而不是让JavaScript管理缓存并阻止您下载已经存储在localStoragesessionStorage中的映像,会更容易。

话虽如此,通常建议将常见的UI图标放在CSSbase64中,然后让整个块都被浏览器缓存。这些通常也是干净的矢量图标,看起来压缩得很好(请参阅测试1)。

但是对于图像内容,除了HTTP请求外,没有什么要保存的,您绝对应该三思而后行地使用base64编码保存请求。是的,您将保存一些HTTP请求,实际上不会保存字节,并且用户实际上可能认为体验较慢,因为在下载图像时他们看不到图像内容。即使您节省了几毫秒的等待时间,感知性能也是最重要的。

(编辑:将未验证的直觉部分的措词从未验证更改为实际问题,以使其更清楚)

EDIT 20135月:添加了一个精灵泄放的示例

 

Guess you like

Origin blog.csdn.net/allway2/article/details/109643983