Improving the performance of Nextcloud
How to use CDN to serve third-party scripts and fonts for a big speed boost
I’ve recently started using Nextcloud, a powerful open-source PHP file manager. It works really well and there are many plugins which allow for extra functionality to be added, including support for external storage via Amazon S3 and more.
A freshly installed Nextcloud site can be a bit slow though as all files are served locally so performance is impacted — especially if you’re on a server without HTTP/2. I decided to do some digging to see if I could improve the performance.
Serving Font from Google’s CDN
Nextcloud uses a locally served ‘Open Sans’ font only in WOFF file format. By using Google’s CDN instead we can take advantage of the smaller and faster loading WOFF2 file format as well as a longer cache life. To do this simply add:
<link href='https://fonts.gstatic.com' rel='preconnect' crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600">
to the following three files just below the <?php emit_css_loading_tags($_); ?>
:
/core/templates/layout.base.php
/core/templates/layout.guest.php
/core/templates/layout.user.php
Serving Third-Party Scripts from a CDN
Nextcloud loads a huge number of JavaScripts which really slows down page load speeds (unless you’re on HTTP/2). There’s a vendor/core.js
file which contains all the third-party plugins and is just over 1 MB and includes 16 scripts (of which 7 of them are unminified):
"jquery/dist/jquery.min.js",
"jquery-migrate/jquery-migrate.min.js",
"jquery-ui/ui/minified/jquery-ui.custom.min.js",
"underscore/underscore.js",
"moment/min/moment-with-locales.min.js",
"handlebars/handlebars.min.js",
"blueimp-md5/js/md5.min.js",
"bootstrap/js/tooltip.js",
"backbone/backbone.js",
"es6-promise/dist/es6-promise.js",
"davclient.js/lib/client.js",
"clipboard/dist/clipboard.min.js",
"autosize/dist/autosize.min.js",
"DOMPurify/dist/purify.min.js",
"snapjs/dist/latest/snap.js",
"select2/select2.js"
I decided to remove the contents of vendor/core.js
(so it’s 0 KB) and then add the following:
<script defer src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script defer src="https://code.jquery.com/jquery-migrate-1.4.0.min.js"></script>
<script defer src="https://code.jquery.com/ui/1.10.0/jquery-ui.min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment-with-locales.min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.5/handlebars.min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.7.0/js/md5.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/gh/twbs/bootstrap@3.3.7/js/tooltip.min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/es6-promise/2.3.0/es6-promise.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/gh/owncloud/davclient.js@0.1.2/lib/client.min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.6.1/clipboard.min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/autosize.js/3.0.20/autosize.min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/1.0.3/purify.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/gh/jakiestfu/snap.js@2.0.0-rc1/dist/2.0.0-rc1/snap.min.js"></script>
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.8/select2.min.js"></script>
to the following files — in place of <?php emit_script_loading_tags($_); ?>
and just below the <?php emit_css_loading_tags($_); ?>
:
/core/templates/layout.base.php
/core/templates/layout.guest.php
/core/templates/layout.user.php
This dramatically improved the first page load speed.
Adjusting the Content Security Policy
It’s important that you adjust the Content Security Policy (CSP) to whitelist assets being loaded from cdn.jsdelivr.net, cdnjs.cloudflare.com, code.jquery.com, fonts.gstatic.com and fonts.googleapis.com otherwise they won’t load.
Summary
By serving assets from a CDN you can greatly improve the load speed of Nextcloud by taking advantage of smaller file sizes (as all scripts are minified), longer cache life and domain sharding.
This article was cross-posted from: https://christianoliff.com/blog/improving-the-performance-of-nextcloud