41

So I am working on something in php where I have to get my images from a sql database where they will be encoded in base64. The speed of displaying these images is critical so I am trying to figure out if it would be faster turn the database data into an image file and then load it in the browser, or just echo the raw base64 data and use:

<img src="data:image/jpeg;base64,/9j/4AAQ..." />

Which is supported in FireFox and other Gecko browsers.

So to recap, would it be faster to transfer an actual image file or the base64 code. Would it require less http request when using ajax to load the images?

The images would be no more than 100 pixels total.

Frederik Struck-Schøning
  • 12,981
  • 8
  • 59
  • 68
teh_noob
  • 1,106
  • 3
  • 12
  • 25

10 Answers10

38
  • Base64 encoding makes the file bigger and therefore slower to transfer.
  • By including the image in the page, it has to be downloaded every time. External images are normally only downloaded once and then cached by the browser.
  • It isn't compatible with all browsers
some
  • 48,070
  • 14
  • 77
  • 93
  • 3
    also, base64 decoding is slow. – Gary Richardson Feb 07 '09 at 04:05
  • also, there is an alternative of merging image thumbnails into larger images and then present only relevant parts using pure css. This way 2 requests are necessary - page and 1 image. Images can be regenerated once every paginated image rows limit is reached. This unfortunately won't apply for searchable content. – too Jun 18 '12 at 08:05
  • @GaryRichardson I can confirm this. Especially on phones. – tedi Jan 26 '18 at 12:37
  • @some, is it still the same in 2019? i need to upload images from phone (an ionic app) to php server from there, php reports would be generated using the images. – Rakibul Haq Mar 03 '19 at 17:18
  • 1
    @RakibulHaq Yes, Base64 still adds 33% overhead. Yes, external images is usually cached by the browser. Yes, by including the images in the page it has to be downloaded every time. Yes, it isn't compatible with all browsers. But it might work for your application. – some Apr 27 '19 at 14:23
  • @some thanks for your clarification. i opted for uploading the image in the server and save the image name in the db, as i know the path, i load the image to the reports later using that path and image name from db, as i used phone app to upload the image i **did not** use `base64`, as it is required by the client to lower the bandwidth of transfer as much as possible because the billing is related to bandwidth usage. also, the transfer needed to be as fast as possible and client pcs may be with very old browsers. – Rakibul Haq Apr 28 '19 at 04:30
26

Well I don't agree with anyone of you. There are cases when you've to load more and more images. Not all the pages contain 3 images at all. Actually I'm working on a site where you've to load more than 200 images. What happens when 100000 users request that 200 images on a very loaded site. The disks of the server, returning the images should collapse. Even worse you've to make so much request to the server instead of one with base64. For so much thumbnails I'd prefer the base64 representation, pre-saved in the database. I found the solution and a strong argumentation at http://www.stoimen.com/2009/04/23/when-you-should-use-base64-for-images/. The guy is really in that case and made some tests. I was impressed and make my tests as well. The reality is like it says. For so much images loaded in one page the one response from the server is really helpful.

gian1200
  • 3,670
  • 2
  • 30
  • 59
  • 21
    The guy you mention seems to say that his images had 2MB (megabytes) when served from disk and went to 45KB (kilobytes) when served inline. That alone makes his case pretty dubious. – Piskvor left the building Apr 23 '09 at 06:21
  • Totally, I checked that base64 encoding actually increases the size. Unless this guy did compression as well – Richeek Nov 16 '16 at 05:34
5

Why regenerate the image again and again if it will not be modified. Hypothetically, even if there are a 1000 different possible images to be shown based on 1000 different conditions, I still think that 1000 images on the disks are better. Remember, disk based images can be cached by the browser and save bandwidth etc etc.

Mir Nazim
  • 636
  • 1
  • 8
  • 20
3

To answer the initial question, I ran a test measuring a jpeg image 400x300 px in 96 ppi:

base64ImageData.Length
177732

bitmap.Length
129882
Amit Kumar Gupta
  • 17,184
  • 7
  • 46
  • 64
esbenr
  • 1,356
  • 1
  • 11
  • 34
3

It's a very fast and easy solution. Although the image size will increase about 33% in size, using base64 will reduce significantly the number of http requests.

Google images and Yahoo images are using base64 and serving images inline. Check source code and you'll see it.

Of course there are drawbacks on this approach, but I believe the benefits outweighs the costs. A cons I have found is in slow devices. For example, In iPhone 3GS the images served by google images are very slow to render, since the images come gziped from the server and must be uncompressed in the browser. So, if the customer has a slow device, he will suffer a little when rendering the images.

