Improving the performance of Nextcloud

Posted on
Contents

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.

Nextcloud

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 .

UPDATE (MARCH 2019)

Since I published this post Nextcloud have released several big updates which have addressed many of the performance issues mentioned above so if you’re running the latest version it might not make sense to attempt the above. You will need to check the correct version of all the scripts too. You should test your site with Google PageSpeed Insights to look for performance improvements you can make though.

You might also like

Self hosting Google Fonts for improved performance

A Hassle-Free Way to Self-Host Google Fonts

Optimizing Static Site Performance on CloudFront

Tweaks for improving caching and adding gZip compression

Notes from my 'Make Your Site Fast' Talk

Links, tools and resources for making high performance web sites