List

Faster websites: integrating next-gen images in your Rails apps

Faster websites: integrating next-gen images in your Rails apps

by JP Balarini

In the talk titled "Faster websites: integrating next-gen images in your Rails apps," JP Balarini discusses the critical role of image loading times in overall website performance and business conversion rates. He highlights that images account for nearly 50% of a site’s load time, leading to a 5% drop in conversions for every additional second it takes to load.

Key points discussed include:

  • Importance of Image Formats: Traditional formats like JPEG and PNG are being replaced by next-gen formats such as WebP and AVIF that provide better compression without compromising quality. WebP is especially noted for its compatibility across most modern browsers.

  • Performance Metrics: Balarini presents compelling statistics from various studies showing that websites loading in under two seconds yield significantly higher conversion rates. Companies like Telefonica and BMW have seen marked improvements in click-through rates after improving their loading times.

  • SEO Implications: Faster-loading websites rank better in search engine results, as loading time is a recognized ranking signal by Google. Therefore, optimizing image loading is not just a technical issue but also has direct repercussions for online visibility.

  • Cost Efficiency: Optimizing image sizes can lead to substantial savings in storage and transfer costs, notably for platforms with high usage like Instagram, which processes vast amounts of data daily.

  • Integrating Next-Gen Images in Rails: Balarini discusses the challenges of integrating WebP images or using picture tags in Rails applications, given that Rails does not natively support these formats. He details the shortcomings of existing gems and the need for a custom solution, which led to the development of a new gem for streamlining this integration.

  • Example of Implementation: He shows how to configure Rails applications to automatically convert and serve WebP images, using a combination of Rake tasks and helper methods for both static and dynamic assets.

In conclusion, by integrating next-gen image formats into Rails applications, developers can significantly reduce load times, improve SEO, and enhance the user experience while also saving costs. Balarini encourages the audience to contribute to developing better solutions for common challenges faced in web development, particularly within the Rails ecosystem.

Faster and cheaper websites: integrating next-gen images in your Rails apps by JP Balarini

Did you know loading images accounts for nearly 50% of your website’s total load time? Also, every additional second of load time results in a 5% decrease in conversion rates, which directly impacts your business. What if I told you there’s a simple way to decrease loading time?

This talk will explore the latest and most effective options for web images that significantly reduce website size without compromising quality. We’ll discuss how using next-gen images can significantly impact website loading times, user conversion, and SEO.

We’ll also go through the different challenges that I faced while integrating next-gen images into a Rails project and how I solved them. A new gem will be presented that streamlines the process of using WebP images with Ruby on Rails.

RailsConf 2023

