Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SITE] Image Rendering #14341

Open
wants to merge 32 commits into
base: main
Choose a base branch
from
Open

Conversation

toshywoshy
Copy link
Contributor

This PR renders all images to webp using hugo extended features
The codes enables images within the assets/ folder to be rendered, while mainting the existing static/ folders.
It converts any image format into webp using compression, and resizing the image.

The following images are rendering

To prove the pages work, I have added 2024-antwerp examples, proving that a mix of static/ and assets folders work, with a preference of using the assets/ over static/

* the event page logos render to 236x236, making all logos square devopsdays#14336
* the welcome page shortcode will render the event logo

Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
@toshywoshy toshywoshy requested review from a team as code owners July 13, 2024 23:42
Copy link

netlify bot commented Jul 13, 2024

Deploy Preview for devopsdays-web ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit c80824e
🔍 Latest deploy log https://app.netlify.com/sites/devopsdays-web/deploys/66e9eac905a7bd00086d7cd8
😎 Deploy Preview https://deploy-preview-14341--devopsdays-web.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@mattstratton
Copy link
Member

First pass, this looks good! I need to dig into it on my computer to fully approve but think it is likely a good one!

@toshywoshy
Copy link
Contributor Author

I know this PR does not add documentation and I prefer to do that after this PR, it is optional so nothing should break.
Only if you use the assets/events/<year>-<city>/ does it look at those folders.

Just for extra information, relating to #14336 , you can test the square resizing with the Cairo event image on the index page

