HEIGE-PCloud / DoIt

A clean, elegant and advanced blog theme for Hugo.
https://hugodoit.pages.dev
MIT License
800 stars 198 forks source link

Refactor assets management #1269

Open HEIGE-PCloud opened 6 months ago

HEIGE-PCloud commented 6 months ago

Location

Currently, all JavaScript and CSS assets are placed at the very bottom of the page. This used to be a "good practice" back in the days when defer scripts were not a thing. External script loading is blocking, so you want to defer them to the end of the page. Now we have defer scripts and defer CSS at our disposal, there is no such loading concern. By putting all resources at the bottom of the page, the browser is unaware of all these resources until it downloads and parse the entire document, which slows down the page load. By moving the assets to the head and assign them with the right fetchpriority, the browser can discover and kick of downloading all these assets in parallel for better page load perf, especially on large pages.

I am planning to move all the assets to the head, and mark all of them as defer. The process mainly involves refactoring assets.html and move it to the head at baseof.html

Code

Currently, all scripts files in the assets.html go through plugin/script.html for no good reason. This adds a level of unnecessary indirection, and plugin/script.html is difficult to maintain. Anyone trying to change anything here is first greeted with a long list of undocumented options you can pass into plugin/script.html. plugin/style.html has the similar problem.

I plan to refactor this part so that script tags are just script tags directly placed inside assets.html. We can always create small, reusable functions if needed.

SRI

The way SRI is implemented currently makes zero sense.

https://github.com/HEIGE-PCloud/DoIt/blob/74e723e79b56139c0e9c4962e0c2ebdf3fc05572/layouts/partials/plugin/script.html#L11-L22

If the user chooses to enable fingerprint in the config, a fingerprint will be generated for files that are served locally. However, there is no way for the user to specify SRI for files from the CDN. This completely defeats the purpose of SRI. SRI for local files are useless, since if these files are tempered, the HTML files can be tempered too. While SRI is mainly used to check the integrity of files served from any third parties i.e. CDNs.

The plan is the change the format of jsdelivr.yml and how init.html parses the data.

https://github.com/HEIGE-PCloud/DoIt/blob/74e723e79b56139c0e9c4962e0c2ebdf3fc05572/layouts/partials/init.html#L31-L42

My proposed new format looks like

version: 2
someJS:
  src: "https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min.js"
  integrity: "sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="

and hopefully we can keep the backwards compatibility through the version identifier. And we will remove the fingerprint option and we do not generate SRI for local files.

wu0407 commented 1 month ago

Consider to use resources.Fingerprint generate hash link " https://cdn.jsdelivr.net/npm/jquery@3.2.1/dist/jquery.min-123456adcef.js "

{{ $js := resources.Get "js/global.js" }}
{{ $secureJS := $js | resources.Fingerprint "sha512" }}
<script src="{{ $secureJS.Permalink }}" integrity="{{ $secureJS.Data.Integrity }}"></script>