00:00:01.199 foreign
00:00:22.820 better known as JP this is my first time
00:00:26.640 at a rubikov at our rails consory and my
00:00:29.580 first time speaking
00:00:31.019 so
00:00:33.540 thank you
00:00:36.780 I'm the CTO and co-founder at eager
00:00:40.320 Works where we are our Royal rails based
00:00:43.260 on Uruguay Dev shop based on Uruguay and
00:00:46.860 today I'm gonna be presenting faster
00:00:48.899 websites integrating next-gen images in
00:00:51.780 your rails apps and I'm going to explain
00:00:54.260 what this fancy title means
00:00:57.480 a little bit of background behind this
00:00:59.280 talk this talk comes from our work
00:01:02.160 trying to improve the performance of our
00:01:04.860 website
00:01:06.180 our website is our presentation card for
00:01:09.240 us so we want it to be smoother we want
00:01:11.640 it to be faster
00:01:13.080 and one thing that we saw since our
00:01:16.260 website is pretty image heavy and has a
00:01:18.659 lot of animations and stuff we saw that
00:01:22.200 uh
00:01:23.640 improving our assets our images will
00:01:26.700 translate into at least one second of
00:01:30.360 loading faster times right so we wanted
00:01:32.880 to improve that so I'm going to show you
00:01:35.520 what problems I faced doing this and the
00:01:38.939 solution I took which is basically
00:01:40.619 creating a gem for streamline in this
00:01:42.900 process
00:01:45.000 okay let's speak a little bit about web
00:01:47.820 images and what they are we all we all
00:01:50.579 know what a web image is because we know
00:01:52.619 jpeg we know PNG
00:01:54.659 but these standards have more than 30
00:01:57.540 years jpeg has yeah it's from 1992 so
00:02:03.180 you can expect that in 30 years
00:02:05.040 something better shook up here
00:02:09.300 every year new algorithms appear and new
00:02:12.120 compression methods and everything so
00:02:13.680 yeah in 30 years something bad I should
00:02:16.319 have a beer because in 30 years it's
00:02:18.540 like 84 programming years
00:02:21.900 so yeah this is true newer image formats
00:02:25.319 have appeared the first one is webp that
00:02:29.220 was created by Google a couple of years
00:02:30.959 ago
00:02:32.220 yeah it's open source I mean it's
00:02:34.319 royalty free you can use it on your
00:02:36.720 website today and there is like the the
00:02:40.080 browser adoption I took that from can I
00:02:42.780 use so as you can see there you can use
00:02:46.140 it on every browser instead a platform
00:02:49.800 Internet Explorer but no one uses that
00:02:51.860 internet
00:02:53.540 it works on edge so you can use that on
00:02:57.000 our on your websites today
00:02:59.160 another format is ABF
00:03:02.160 ABF
00:03:04.800 the format ABF was created by a
00:03:07.680 Consortium that is created by Google
00:03:10.140 Apple Microsoft Netflix I mean all the
00:03:14.040 big companies are supporting this new
00:03:15.540 format it's a little bit new
00:03:19.080 and also we have jpeg Excel that was
00:03:22.379 created like just two two or three years
00:03:25.379 ago but it's pretty new it doesn't have
00:03:28.319 much browser resolution today
00:03:31.620 but before continuing I want to know how
00:03:34.560 many of you here have used any of these
00:03:36.540 formats in their production websites or
00:03:38.940 are using it today
00:03:40.980 please raise your hands okay just a
00:03:43.379 couple right
00:03:44.840 so with this image format you can expect
00:03:48.299 at least 30 percent Improvement on on
00:03:51.599 the sides of your images I say at least
00:03:54.239 because I have seen like 90 Improvement
00:03:56.700 in some cases and we are going to see
00:03:59.340 this later
00:04:02.220 okay what is the motivation behind using
00:04:05.220 this next-gen image formats well the
00:04:08.220 main motivation is to decrease the image
00:04:10.319 size right because this
00:04:12.659 um
00:04:13.319 doing this has some important benefits
00:04:15.420 that we are going to see
00:04:17.699 the first time the first one is the
00:04:19.680 loading times right if you decrease the
00:04:21.479 image size you're going to load
00:04:23.520 everything faster
00:04:25.020 so this directly affects user conversion
00:04:28.800 and how the the user perceives your
00:04:31.259 website in our case we want it to be
00:04:33.300 pretty pretty fast and smooth because we
00:04:36.240 are a super agency you want people to to
00:04:38.280 think that we can do fast things right
00:04:42.139 I'm going to show some extra extracts
00:04:46.020 from some studies the first one is from
00:04:48.960 important a couple of years ago they saw
00:04:51.360 that if you have an e-commerce for
00:04:53.160 example
00:04:54.900 um the highest conversion rates on
00:04:56.699 e-commerce occur on websites that load
00:04:59.160 below two seconds so if your website
00:05:01.440 loves takes more than two seconds to
00:05:03.479 load you're missing money
00:05:06.360 on a similar note for each additional
00:05:08.820 second that your website takes to load
00:05:10.979 you are missing five percent of
00:05:12.780 conversion rate so that's money that
00:05:15.300 you're losing also
00:05:17.220 similar telefonica which is a leading
00:05:19.979 mobile provider in Latin America and
00:05:23.220 Spain they saw they did a revamp of
00:05:26.520 their mobile website improving the
00:05:28.020 performance by 70 and they saw an
00:05:31.080 increase click an increasing click
00:05:32.820 through rate of 31 percent
00:05:36.240 really similar BMW another side revamp
00:05:39.120 they improve the performance they saw a
00:05:41.820 4X in conversion in Click through rice
00:05:44.699 on their website
00:05:46.740 so this is pretty important right
00:05:50.160 a second thing uh
00:05:52.500 is seo seo is search engine optimization
00:05:56.220 for those of you who haven't heard this
00:05:58.800 term before basically you can optimize
00:06:01.380 your website so it ranks higher on
00:06:03.539 Google
00:06:04.199 so basically if you
00:06:08.340 you can you can do things to improve
00:06:10.259 that ranking right so one of the things
00:06:12.479 that Google
00:06:15.120 takes into account to to rank your page
00:06:17.460 higher is loading times right so from a
00:06:21.780 couple of years ago I took this from
00:06:23.220 Google's blog so it's it's the real
00:06:25.680 thing because no one knows how how the
00:06:28.860 Google algorithm works but you know we
00:06:31.680 know a couple of things
00:06:33.080 loading times is a ranking signal for
00:06:35.580 Google both on desktop and mobile so you
00:06:39.060 want your website to load faster
00:06:42.120 and the third one and it's like the more
00:06:44.699 direct one maybe it's the cost right I
00:06:47.580 mean you need to store those images
00:06:48.900 somewhere you need to transfer that
00:06:51.479 image so you need to pay for that
00:06:54.479 um
00:06:55.500 and for that we are going to do like a
00:06:57.600 quick
00:07:00.060 thought experiment here using Instagram
00:07:02.639 as a case study
00:07:04.620 I took this this number from from
00:07:07.080 Instagram so 50k images are uploaded to
00:07:10.740 Instagram
00:07:11.580 every minute
00:07:12.900 so if we assume a two megabyte two
00:07:15.960 megabyte per image that's a reasonable
00:07:18.180 number I guess
00:07:20.220 you will need to store at least
00:07:22.919 100
00:07:24.240 144 terabytes per day just to store
00:07:26.819 images that user are blogging and this
00:07:29.280 is like a conservative number because
00:07:30.900 you usually don't store only the image
00:07:32.940 that the user uploads you store multiple
00:07:34.560 versions for different resolutions so
00:07:37.319 these are these numbers is really high
00:07:40.199 right it's it's a lot of cardboard hard
00:07:42.180 drives per day
00:07:44.340 also you need to take into account usage
00:07:46.740 I mean if you are browsing Instagram you
00:07:48.900 are doing get requests to a server so
00:07:51.720 you need to transfer that image I did a
00:07:54.419 quick experiment with myself trying to
00:07:56.160 browse Instagram for a couple of minutes
00:07:57.599 to see how many images I was able to see
00:07:59.520 that's around 50 images per minute per
00:08:01.680 user
00:08:03.479 they have 500 million active users so
00:08:06.740 these translate more or less in one
00:08:10.020 million and a half terabytes per day of
00:08:12.479 network transfer so
00:08:14.759 I mean it's huge
00:08:17.880 so I did some math here you will need to
00:08:20.639 trust me you can you can check them out
00:08:22.259 after the the conference but
00:08:24.720 it's something I I want to win to edulas
00:08:27.660 and to assure also to more or less take
00:08:31.319 some number some rough number and this
00:08:34.260 number is around in the order for
00:08:36.240 between 40 and 70 million per day just
00:08:39.060 to store and transfer images
00:08:41.159 so because we need to assume a lot of
00:08:43.560 things that are not public but it's it's
00:08:45.839 in the order of millions of dollars per
00:08:47.519 day
00:08:48.360 so you would expect that a significant
00:08:50.760 reaction I don't know 30 40 50
00:08:53.600 reaction on those sizes will translate
00:08:56.580 into millions of dollars of savings per
00:08:59.399 day not per year per day
00:09:02.160 um
00:09:03.480 so continuing in that in the same line
00:09:07.080 let's see a couple of more real examples
00:09:09.839 that I mean you can check for yourself
00:09:14.040 Instagram I went to their website
00:09:16.500 inspect element and yeah they are still
00:09:19.260 using jpegs it's really small there but
00:09:21.779 it says JPEG and it's a jpeg
00:09:24.540 so imagine again how much they could be
00:09:26.580 saving just by doing the conversion to a
00:09:28.320 webp or an ABF
00:09:32.040 pretty similar Elon Musk but Twitter a
00:09:35.399 couple of months ago and he asked the
00:09:37.680 teams there to cut infrastructure goods
00:09:40.680 between one and one and a half and three
00:09:42.839 million per day
00:09:44.640 so I asked myself okay are they still
00:09:48.420 using old image formats yes they are
00:09:51.500 they're still leading jpegs
00:09:54.660 so I wanted to know how how much could
00:09:57.660 be saved by this so I went to Google
00:10:01.260 Lighthouse I don't know if you know that
00:10:03.300 tool but it's a Google Chrome tool
00:10:05.959 you can run audits on our website and it
00:10:09.180 will tell you okay yeah your performance
00:10:11.279 is this it's a number and by doing this
00:10:14.399 this is you can you could improve your
00:10:16.380 the performance of your website
00:10:18.899 so here it says by serving images in an
00:10:23.100 exchange format which could be webp or
00:10:25.320 ABF you could be saving one second
00:10:27.540 right one second of loading time so
00:10:30.300 every user could load the feed once
00:10:32.640 again faster just fine switching to a
00:10:34.320 webp for example
00:10:36.360 and I don't know if it's too it's big or
00:10:39.060 not that here are the there are the like
00:10:41.519 the top four images of my field and it's
00:10:44.760 a long list but you can see there it
00:10:47.160 says for the first image it's
00:10:49.700 450 kilobytes and you could be saving
00:10:54.079 421 kilowatts that's like 90 of the
00:10:57.540 image that could be
00:10:59.640 saved by by switching to that
00:11:03.180 but it could be saying okay these are
00:11:05.760 just two hand-picked examples what about
00:11:08.700 if we apply these to entire internet
00:11:11.760 well do the Google did this a couple of
00:11:14.640 years ago like 30 years ago and when
00:11:17.459 they created the
00:11:19.740 the format for the first time and this
00:11:22.200 created one million images that are
00:11:24.120 somehow representative of the internet
00:11:26.040 they say that I don't know what that
00:11:28.079 means but they scrapped 1 million images
00:11:31.620 and they run several compression
00:11:33.180 algorithms on top of those images and
00:11:36.180 for webp they could get like 40 40 on
00:11:39.779 average compression
00:11:41.880 so this number should be higher today
00:11:45.480 because the the algorithms has changed a
00:11:47.880 lot but we can expect at least 40
00:11:50.339 compression by just switching to one of
00:11:52.920 these formats
00:11:55.200 okay even though we saw that there are a
00:11:58.620 couple of image formats that we can use
00:12:01.339 I'm going to focus on webp which is the
00:12:04.680 one that has wider browser support right
00:12:07.140 now and I wanted to use this in my rails
00:12:09.959 project right our website it's a rails
00:12:12.600 project how can I do it today
00:12:15.899 well there are a couple of ways of doing
00:12:18.120 this today the first one is using the
00:12:20.339 plain old image tag that we all use yeah
00:12:24.000 you can just specify source hello.webby
00:12:27.180 and that is going to work
00:12:29.640 the web B the sorry the image tag
00:12:32.940 supports what is called resolution
00:12:34.560 switching which is you can specify
00:12:36.899 multiple formats and the browser is
00:12:39.480 going to decide which one to use
00:12:40.980 depending for example on browser with
00:12:44.339 the thing with that is that the browser
00:12:46.320 decides which image to use so a couple
00:12:49.380 of years ago on HTML5 a picture tag was
00:12:52.980 introduced that is like a more robust
00:12:55.860 version of the image tag that apart from
00:12:58.980 resolution switching supports image
00:13:01.380 fallbacks so you can load first an ABF
00:13:04.019 if that's not supported though there
00:13:05.639 will be if not load the PNG
00:13:08.639 and it also supports what it's called R
00:13:10.620 Direction what means what does our
00:13:13.139 direction mean well it's like resolution
00:13:15.240 switching but
00:13:16.980 you can specify which image to use
00:13:19.320 depending on the use case and here like
00:13:21.899 for example I have a an image of our
00:13:24.360 website
00:13:25.320 so on the left you can see that we are
00:13:27.779 loading a totally different image than
00:13:29.579 the one from the right and we specify
00:13:32.940 okay for this resolution for this device
00:13:35.339 for this with load this image I'm not
00:13:38.040 doing fine the browser doesn't decide
00:13:41.220 which one which image to use
00:13:45.240 so what does like a picture tag look
00:13:48.300 like okay this is a picture tag it's
00:13:50.700 it's like a picture HTML tag that that
00:13:54.360 is wrapping everything
00:13:55.800 inside you can specify multiple sources
00:13:57.959 and just an image tag and the image tag
00:14:01.019 it's going to select it's going to load
00:14:03.000 one of these sources depending if it is
00:14:06.540 supported for example here you can see
00:14:09.959 that we have a couple of media queries
00:14:11.820 so we can specify a lot of things on the
00:14:14.459 first for example in the First Source if
00:14:16.620 the width is less than 600 pixels is
00:14:19.320 going to load the first one
00:14:21.139 if not it's going to lock the big one
00:14:23.519 and if webp is not supported just load
00:14:26.100 the the PNG
00:14:29.639 and here it's like the more complex
00:14:31.560 example here we are mixing a lot of
00:14:34.620 stuff we are mixing media queries we're
00:14:36.899 mixing pixel ratios we're mixing
00:14:39.000 different formats and the the thing
00:14:41.040 about this it's like these kind of
00:14:43.079 things that you used to do with CSS for
00:14:45.899 example a couple of years ago we maybe
00:14:47.699 you had to hide hide some sub I mean
00:14:50.760 load two images high one depending on
00:14:52.980 whatever you wanted you can do this with
00:14:55.500 a picture tag
00:14:57.959 so I wanted to use this in the picture
00:15:00.240 tag and web B and everything on my roles
00:15:03.420 website
00:15:04.920 how can I do it
00:15:06.779 well
00:15:08.160 I was a little bit disappointed at first
00:15:10.139 to know that I mean rails doesn't
00:15:12.240 doesn't natively support web beats or
00:15:15.180 picture tags and everything
00:15:17.579 um
00:15:18.360 so
00:15:19.500 it doesn't support for example
00:15:21.240 conversion of web images why do we want
00:15:24.240 conversion of web image as well
00:15:26.339 if you're working with a designer I mean
00:15:28.980 the person is not going to send you a
00:15:30.839 webp it's going to send you a PNG or
00:15:32.639 jpeg for example figma doesn't even
00:15:34.680 support exporting in in webp so you need
00:15:37.560 a you need to convert that somehow
00:15:39.680 so we want something that is automatic
00:15:43.920 the other thing is yeah rails doesn't
00:15:46.560 have a picture tag it only has the image
00:15:48.660 tag so yeah it was weird but yeah it
00:15:51.779 doesn't support it so if you want to use
00:15:53.519 it you just need to specify the full
00:15:55.860 HTML by yourself
00:15:58.199 and also it doesn't have any
00:16:00.240 optimization to serve Webby images
00:16:03.360 uh also I try to use anything that is
00:16:06.720 out there a third party option but the
00:16:09.959 the gems that I saw they assume a lot of
00:16:12.420 stuff depending on the specific reality
00:16:15.180 of the person that implemented the gem
00:16:17.279 they sold part of the problem maybe the
00:16:19.980 conversion Maybe This Plane maybe uh
00:16:22.740 serving that don't even work and they
00:16:25.800 are unmaintained and they have they lack
00:16:28.199 documentation most of them so if you
00:16:30.779 don't believe me here are a couple of
00:16:32.459 examples I took from
00:16:34.320 a couple of screenshots I took the first
00:16:36.839 one is uh post from stack overflow
00:16:40.860 and here is someone that is trying to I
00:16:43.920 mean it's from a couple few months ago
00:16:45.600 seven months ago
00:16:47.100 and it's someone who is trying to
00:16:49.800 integrate webp without the extra Active
00:16:52.740 search on their rails website and it's
00:16:55.199 saying okay I'm trying to do this I
00:16:57.060 can't it's not possible and in the end
00:16:59.399 it says it's real small but it says Ruby
00:17:01.500 and rails is dead
00:17:03.060 so it's funny
00:17:05.579 um
00:17:06.299 on the on their right you can see other
00:17:09.179 two gems that are the ones that have
00:17:11.579 more stars the first one is for carry
00:17:13.980 web it says the gem this gem provides an
00:17:16.199 ugly but working solution I graded it as
00:17:18.540 an experiment you have been warned so
00:17:21.839 and the next one it says in my
00:17:23.939 experience the exiting gems made
00:17:26.100 questionable assumptions which is exact
00:17:28.559 the exact same feeling that I had while
00:17:31.200 doing this
00:17:33.600 so it makes sense that there's not a
00:17:36.419 civil suitable Silver
00:17:38.960 Bullet for this problem
00:17:41.820 um because there are multiple problems
00:17:43.799 to solve and each one could be solved in
00:17:46.740 a different way depending on the
00:17:48.480 specific reality that you need
00:17:50.820 so you might need to convert the images
00:17:53.160 to a b but maybe you don't because you
00:17:55.440 are converting that somehow in another
00:17:57.419 way you need to handle both static and
00:18:00.360 dynamic asset assets which means assets
00:18:03.600 that are on the app asset images path
00:18:06.179 folder and assets that maybe are
00:18:08.820 uploaded by users by ordering a process
00:18:11.340 or whatever
00:18:13.080 which are handled by active storage for
00:18:16.320 example you also need to display the
00:18:20.039 those images so you will need a picture
00:18:21.900 tag for this so you want to support
00:18:24.240 multiple formats you need to serve this
00:18:26.880 you need to handle the asset digest
00:18:28.919 which is tricky
00:18:30.440 I don't know maybe you want you have
00:18:33.240 some option that works on the
00:18:34.799 interaction but I want this to work also
00:18:37.140 in development so there are a couple of
00:18:38.880 problems that will arise with this
00:18:42.419 so these are the options that I had the
00:18:45.419 first option was okay maybe we can use
00:18:47.400 something that it's already there maybe
00:18:49.500 a gem
00:18:50.520 and these are the top two that have most
00:18:53.580 stars the first one doesn't even work I
00:18:56.100 try to use that with rel6 it doesn't
00:18:57.840 work
00:18:59.760 so the last committed from was from like
00:19:01.919 four years ago
00:19:03.480 um
00:19:04.679 five years ago the next one
00:19:07.559 um yeah you cut a bag with the asset
00:19:09.780 dashes I tried to use that it had a bag
00:19:11.760 I had to clone it forget find the bag
00:19:15.120 fix it and at the end it doesn't even
00:19:17.700 fit my needs so there wasn't an option
00:19:20.580 that fit in my needs in this case
00:19:23.340 the second option was like okay maybe we
00:19:26.039 don't even want to convert this because
00:19:28.140 maybe we can maintain our webis
00:19:30.360 alongside pngs and that's it yeah but
00:19:33.179 yeah we need to solve the dynamic images
00:19:35.580 we need to solve the serving them
00:19:37.559 displaying them whatever
00:19:40.320 the third option was that I saw out
00:19:42.480 there was like okay maybe we can
00:19:45.120 have something that
00:19:47.160 converts this on the fly or whatever but
00:19:51.059 I saw also some people that doing it
00:19:53.520 were doing like an nginx redirection for
00:19:56.039 example so if you requested that jpeg
00:19:58.380 for example I do a rewrite of that
00:20:00.539 request and serve you a webp but yeah
00:20:03.780 this doesn't even work on development
00:20:05.700 you still need to display the the web
00:20:08.580 image through a bigger tag you're not
00:20:11.039 solving the the dynamic assets and
00:20:12.960 whatever
00:20:13.919 so the photo option and it's the one
00:20:16.260 that I took was like okay I need to
00:20:18.240 solve these two problems here the first
00:20:20.580 one is to basically convert and yeah and
00:20:23.640 convert the webp assets I mean the asset
00:20:26.160 2 will be actually
00:20:27.960 this means handle the static asset
00:20:30.240 problem and the dynamic assets
00:20:32.640 and also I wanted to display this so we
00:20:35.700 need a picture tag I wanted to like
00:20:38.640 solve three use cases here I wanted the
00:20:41.100 user to have like the full I mean if the
00:20:44.700 user wanted to specify anything
00:20:46.500 everything he could do it with a picture
00:20:49.980 with a Blog for example another option
00:20:53.100 is like
00:20:55.320 I want the option to automatically infer
00:20:57.720 everything from the existing assets so
00:21:01.020 you can specify an option that says okay
00:21:02.880 yeah
00:21:04.260 compared to webp and that works like
00:21:06.660 magic and I had to take it around both
00:21:10.200 static and dynamic assets so I needed to
00:21:12.059 support that
00:21:13.980 okay so I wanted to build this how can I
00:21:16.679 do it well the selected approach I took
00:21:19.200 was for the webp assets you can do like
00:21:22.799 an enhance on our rake task so basically
00:21:26.780 I do an enhance of the ads per compile
00:21:29.400 task I had a couple of options of doing
00:21:31.559 for doing this the other one was to do a
00:21:34.559 transformation on sprocket but that was
00:21:36.720 a complex and actually this is going to
00:21:40.380 be migrated to Prop Shops so it doesn't
00:21:42.659 make sense right now so I use it as a
00:21:45.600 rectus and the dynamic assets are
00:21:49.020 handled in a different way I wrote some
00:21:51.299 helper methods to for this so you can
00:21:54.240 integrate this for with currywave for
00:21:56.400 example an axis storage
00:21:57.960 and for the picture tag
00:22:00.059 I wanted to support the three use cases
00:22:02.280 I mentioned so you can pass a Blog so
00:22:05.100 you have full control on what you are
00:22:07.140 generating
00:22:08.460 you can pass an array so an array of
00:22:11.159 sources and this is going to handle
00:22:12.780 automatically automatically by by the
00:22:15.059 picture tag and also what I said before
00:22:17.460 automatic inference I mean you just pass
00:22:20.039 ad Webb option and that is going to work
00:22:23.820 so I'm going to show a little bit of
00:22:25.799 code here
00:22:26.820 so you get the sense of what is done
00:22:29.760 what happened has been done
00:22:31.679 for the static assets this is like a
00:22:34.740 rate dust basically I'm hooking into the
00:22:38.460 acid pre-compile task so you just put an
00:22:41.580 enhance and this code is going to be run
00:22:44.520 every time another pre-compiled task
00:22:46.679 each run
00:22:47.820 so basically forage image that we have
00:22:51.299 on public assets we just iterate that
00:22:55.080 and we convert that to webpage so it's
00:22:57.780 pretty simple
00:23:00.179 for the dynamic assets if you're using
00:23:02.820 Hardware you just include a module there
00:23:06.020 and you have a helper method that says
00:23:09.240 convert to webp and that's it you don't
00:23:11.340 have to do anymore
00:23:13.260 and if you're using active storage
00:23:15.840 just convert web B format with b and you
00:23:18.780 have a variant that it's a web B
00:23:21.600 yeah there's a little caveat for
00:23:23.760 electric storage it's like you need to
00:23:25.380 enable baps which is a image processing
00:23:28.440 library but it's just a configuration on
00:23:30.179 Rails it's pretty simple
00:23:34.559 well the picture tag helper I'm going to
00:23:37.320 show you first how it looks like and
00:23:39.659 then how it works
00:23:42.120 here it's an example of the picture Tau
00:23:45.360 with when you specify the Apple block so
00:23:47.820 you have full control of what is being
00:23:49.679 generated it's pretty similar to what it
00:23:52.140 ends up being generated on a picture tag
00:23:54.860 you just specify a Blog there with the
00:23:57.539 do and that's it you can specify
00:24:00.240 multiple sources
00:24:01.799 what about if you have like an array of
00:24:04.500 elements well you can just pass that
00:24:07.380 an array of filaments of multiple image
00:24:10.260 formats multiple resolutions whatever
00:24:12.120 this is going to be generated as
00:24:14.580 multiple sources so again pretty simple
00:24:18.419 and the option that I like is like okay
00:24:20.220 I have my image in PNG I just put the
00:24:24.419 image PNG at web B true and that is
00:24:27.900 going to generate the web B
00:24:29.580 automatically
00:24:32.760 well how this works well again pretty
00:24:35.340 simple how it works I just Define a
00:24:38.039 picture tag helper and that basically
00:24:41.520 tries to mimic the signature of the
00:24:43.980 image tag
00:24:45.960 function so it receives a source some
00:24:48.659 options and a Blog that can be optional
00:24:51.960 so I wrap everything everything on a
00:24:55.620 Content tag picture which is like the
00:24:58.080 picture that is wrapping everything
00:24:59.340 there
00:25:01.260 and inside that I just passed a log and
00:25:03.900 that's it I have a helper method that
00:25:05.520 generates all the sources so why how
00:25:08.100 does it look like the picture the build
00:25:10.320 picture content helper model metal well
00:25:13.020 it receives a source some options and a
00:25:15.240 block and basically if you're passing a
00:25:18.000 Blog you're here I just captured that
00:25:21.059 block and that is going to be the
00:25:22.620 content of the HTML tag
00:25:25.980 and at the end I
00:25:27.900 append the image tag so you're we are
00:25:31.679 generating this case here so I specify a
00:25:35.700 Blog on top and then the blog is going
00:25:39.120 to be passed to the picture tag and at
00:25:40.799 the end I'm generating an animation
00:25:44.100 and if you're not passing a Blog you're
00:25:46.440 passing a
00:25:47.760 sorry here you are passing an array or a
00:25:50.640 string it's just I convert that to an
00:25:52.500 array either I iterate that and for each
00:25:55.559 one I create the source and that's it
00:25:57.900 pretty simple and at the end I
00:25:59.940 concatenate the image tag
00:26:02.279 I have a couple of helper methods that
00:26:04.260 you can check on the on the gem and
00:26:07.500 on the rebel but
00:26:10.500 you might be asking okay what is all of
00:26:13.740 this worth it well yeah in the end we
00:26:17.039 end up saving like one second of loading
00:26:19.500 times on our websites and if you can see
00:26:22.559 here we there are a couple of images
00:26:24.480 here for example the first one was 700
00:26:26.940 kilobytes we we could be saving 420
00:26:31.279 435 kilobytes
00:26:34.380 so yeah that was what's important for us
00:26:37.020 so in the end it was 14 for sure and
00:26:40.740 this is before and migrating to webp and
00:26:43.919 you can see there the score at the very
00:26:46.200 top it was 79. yeah and after the
00:26:50.220 conversion we reached 99 so it increased
00:26:53.880 our SEO our loading times so yeah it's
00:26:57.720 worth it
00:26:59.400 so I wanted to edit this talk with a
00:27:02.520 yeah please test it out for sure
00:27:05.640 that's a repo link please put a stand on
00:27:08.400 it
00:27:09.440 the good thing is that we are using this
00:27:12.179 in our website so we are going to
00:27:14.039 maintain it for sure
00:27:15.720 and the next step for us are
00:27:18.419 we want to add other image format for
00:27:20.940 sure we want to add some configuration
00:27:23.100 because we are assuming that you are
00:27:24.779 using the asset digest for example that
00:27:27.000 you want to convert this to a webp maybe
00:27:28.860 you are converting that by yourself and
00:27:32.039 yeah and I want to end this talk with a
00:27:35.460 reflection which is
00:27:37.260 sometimes rails behind a false flag
00:27:40.620 behind some other Frameworks or other
00:27:43.740 Technologies until some big name like
00:27:46.500 dhh GitHub Shopify whatever needs to use
00:27:51.240 that specific case on their platform
00:27:55.200 and it was and this was like a real
00:27:57.360 specific use case that we wanted to
00:27:59.820 improve and it took me like 100 lines of
00:28:03.000 code and some of my time it wasn't
00:28:06.000 darkhar it wasn't that hard so I think
00:28:08.880 that we can all contribute to this
00:28:10.980 amazing framework and make it better so
00:28:13.500 this is an invitation for you to make a
00:28:15.779 new jam
00:28:17.279 and that's pretty much it
00:28:19.320 thanks