{{- if (where (readDir "assets/sponsors/") "Name" $imagefilename) -}}
{{- $imagelocation := (printf "sponsors/%s" $imagefilename) -}}
{{- $imageresource := resources.Get $imagelocation -}}
{{- $imagefile := $imageresource.Fit "600x600 webp Lanczos q100" -}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think we want the sponsor image to be 600x600?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have them all mostly at 600x600, this is just to make them fit nicely, we should have them with the correct sizing per type, so the result is smaller in file size

What would be best for the sizing for each of these

  • Welcome page : 236x236
  • Sponsor logos
  • Speaker page
  • Program Talk Page
  • Organizers Page

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I have them all mostly at 600x600, this is just to make them fit nicely, we should have them with the correct sizing per type, so the result is smaller in file size

What would be best for the sizing for each of these

  • Welcome page : 236x236
  • Sponsor logos
  • Speaker page
  • Program Talk Page
  • Organizers Page

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Welcome page : 236x236 (i think? this might be too small; maybe double it?)
Sponsor logos: (see below)
Speaker page: (assume you mean speaker headshots, these should be 600 x 600)
Program Talk Page: Same as speaker page (600x600)
Organizers Page: Same as speaker page (600x600)

if we wanted to go smaller, the "headshot" type images (speaker, organizer, talk) can all be 300x300 but iirc the way we are doing responsive/retina images, we want them at the 2x size. that said, that could be Old Way of Doing Things (also since it's a build time sizing, we can try it smaller and see how they look and it's non-destructive)

For sponsors, the guidance we have given is:

The dimensions of the image file must be at least 200px wide. 600px will look best for high-density display.
The background must be either white or transparent.
Images do not need to be square, but they may look better if they are.

so I don't think we hard code both height and width, I think we just set it to 600px wide and let height go proportional?

@mattstratton
Copy link
Member

Adding a comment for future implementation; the sizing of various images should be set in the config/_default/hugo.yml instead of being hardcoded, but we can add that later!

@mattstratton mattstratton requested a review from a team as a code owner September 13, 2024 18:28
* the event page logos render to 236x236, making all logos square devopsdays#14336
* the welcome page shortcode will render the event logo

Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
@mattstratton
Copy link
Member

okay it's breaking if there is a folder for the event in the assets directory, but none of the subfolders

example:

ERROR render of "page" failed: "/Users/matty.stratton/src/github.com/devopsdays/devopsdays-web/themes/devopsdays-theme/layouts/speaker/single.html:48:23": execute of template failed: template: speaker/single.html:48:23: executing "main" at <readDir $assetspeakersfolder>: error calling readDir: failed to read directory "assets/events/2024-cairo/speakers/": open /Users/matty.stratton/src/github.com/devopsdays/devopsdays-web/assets/events/2024-cairo/speakers: no such file or directory
ERROR render of "page" failed: "/Users/matty.stratton/src/github.com/devopsdays/devopsdays-web/themes/devopsdays-theme/layouts/speakers/single.html:17:31": execute of template failed: template: speakers/single.html:17:31: executing "main" at <readDir $assetspeakersfolder>: error calling readDir: failed to read directory "assets/events/2024-cairo/speakers/": open /Users/matty.stratton/src/github.com/devopsdays/devopsdays-web/assets/events/2024-cairo/speakers: no such file or directory
ERROR render of "page" failed: "/Users/matty.stratton/src/github.com/devopsdays/devopsdays-web/themes/devopsdays-theme/layouts/talk/single.html:155:29": execute of template failed: template: talk/single.html:155:29: executing "main" at <readDir $assetspeakersfolder>: error calling readDir: failed to read directory "assets/events/2024-organiser-summit/speakers/": open /Users/matty.stratton/src/github.com/devopsdays/devopsdays-web/assets/events/2024-organiser-summit/speakers: no such file or directory
Built in 17048 ms
Error: error building site: render: failed to render pages: render of "page" failed: "/Users/matty.stratton/src/github.com/devopsdays/devopsdays-web/themes/devopsdays-theme/layouts/speaker/single.html:48:23": execute of template failed: template: speaker/single.html:48:23: executing "main" at <readDir $assetspeakersfolder>: error calling readDir: failed to read directory "assets/events/2024-cairo/speakers/": open /Users/matty.stratton/src/github.com/devopsdays/devopsdays-web/assets/events/2024-cairo/speakers: no such file or directory

@mattstratton
Copy link
Member

A little experimenting...

Here is the build performance with the POC images only:

Template Metrics:

       cumulative       average       maximum      cache  percent  cached  total
         duration      duration      duration  potential   cached   count  count  template
       ----------      --------      --------  ---------  -------  ------  -----  --------
  3m29.810621322s    18.78845ms  896.842041ms         10        0       0  11167  partials/head.html
  2m35.571748609s   42.459538ms   300.73775ms          0        0       0   3664  talk/single.html
  1m56.045205677s   46.306945ms  903.917333ms          0        0       0   2506  event/single.html
  1m30.491326483s     22.3933ms  202.150667ms          0        0       0   4041  speaker/single.html
   1m5.824077475s    5.894517ms  181.057917ms         79        0       0  11167  partials/head_includes.html
    54.774728289s  137.624945ms    359.1345ms          0        0       0    398  welcome/single.html
    47.133867883s    4.220817ms  889.704791ms          5        0       0  11167  partials/head/seo.html
    33.140333166s    2.989385ms  113.396708ms         14       19    2101  11086  partials/sponsors.html
     30.94506721s   76.596701ms  201.209583ms          5        0       0    404  partials/welcome.html
    29.193036826s    2.614223ms  101.757542ms         84        0       0  11167  partials/google_analytics.html
    26.019238678s    2.330011ms    176.0535ms         97        0       0  11167  partials/google_tag_manager.html
    25.547085304s     2.28773ms  111.189875ms         61        0       0  11167  partials/footer_scripts.html
    23.482394011s    2.114959ms  175.641167ms         61        0       0  11103  partials/events/event_navbar.html
    17.570542508s   75.735097ms   253.39925ms          0        0       0    232  program/single.html
    17.158263086s   70.033726ms  277.388333ms          0        0       0    245  speakers/single.html
     5.620149525s      60.673µs   29.403875ms          0        0       0  92629  partials/functions/get-event-data.html
     4.917110832s  136.586412ms     737.119ms          0        0       0     36  blog/single.html
      4.76719921s   95.343984ms  653.820333ms        100       98      49     50  partials/future.html
      4.56709518s    2.593466ms  105.011417ms          0        0       0   1761  shortcodes/event_link.html
     3.142301964s    7.797275ms  886.820084ms          0        0       0    403  shortcodes/list_organizers.html
     3.034237706s    2.694704ms   99.381666ms          0        0       0   1126  shortcodes/email_organizers.html
     2.757882337s    6.826441ms   101.13925ms         60        0       0    404  partials/events/cta.html
     1.812446457s  139.418958ms  224.418166ms          0        0       0     13  events/single.html
     1.637389251s    5.069316ms   175.76075ms          0        0       0    323  shortcodes/event_logo.html
     1.636380043s    4.483232ms   98.054375ms          0        0       0    365  shortcodes/event_start.html
     1.361291459s   68.064572ms  652.603709ms        100        0       0     20  partials/functions/get-upcoming-events.html
      1.25012978s    3.918902ms  179.619459ms          0        0       0    319  shortcodes/event_map.html
     1.072926287s    2.572964ms   16.743667ms        100        0       0    417  partials/functions/get-all-events.html
     1.024647162s    3.595253ms   99.086416ms          0        0       0    285  shortcodes/event_location.html
     984.117172ms    3.154221ms   69.747166ms          0        0       0    312  shortcodes/event_end.html
     963.462757ms    2.768571ms   75.150458ms          0        0       0    348  shortcodes/event_twitter.html
      827.16333ms   34.465138ms  130.088791ms          0        0       0     24  _default/single.html
     740.963624ms  185.240906ms  733.665541ms          0        0       0      4  section/blog.html
     738.296208ms  738.296208ms  738.296208ms          0        0       0      1  404.html
     735.912792ms  735.912792ms  735.912792ms          0        0       0      1  index.html
     723.544951ms    2.395844ms  105.090458ms          0        0       0    302  shortcodes/cfp_dates.html
     688.521706ms      61.656µs   75.050042ms        100      100   11166  11167  partials/footer.html
     250.294874ms     9.27018ms  243.629584ms          0        0       0     27  _internal/_default/rss.xml
     229.905291ms  229.905291ms  229.905291ms          0        0       0      1  _internal/_default/sitemap.xml
     193.345125ms  193.345125ms  193.345125ms          0        0       0      1  sponsor/single.html
     192.434167ms  192.434167ms  192.434167ms          0        0       0      1  speaking/single.html
     188.769042ms  188.769042ms  188.769042ms        100        0       0      1  partials/speaking.html
     137.902792ms  137.902792ms  137.902792ms        100        0       0      1  partials/sponsors-accepted.html
      99.516207ms    2.551697ms   52.490458ms          0        0       0     39  shortcodes/email_proposals.html
      69.732192ms       6.244µs    1.678708ms        100        0       0  11167  partials/meta.html
      61.499484ms      22.209µs     5.82375ms          0        0       0   2769  _default/_markup/render-link.html
      28.177782ms       2.523µs     6.55125ms        100      100   11166  11167  partials/global_navbar.html
      21.610958ms    1.543639ms    2.704666ms        100        0       0     14  partials/functions/get-tbd-events.html
       7.500791ms    7.500791ms    7.500791ms          0        0       0      1  section/events.rss.xml
       6.561877ms     182.274µs    1.309542ms          0        0       0     36  blog/summary.html
       6.476819ms       8.499µs         310µs          0        0       0    762  _internal/alias.html
       6.140667ms    6.140667ms    6.140667ms          0        0       0      1  section/speaking.rss.xml
       1.993167ms    1.993167ms    1.993167ms          0        0       0      1  shortcodes/registration_end.html
       1.773292ms     354.658µs    1.757208ms          0        0       0      5  shortcodes/emoji.html
       1.494125ms    1.494125ms    1.494125ms          0        0       0      1  shortcodes/registration_start.html
       1.297958ms    1.297958ms    1.297958ms        100        0       0      1  partials/toc.html
       1.055958ms    1.055958ms    1.055958ms          0        0       0      1  section/blog.rss.xml
        1.00175ms      41.739µs     200.542µs          0        0       0     24  _default/_markup/render-image.html
        726.166µs     145.233µs     311.625µs          0        0       0      5  _internal/shortcodes/youtube.html
        475.375µs      79.229µs     253.209µs          0        0       0      6  _internal/shortcodes/figure.html
        296.001µs          74µs     143.417µs         50        0       0      4  partials/functions/get-cfp-url.html
        219.121µs         545ns       50.25µs          0        0       0    402  shortcodes/list_core.html
        206.918µs      51.729µs     134.292µs         38        0       0      4  partials/blog_pagination.html
         163.25µs      163.25µs      163.25µs        100        0       0      1  partials/heading_link.html
        148.542µs     148.542µs     148.542µs          0        0       0      1  shortcodes/list_core_active.html
        135.583µs      67.791µs     124.792µs          0        0       0      2  shortcodes/tix.html
        135.459µs      67.729µs     130.334µs          0        0       0      2  _internal/shortcodes/param.html
        129.166µs      25.833µs     105.333µs          0        0       0      5  shortcodes/google_form.html
        128.625µs     128.625µs     128.625µs          0        0       0      1  shortcodes/list_core_emeritus.html
            118µs         118µs         118µs          0        0       0      1  shortcodes/list_core_advisory.html
        113.584µs     113.584µs     113.584µs          0        0       0      1  shortcodes/privacy_policy.html
         75.044µs        2.68µs      64.375µs          0        0       0     28  _default/list.html


                   |  EN
-------------------+--------
  Pages            | 11195
  Paginator pages  |     3
  Non-page files   |    82
  Static files     | 17427
  Processed images |    46
  Aliases          |   762
  Cleaned          |     0

Total in 47866 ms

This is the build performance when the full sponsor image directory is used in the assets folder:

Template Metrics:

       cumulative       average       maximum      cache  percent  cached  total
         duration      duration      duration  potential   cached   count  count  template
       ----------      --------      --------  ---------  -------  ------  -----  --------
  1h32m38.252962024s  501.692658ms  1.955090917s         10       19    2089  11079  partials/sponsors.html
  40m47.347144787s  605.629088ms  1.746289125s          0        0       0   4041  speaker/single.html
  38m7.922566837s  624.433014ms  1.742393042s          0        0       0   3664  talk/single.html
  10m5.153871177s  241.481991ms   1.95864625s          0        0       0   2506  event/single.html
  2m31.792351277s  381.387817ms  1.572632833s          0        0       0    398  welcome/single.html
  2m15.886438507s  554.638524ms  1.750853375s          0        0       0    245  speakers/single.html
  1m55.961051832s  499.832119ms  1.616213583s          0        0       0    232  program/single.html
    1m3.13823594s    5.654001ms  141.553459ms         10        0       0  11167  partials/head.html
    31.059644374s   76.880307ms  194.016833ms          5        0       0    404  partials/welcome.html
    19.384101989s    1.735837ms  106.259209ms         79        0       0  11167  partials/head_includes.html
    18.095954533s    1.620484ms  125.526167ms          5        0       0  11167  partials/head/seo.html
     9.137825224s     830.107µs   97.764125ms         61        0       0  11008  partials/footer_scripts.html
     8.829076136s     795.197µs    134.0875ms         61        0       0  11103  partials/events/event_navbar.html
     8.724770283s     781.299µs   77.243083ms         84        0       0  11167  partials/google_analytics.html
     8.312666248s     744.395µs  104.571416ms         97        0       0  11167  partials/google_tag_manager.html
     7.939473581s      85.855µs     26.5585ms          0        0       0  92475  partials/functions/get-event-data.html
     4.857959874s  134.943329ms  726.987583ms          0        0       0     36  blog/single.html
      4.62246575s   92.449315ms   620.61675ms        100       98      49     50  partials/future.html
     1.654041374s  127.233951ms  205.220875ms          0        0       0     13  events/single.html
     1.621252425s    5.019357ms   55.413917ms          0        0       0    323  shortcodes/event_logo.html
     1.292096279s    3.198258ms   96.633958ms         60        0       0    404  partials/events/cta.html
     1.288777455s    3.090593ms   26.782709ms        100        0       0    417  partials/functions/get-all-events.html
     1.285456792s   71.414266ms  615.167333ms        100        0       0     18  partials/functions/get-upcoming-events.html
     1.175289998s     667.399µs   55.157167ms          0        0       0   1761  shortcodes/event_link.html
     1.169439979s    1.038579ms   79.949542ms          0        0       0   1126  shortcodes/email_organizers.html
     873.800447ms      79.378µs   90.340375ms        100      100   11007  11008  partials/footer.html
     773.668203ms    1.919772ms   54.044875ms          0        0       0    403  shortcodes/list_organizers.html
     728.132418ms  182.033104ms    720.4175ms          0        0       0      4  section/blog.html
     718.658542ms  718.658542ms  718.658542ms          0        0       0      1  index.html
     710.904375ms  710.904375ms  710.904375ms          0        0       0      1  404.html
     445.737208ms    1.221197ms    52.00675ms          0        0       0    365  shortcodes/event_start.html
     423.798542ms    1.328522ms   57.771083ms          0        0       0    319  shortcodes/event_map.html
     415.950049ms    1.377318ms   74.002583ms          0        0       0    302  shortcodes/cfp_dates.html
     313.619623ms   13.067484ms  194.795125ms          0        0       0     24  _default/single.html
     245.008504ms     785.283µs   52.391542ms          0        0       0    312  shortcodes/event_end.html
     224.856166ms  224.856166ms  224.856166ms          0        0       0      1  _internal/_default/sitemap.xml
     219.994704ms     771.911µs   52.139542ms          0        0       0    285  shortcodes/event_location.html
     198.828672ms     571.346µs   25.958833ms          0        0       0    348  shortcodes/event_twitter.html
     193.024875ms  193.024875ms  193.024875ms          0        0       0      1  sponsor/single.html
      107.08746ms       9.589µs    3.047166ms        100        0       0  11167  partials/meta.html
      85.376167ms   85.376167ms   85.376167ms          0        0       0      1  speaking/single.html
      80.948625ms   80.948625ms   80.948625ms        100        0       0      1  partials/sponsors-accepted.html
       74.89026ms      27.045µs    2.906041ms          0        0       0   2769  _default/_markup/render-link.html
      54.810708ms       4.908µs    6.568291ms        100      100   11166  11167  partials/global_navbar.html
      20.576167ms     527.594µs    2.061958ms          0        0       0     39  shortcodes/email_proposals.html
      20.540667ms     1.46719ms    1.711334ms        100        0       0     14  partials/functions/get-tbd-events.html
       7.855792ms    7.855792ms    7.855792ms          0        0       0      1  shortcodes/registration_end.html
       6.895673ms       9.049µs     817.917µs          0        0       0    762  _internal/alias.html
       6.365582ms     176.821µs       1.243ms          0        0       0     36  blog/summary.html
        6.01425ms     6.01425ms     6.01425ms        100        0       0      1  partials/speaking.html
       1.395375ms    1.395375ms    1.395375ms        100        0       0      1  partials/toc.html
       1.344874ms     268.974µs    1.328625ms          0        0       0      5  shortcodes/emoji.html
       1.211131ms       3.012µs     902.208µs          0        0       0    402  shortcodes/list_core.html
       1.040459ms      43.352µs     213.584µs          0        0       0     24  _default/_markup/render-image.html
        647.167µs     129.433µs     173.792µs          0        0       0      5  _internal/shortcodes/youtube.html
        464.791µs     464.791µs     464.791µs          0        0       0      1  shortcodes/registration_start.html
        311.624µs      51.937µs     122.416µs          0        0       0      6  _internal/shortcodes/figure.html
         240.75µs      60.187µs     125.417µs         38        0       0      4  partials/blog_pagination.html
        233.041µs      116.52µs         222µs          0        0       0      2  shortcodes/tix.html
        229.709µs      57.427µs     141.458µs         50        0       0      4  partials/functions/get-cfp-url.html
        220.417µs      44.083µs     191.417µs          0        0       0      5  shortcodes/google_form.html
        168.208µs     168.208µs     168.208µs        100        0       0      1  partials/heading_link.html
        145.667µs     145.667µs     145.667µs          0        0       0      1  shortcodes/list_core_active.html
        132.833µs      66.416µs     117.708µs          0        0       0      2  _internal/shortcodes/param.html
        129.125µs     129.125µs     129.125µs          0        0       0      1  shortcodes/list_core_emeritus.html
        117.333µs     117.333µs     117.333µs          0        0       0      1  shortcodes/list_core_advisory.html
        113.291µs     113.291µs     113.291µs          0        0       0      1  shortcodes/privacy_policy.html
         69.464µs        2.48µs      66.167µs          0        0       0     28  _default/list.html

Total in 576858 ms

(also random error - Error: error building site: render: failed to render pages: render of "page" failed: "/Users/matty.stratton/src/github.com/devopsdays/devopsdays-web/themes/devopsdays-theme/layouts/talk/single.html:244:4": execute of template failed: template: talk/single.html:244:4: executing "main" at <partial "sponsors.html" .>: error calling partial: "/Users/matty.stratton/src/github.com/devopsdays/devopsdays-web/themes/devopsdays-theme/layouts/partials/sponsors.html:82:52": execute of template failed: template: partials/sponsors.html:82:52: executing "partials/sponsors.html" at <$imageresource.Fit>: error calling Fit: fit /sponsors/dasa.png: png: invalid format: invalid checksum


To summarize:

When it only has to process a few images, the build (on my laptop) takes a little less than 1 minute. When the full sponsor directory is used, it takes 9.5 minutes.

I'm doing a test now to see how long it takes on builds when things have not changed (most sponsor images, once generated, will never change) but note: on deploy previews, it is a completely fresh build every time, so our deploy previews will take AT LEAST 10 minutes (probably longer, as the netlify build containers are less powerful than my laptop) and likely will time out.

Copy link
Member

@mattstratton mattstratton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to address/revisit the build performance implications of this prior to merging, even with the small "opt in" version IMHO

@mattstratton
Copy link
Member

I'm doing a test now to see how long it takes on builds when things have not changed

Update: subsequent build was only about 30 seconds faster :/

@don-code
Copy link
Contributor

These images don't change. Some possibly heretical ideas to take advantage of that:

  1. Place a cache in Git. Build WebP images when their JPEG/PNG sources change. This could be paired with a lighter-weight CI check to make sure the cache is populated, failing the build with some explicit instructions for the user to populate the cache.
  2. Auto-generate a cache as part of CI. Same as above, except the CI pipeline commits changes back to the user's branch. Confusing for multi-commit PRs (you could get merge conflicts with your own branch!), but potentially faster and easier to use for the average MR.
  3. Just fail the build if new JPEG/PNG images are committed. Require all images to natively be correctly-sized WebP via a CI check. Probably the most disruptive option, as it requires committers to run extra steps to resize and commit WebP images, but also the fastest to implement. Pair this with a commit of all existing JPEG/PNG images as WebP.

@toshywoshy
Copy link
Contributor Author

This is good to go - however, we will need a fast (ish?) follow on a few tasks

* update documentation to explain how to use this

OK, should we have that added in this PR or create a new linked PR

* update various scripts to put images in the assets folder instead of static

I have never used any of these scripts, but they are bash, so I can update them.
The question is should it ask or enforce the new assets folder?

* move images (as makes sense) from static to assets (thinking that we should migrate sponsor images at least)

Well, yes, those would be a good first target and a good test of endurance.

We need to address/revisit the build performance implications of this prior to merging, even with the small "opt in" version IMHO

Ok, so my tests are as follows, first number without cache, second number with cache
Standard deploy in [main] : 9,5 s => 9.4s
Logo rendering deploy in [logorendering] with all sponsors starting with the letter 'e": 42,44 s => 10,5 s
Logo rendering deploy in [logorendering] with all sponsors logos : 14,48m => 18,5m

I tested my other Hugo setups and most have image folders of no more than 200 images per folder.
Most of my setups have about 500 images in total, with one other setup of 1000 images, however all of these are spread over several folders with one folder being 250 images at max.
Having tested those setups again and adding caching to them seem to indicate that an initial run takes about 1 minute and then falls back to the normal deploy of 5 to 15 seconds.

We seem to suffer from the folder overload problem, the static folder just gets copied, however the assets folder get interpretated, so Hugo does file actions on these and there the filtering takes much too long.
The image rendering of Hugo for about 200 to 250 PNG images should take about 30 to 45 seconds, as per my tests.
I think I need to update the logic to have the assets/sponsors/ folder alphabetized, this would optimize some of those folder/file searches and would enable us to have the archive folder under the number 2 folder.
This also means that we take the first letter of the sponsor and use that the create assets/sponsors/#/ with the carre being the letter and there for about result in folders of no more than 300 at present division.

I will update the branch and run some more tests after which I hope @mattstratton can confirm that the improvement also enhanced the build time.
We also need to look at the deploy script and add caching in there, so I will make an attempt at solving that too.

I'm doing a test now to see how long it takes on builds when things have not changed

Update: subsequent build was only about 30 seconds faster :/

Unless caching is added, the build time will to speed up, the difference here seems to be resource bound and not actually Hugo doing anything differently.

These images don't change. Some possibly heretical ideas to take advantage of that:

1. **Place a cache in Git.** Build WebP images when their JPEG/PNG sources change. This could be paired with a lighter-weight CI check to make sure the cache is populated, failing the build with some explicit instructions for the user to populate the cache.

Well, actually Hugo has this options, I presumed we had the cache already built in, however @mattstratton tests show the cache not being used correctly and we need to optimize for that.

2. **Auto-generate a cache as part of CI.** Same as above, except the CI pipeline commits changes back to the user's branch. Confusing for multi-commit PRs (you could get merge conflicts with your own branch!), but potentially faster and easier to use for the average MR.

Yes, we need Netlify to build with the cache, I did see some reference in the Hugo and Netlify documentation and I will try to use that.
We also need to think about how the CI builds run, we might not need to build everything every time, but that is something for later.

3. **Just fail the build if new JPEG/PNG images are committed.** Require all images to natively be correctly-sized WebP via a CI check. Probably the most disruptive option, as it requires committers to run extra steps to resize and commit WebP images, but also the fastest to implement. Pair this with a commit of all existing JPEG/PNG images as WebP.

No, that negated the purpose of using Hugo Image Pipes, and would mean that we add more work for individual event organisers.

@mattstratton
Copy link
Member

I've thought about the "divide the sponsor folder up by first initial" thing before; my concern is more about how to keep that enforced? I guess we can put some logic into the linter for pull requests, and watch out for it, but I am slightly concerned about people not following this :)

it's not necessarily a reason not to do it, but we def need to make sure it's easy to catch doing it the "wrong" way (ask me how I know, after almost ten years of merging PRs here LOL)

@mattstratton
Copy link
Member

mattstratton commented Sep 17, 2024

Yes, we need Netlify to build with the cache, I did see some reference in the Hugo and Netlify documentation and I will try to use that.

I'm guessing it's this?

https://www.netlify.com/integrations/community-built/hugo-cache-resources-build-plugin/

I do wonder about intiial local builds however; remember that lots of folks run this once a year, and even though we have codespaces, gitpod, etc, most folks are building it locally

although I guess that cache is also stored in git somehow? So when they clone it down...

...which can make the repo bloat, right? which is also a concern we have

hmm

Netlify
Persist Hugo resources folder between Netlify builds for huge build speed improvements!

@mattstratton
Copy link
Member

i suspect if we want to keep the file cache of the processed assets, then this line should be removed from .gitignore (I added it the other day but it's not going to be causing any of the current issues with local builds)

/resources/_gen

@mattstratton
Copy link
Member

Well, actually Hugo has this options, I presumed we had the cache already built in, however @mattstratton tests show the cache not being used correctly and we need to optimize for that.

i'm confused about how this is not set correctly? From what I can read, it just works by default. The cache potential values in the output from my tests are about caching partials, not asset resource caching?

{{- if (where (readDir "static/events") "Name" $e.name) -}}
{{- $.Scratch.Set "assetsdir" (printf "assets/events/%s/" $e.name) -}}
{{- if (where (readDir "assets/events") "Name" $e.name) -}}
{{- $imagelocation := (printf "events/%s/logo.png" $e.name) -}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you look below, you'll see that we support the logo being JPG as well. this bails if it looks for .png and finds .jpg instead. at minimum we should put in a check for the .png file existing (bc the assets dir might be there but using a jpg version)

@don-code
Copy link
Contributor

although I guess that cache is also stored in git somehow? So when they clone it down...

...which can make the repo bloat, right? which is also a concern we have

If we want a cheap and easy way to save a few gigs today, we never (to my knowledge) did the follow-up on #13018, which was to run BFG9000 on the repo to eliminate all of the now-removed historical images from the repository. I'll make a scientific wild-ass guess that cleaning up the repo, then committing the entire site's worth of cache, would still be smaller than the current state.

Signed-off-by: Toshaan Bharvani <[email protected]>
* add caching to prevent rebuilding everything everytime
* enable stats so we can understand the build speed

Signed-off-by: Toshaan Bharvani <[email protected]>
@toshywoshy toshywoshy requested a review from a team as a code owner September 17, 2024 14:22
@toshywoshy
Copy link
Contributor Author

toshywoshy commented Sep 17, 2024

I've thought about the "divide the sponsor folder up by first initial" thing before; my concern is more about how to keep that enforced? I guess we can put some logic into the linter for pull requests, and watch out for it, but I am slightly concerned about people not following this :)

Yes, I understand the concern, and I think while the number of files was smaller, it would be an unnecessary overhead, however, at present I think we need to find a way to solve this.

it's not necessarily a reason not to do it, but we def need to make sure it's easy to catch doing it the "wrong" way (ask me how I know, after almost ten years of merging PRs here LOL)

I also understand that now much better, and I think adding a check for that is the only way
At present I am more concerned with the correct splitting and after splitting that we actually get improvements.

Yes, we need Netlify to build with the cache, I did see some reference in the Hugo and Netlify documentation and I will try to use that.

I'm guessing it's this?

https://www.netlify.com/integrations/community-built/hugo-cache-resources-build-plugin/

Yes, that and maybe also enable it in the deploy script

I do wonder about intiial local builds however; remember that lots of folks run this once a year, and even though we have codespaces, gitpod, etc, most folks are building it locally

although I guess that cache is also stored in git somehow? So when they clone it down...

No, I do not think we should do that, HugoIO creates the caches locally and these should not be in the git repository.

...which can make the repo bloat, right? which is also a concern we have

Unless we want a cache repository as a submodule that gets updated once in a while, while the embedded folders remains empty, or a artifact repository you can download with the cached data.
We could even have that in the build scripts to download the latest cache.
I am not in favour of creating more bloat, niether of having cache in a main repository.

Netlify
Persist Hugo resources folder between Netlify builds for huge build speed improvements!

@mattstratton
Copy link
Member

Yes, I understand the concern, and I think while the number of files was smaller, it would be an unnecessary overhead, however, at present I think we need to find a way to solve this.

To be clear, I am not saying this is a reason not to divvy it up, I am very much in favor of it for a few reasons! Just was thinking though the things we would want to account for (vs saying it as a reason not to do it!)

Yes, that and maybe also enable it in the deploy script

you don't even really enable it in a script, per se, it's just a netlify plugin that goes in the config - easy!

Unless we want a cache repository as a submodule that gets updated once in a while, while the embedded folders remains empty, or a artifact repository you can download with the cached data.
We could even have that in the build scripts to download the latest cache.
I am not in favour of creating more bloat, niether of having cache in a main repository.

Definitely no on submodules! I think that if splitting this up means a local build still runs reasonably, then it's a non issue. I was confused about the "cache configuration" but I understand a few things better after seeing the latest stuff to this PR, thanks!

I realize this is a LOT of back and forth on this PR, but this is really a huge (and important!) improvement and I'm glad we are spending the time on getting it right - that's awesome!

* move all static sponsor images to the assets folder
* alphabetize the sorting to use the first letter
* remove several images that generate problems
    - lenovo.png
    - oracle-mysql.png
    - netlabs.png
    - igv.png
    - nexa.png
    - universidad-de-montevideo.png
    - montevideocomm.png
    - idatha.png
  there may be more, but this is the list I found

Signed-off-by: Toshaan Bharvani <[email protected]>
images not copied from static
* dasa.png
* devops-meetup-capetown.png

Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
Signed-off-by: Toshaan Bharvani <[email protected]>
@toshywoshy
Copy link
Contributor Author

Yes, I understand the concern, and I think while the number of files was smaller, it would be an unnecessary overhead, however, at present I think we need to find a way to solve this.

To be clear, I am not saying this is a reason not to divvy it up, I am very much in favor of it for a few reasons! Just was thinking though the things we would want to account for (vs saying it as a reason not to do it!)

Well, it has been done now, so lets see how this works out over time.
The logic takes the first letter of the sponsor and uses that in the folder index

At present with the alpabetised folders builds between 35 s and 50 s (cached) on my laptop and about 2m30s in Netlify

Yes, that and maybe also enable it in the deploy script

you don't even really enable it in a script, per se, it's just a netlify plugin that goes in the config - easy!

Well, I did it in the config, not sure if it is working, but you can add it to the netlify.tomlfile as a plugin.
Again not sure if that works without you having to enable it in the GUI or as an admin
From the numbers I suspect the cache is not (yet) working.

Unless we want a cache repository as a submodule that gets updated once in a while, while the embedded folders remains empty, or a artifact repository you can download with the cached data.
We could even have that in the build scripts to download the latest cache.
I am not in favour of creating more bloat, niether of having cache in a main repository.

Definitely no on submodules! I think that if splitting this up means a local build still runs reasonably, then it's a non issue. I was confused about the "cache configuration" but I understand a few things better after seeing the latest stuff to this PR, thanks!

OK, so a "full" build without any resources/ takes about 1m30s, while a subsequent build with cache takes about 35s.
This is on my laptop running a make file to run builds.
I am sure we can improve that over time, but these numbers seem acceptable enought to me

I realize this is a LOT of back and forth on this PR, but this is really a huge (and important!) improvement and I'm glad we are spending the time on getting it right - that's awesome!

Yes, no hurry or worry, we need to check every aspect and that takes times, especially so we do not break anything.

@mattstratton
Copy link
Member

I'm doing a little bit of testing here, and had a couple of thoughts:

  1. i think that if this passes for the sponsor directory (all signs point to yes!) we should adjust the sponsors shortcode, etc, to only use the assets directory. I don't think there is any reason to make that one an "opt in".
  2. we cannot remove the /static/img/sponsors directory unfortunately, because too many of the previous "archived to static" pages will have paths to those sponsor images and will break. I think that we can clean that up later and at some point remove the static dir for the sponsors (alternate idea - move them to the assets repo and write a redirect from www to assets for antyhign looking for devopsdays.org/img/sponsors/* etc)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants