? NPM Resource Changed ? Pending

User tests: Successful: Unsuccessful:

avatar dgrammatiko
dgrammatiko
29 Dec 2018

Pull Request for Issue # .

Summary of Changes

  • Add a small script to the arsenal of NPM tools so that scripts and stylesheets can be gzipped

WHY?

Performance is really crucial these days, especially since Google is accounting it as a metric to rank the pages. Joomla is not meeting the today needs. Prove that in the HTTP archive the Joomla websites rank second to last (WIX):

Link: https://discuss.httparchive.org/t/cms-performance/1468

The main reason for this is that Joomla has ALL the scripts in the head of the document and also a huge CSS file that blocks the rendering. But these cannot seem to be ok to be fixed for various reasons. So let's try to get some small wins from various tweaks.
In this PR we provide a way to gzip the script and stylesheet files ONCE (probably in the build of the installable zip files). This will free up some processor cycles in every request since the files are already gzipped so Apache or Nginx don't have to stupidly repeat the process for every request. Simple, efficient, performant. This has been my way of handling the assets for many years with 0 problems, so it's also battle tested somehow.

How to

Run the command

node build.js --build-gzip

in the root of your Joomla installation.

If you're in Apache follow the instructions here: https://httpd.apache.org/docs/2.4/mod/mod_deflate.html#page-header
Basically:

<IfModule mod_headers.c>
    # Serve gzip compressed CSS files if they exist 
    # and the client accepts gzip.
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.css" "$1\.css\.gz" [QSA]

    # Serve gzip compressed JS files if they exist 
    # and the client accepts gzip.
    RewriteCond "%{HTTP:Accept-encoding}" "gzip"
    RewriteCond "%{REQUEST_FILENAME}\.gz" -s
    RewriteRule "^(.*)\.js" "$1\.js\.gz" [QSA]


    # Serve correct content types, and prevent mod_deflate double gzip.
    RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1]
    RewriteRule "\.js\.gz$" "-" [T=text/javascript,E=no-gzip:1]


    <FilesMatch "(\.js\.gz|\.css\.gz)$">
      # Serve correct encoding type.
      Header append Content-Encoding gzip

      # Force proxies to cache gzipped & 
      # non-gzipped css/js files separately.
      Header append Vary Accept-Encoding
    </FilesMatch>
</IfModule>

Documentation Changes Required

To production team: If you accept this you need to run the command above before each realise (can be automated, I guess) and also you need to provide a solid guide based on the info above so Admins can tweak the apache/nginx configurations. Also one thing that might needs to be considered is that the size of the installable/updates will increase by a good amount of Mbs.
Lastly if this will ever be consider I also propose that you force the extensions in the JED to also provide gzipped files for all their scripts/stylesheets.

And a final word: even if you reject to actually formally follow the proposed path, you can at least provide the tool so people that want to provide decent experiences at least have the means.

avatar dgrammatiko dgrammatiko - open - 29 Dec 2018
avatar dgrammatiko dgrammatiko - change - 29 Dec 2018
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 29 Dec 2018
Category JavaScript Repository
avatar dgrammatiko dgrammatiko - change - 29 Dec 2018
Labels Added: ?
avatar richard67
richard67 - comment - 29 Dec 2018

@dgrammatiko I have done this method too before my hoster finally enabled mod_deflate for shared hosting, but I did not use extension gz, I used jgz for reasons stated here:

I suggest that you check the information linked above, and if still relevant consider to use jgz instead of gz.

avatar dgrammatiko
dgrammatiko - comment - 29 Dec 2018

I don't think any of these apply here:

  • safari v4 is outdated
  • I'm not proposing to call/use the file.js.gz directly, this is done automagically by either Apache or Nginx.

Some explanation how all this works:

  • User makes a request to our site
  • Joomla creates the html and sends it back
  • Browser parses the page, finds all the assets and starts making requests
  • Apache receives the request
  • Checks if the header that is send by the browser got the gzip deflate : eg Accept-Encoding: br, gzip, deflate
  • If gzip is supported apache through the snippet provided above will switch off the automatic gzipping of the file and serve the already stored one.

The process power released by not having to gzip files in every request is enough to raise the maximum number of concurrent client. Not to mention that this is environmentally friendly programmingⓇ

BTW the provided default snippet by apache will always switch the extensions, I guess this needs an if statement to check if the file actually exists...

avatar richard67
richard67 - comment - 29 Dec 2018

I'm not proposing to call/use the file.js.gz directly, this is done automagically by either Apache or Nginx.
I know.

Some explanation how all this works:
I know.

BTW the provided default snippet by apache will always switch the extensions, I guess this needs an if statement to check if the file actually exists...

Yes, there should be a RewriteCond %{REQUEST_FILENAME}.gz -f at the end of the rewrite conditions chain for each of the file types.

avatar richard67
richard67 - comment - 29 Dec 2018

Oh, I just see there is already a RewriteCond "%{REQUEST_FILENAME}\.gz" -s. That should do already the job.

avatar dgrammatiko
dgrammatiko - comment - 29 Dec 2018

Here is my nginx conf:

# gzip
gzip_static  on;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml application/font-woff  application/font-woff2;

The only extra part needed to work is gzip_static on;
Ref: http://nginx.org/en/docs/http/ngx_http_gzip_static_module.html

avatar ggppdk
ggppdk - comment - 29 Dec 2018

very nice to see this pr,

i understand how this works,
i have used it myself in some cases

but i want to ask regarding the case of having apache as web server
why this PR does not include the suggested changes inside htaccess.txt too ?
i mean htaccess.txt is used in new installations so why not include the suggested modification ?
are we expecting issues with contents of

<IfModule mod_headers.c>
    # Serve gzip compressed CSS files if they exist 
    # and the client accepts gzip.
...
</IfModule>
avatar dgrammatiko
dgrammatiko - comment - 29 Dec 2018

why this PR does not include the suggested changes inside htaccess.txt too

This PR only provides the tool for automating the creation of the .gz files. The steps to roll this to production are not part of this PR. As I wrote above the documentation is vital here and obviously tweaking the htaccess.txt and the build script are also required steps.

avatar Cyrusxxx
Cyrusxxx - comment - 30 Dec 2018

@dgrammatiko you are a genious!


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/23385.

avatar dgrammatiko
dgrammatiko - comment - 11 Jan 2019

@wilsonge can we get a decision from the production team on this one?

PS. The drone is failing, probably because the linux is 32bit and the zopfli script exists only for 64bit systems.

By the way, for anyone care to dig into the used technology here that is zopfli. Zopfli is compression scripts from Google, basically an improved gzip: https://github.com/google/zopfli

094cfd0 30 Jan 2019 avatar dgrammatiko oops
148e570 31 Jan 2019 avatar dgrammatiko CS
avatar joomla-cms-bot joomla-cms-bot - change - 3 Feb 2019
Category JavaScript Repository Administration com_categories com_config com_content com_media com_modules Templates (admin) JavaScript Repository
avatar dgrammatiko
dgrammatiko - comment - 3 Feb 2019

Redid this using WASM so no further changes required.
Attention this is now based on the new code for the build tools...

avatar HLeithner
HLeithner - comment - 3 Feb 2019

is there a reason why we don't create brotli compressed files? gzip is done by the moste webservers/loadbalancers/caches on the fly but brotli support is still very limited.

avatar dgrammatiko
dgrammatiko - comment - 3 Feb 2019

@HLeithner we could do that as well. The idea here is that these are repeated tasks from the web server which require processor power, so by providing them ready for delivery it's only a case of reading the file and streaming it...

FWIW I like the idea that Joomla will also provide prepared Brotli files

avatar dgrammatiko
dgrammatiko - comment - 3 Feb 2019

@HLeithner it seems zopfli is able to achieve the same level of compression as brotli:
screenshot 2019-02-03 at 22 42 00

e1ccbbc 3 Feb 2019 avatar dgrammatiko oops
avatar joomla-cms-bot joomla-cms-bot - change - 8 Feb 2019
Category JavaScript Repository Administration com_categories com_config com_content com_media com_modules Templates (admin) Repository Administration Templates (admin) JavaScript Installation Front End Templates (site)
avatar wilsonge wilsonge - change - 27 Feb 2019
Labels Added: ?
avatar joomla-cms-bot joomla-cms-bot - change - 27 Feb 2019
Category JavaScript Repository Administration Templates (admin) Installation Front End Templates (site) Administration Templates (admin) JavaScript NPM Change Repository Installation Front End Templates (site)
avatar wilsonge wilsonge - change - 28 Feb 2019
Labels Added: NPM Resource Changed
avatar wilsonge
wilsonge - comment - 28 Feb 2019

@dgrammatiko you've accidentally committed the templates compiled css (and minified css) files here

8742cab 28 Feb 2019 avatar dgrammatiko upd
avatar joomla-cms-bot joomla-cms-bot - change - 28 Feb 2019
Category JavaScript Repository Administration Templates (admin) Installation Front End Templates (site) NPM Change JavaScript NPM Change Repository Installation
avatar dgrammatiko
dgrammatiko - comment - 28 Feb 2019

@wilsonge can you try to build (locally) a 4.0-dev release so you can verify that this is actually working?

6455e04 28 Feb 2019 avatar dgrammatiko order
avatar wilsonge
wilsonge - comment - 28 Feb 2019
Processing: /Users/george/Sites/joomla-cms/media/vendor/webcomponentsjs/js/webcomponents-sd.min.js

After this file it hung. I had to command + c to close the task

avatar dgrammatiko
dgrammatiko - comment - 28 Feb 2019

@wilsonge it didn't hang it just takes very long to make all those .gz files. Try adding a console.log to see the files processing

PS the compression from zopfli is slow but the ratio is the same as brotli:
screenshot 2019-02-28 at 22 26 33

avatar dgrammatiko
dgrammatiko - comment - 28 Feb 2019

And for comparison here are the minified, normal gzip from a server, and the zopfli sizes:

56.658 bytes, 21.462 bytes, 17.881 bytes

screenshot 2019-02-28 at 22 42 50

avatar wilsonge wilsonge - change - 18 Mar 2019
Status Pending Fixed in Code Base
Closed_Date 0000-00-00 00:00:00 2019-03-18 09:08:52
Closed_By wilsonge
avatar wilsonge wilsonge - close - 18 Mar 2019
avatar wilsonge wilsonge - merge - 18 Mar 2019
avatar wilsonge
wilsonge - comment - 18 Mar 2019

Seems good to me. Thanks!

Add a Comment

Login with GitHub to post a comment