3

I have used base64 images once or twice for icons (10x10 pixels or so).

Base64 images pros:

  • compact - you have single file. also if file is compressed, base64 image is compressed almost to the size of normal image.
  • page is retrieved in single request.

Base64 images cons:

  • to be realistic, you probably need to use scripting engine (such PHP) on all pages that contains the image.
  • if image is changed, all cached pages must be re-downloaded.
  • because image is inline, you can not use CDN or static content web server.

Normal images pros:

  • if you are use SPDY protocol, at least theoretical, page + images + CSS will load with single request too.
  • you can set expiration on the image, so content will be cached from the browsers.
Community
  • 1
  • 1
Nick
  • 9,962
  • 4
  • 42
  • 80
3

Don't think data:// works in IE7 or below.

When an image is requested you could save it to the filesystem then serve that from then on. If the image data in the database changes then just delete the file. Serve it from another domain too like img.domain.com. You can get all the benefits of last-modified, or e-tags for free from your webserver without having to start up PHP unless you need too.

If you're using apache:

# If the file doesn't exist:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/(image123).jpg$ makeimage.php?image=$1
MrWhite
  • 43,179
  • 8
  • 60
  • 84
rojoca
  • 11,040
  • 4
  • 45
  • 46
  • i stopped using this approach to prevent un-logged in user to access some image file. Image can contain sensitive information. Not saying it's bas but in some exception case you want to avoid that. – Louis Loudog Trottier Feb 09 '17 at 00:36
2

Generally, using base64 encoding is going to increase the byte size by about 1/3. Because of that, you are going to have to move 1/3 bytes from the database into the server, and then move those extra same 1/3 bytes over the wire to the browser.

Of course, as the size of the image grows, the overhead mentioned will increase proportionately.

That being said, I think it is a good idea to change the files into their byte representations in the db, and transmit those.

casperOne
  • 73,706
  • 19
  • 184
  • 253
2

To answer the OP Question. As static files, directly via disk thru web server. at only 100px they are ideally suited to in memory caching by the Web server. There is a plethora of info ,caching strategies, configs, how-to's for just about every web server out there.

Infact - The best option in terms of user experience (the image speed you refer to) is to use a CDN capable object store. period.

The "DB" as static storage choice is simply expensive - in terms of all the overhead processing, the burden on the DB, as well as financially, and in terms of technical debt.

A few things, from several answers

Google images and Yahoo images are using base64 and serving images inline. Check source code and you'll see it.

No. They absolutely do NOT. Images are mostly served from a static file "web server" Specfically gstatic.com: e.g. https://ssl.gstatic.com/gb/images/p1_2446527d.png

compact - you have single file. also if file is compressed, base64 image is compressed almost to the size of normal image.

So actually, No advantage at all, plus the processing needed to compress?

page is retrieved in single request. Again, multiple parallel requests as opposed to a single larger load.

What happens when 100000 users request that 200 images on a very loaded site. The disks of the server, returning the images should collapse. You will still be sending The same amount of data, but having a Longer connection time, as well as stressing your database. Secondly the odds of a run of the mill site having 100000 concurrent connections... and even if so, if you are running this all of a single server you are a foolish admin.

By storing the images - binary blobs or base64 in the DB, all you are doing it adding huge overhead to the DB. Either, you have masses and masses of RAM, or your query via the DB will come off the disk anyway. And, if you DID have such unlimited RAM, then serving the bin images off a Ramdisk - ideally via an alternative dedicated, lightweight webserver static file & caching optimised, configured on a subdomain, would be the fastest, lightest load possible!

Forward planning? You can only scale up so far, and scaling a DB is expensive (relatively speaking). Again the disks you say will "sp

In such a case, where you are serving 100's of images to 100000 concurrent users, the serving of you images should be the domain of CDN Object store.

Coopz
  • 41
  • 3
0

If you want the fastest speed, then you should write them to disk when they are uploaded/modified and let the webserver serve static files. Rojoca's suggestions are good, too, since they minimize the invocation of php. An additional benefit of serving from another domain is (most) browsers will issue the requests in parallel.

Barring all that, when you query for the data, check if it was last modified, then write it to disk and serve from there. You'll want to make sure you respect the If-Modified-Since header so you don't transfer data needlessly.

If you can't write to disk, or some other cache, then it would be fastest to store it as binary data in the database and stream it out. Adjusting buffer sizes will help at that point.

Richard Levasseur
  • 14,562
  • 6
  • 50
  • 63