- git clone https://github.com/zekkie/pm.git
- cd pm && npm install
- node index.js
- [http://localhost:9000](http://localhost:9000)
As you can see, the serverside rendered page was finished loading three times faster than the SPA. But the serverside rendered page also had alot less requests than the SPA. That is the benefit of having serverside rendered pages. Routing and rendering handled by a server and not the client.
Since the application is small and boring to do some performance improvements, I'll bloat the website so we will have something to work with.
A loadtime of 41.59s, Pretty awefull if you ask me. A good starting point though.
Well, every modern framework is pretty big. So it is not a surprise that angular is 1.3mb. But there are an awefull lot of comments inside the Angular file that will not be read anyways. And the same goes for jQuery. Let's remove those and minify the files. And as bonus,concat all js files.
Alright, 530kb. Still a big file, but considering they were two files before and almost 2mb combined. This is not too bad. We brought down the loading time from 41.59s to 19.20s. Not bad if you ask me.
Lets see if we can do the same for the css files
Hmm, the css is probably too small to have any effect on the loading time. 19.17s is a too small of an improvement.
After compressing, minifying and concatenating all the files. We have a loadtime of 10.74s. Which is reasonable for getting here from 41.59s. I don't know what to do more to get the loadtime even smaller.
For generating static gzip files, minifying and concatenating the files, I've used a gulp file that looks like this.
const gulp = require("gulp");
const concat = require("gulp-concat");
const uglify = require("gulp-uglify");
const uglifycss = require("gulp-uglifycss");
const gzip = require("gulp-gzip");
const jsfiles = "static/js/*.js";
const cssfiles = "static/css/*.css";
gulp.task('create-vendor-js', () => {
return gulp.src(jsfiles)
.pipe(concat('script.js'))
.pipe(uglify())
.pipe(gzip())
.pipe(gulp.dest('static/js'))
})
gulp.task('create-vendor-css', () => {
return gulp.src(cssfiles)
.pipe(concat('vendor.css'))
.pipe(uglifycss())
.pipe(gzip())
.pipe(gulp.dest('static/css'))
})
As you can see, the gulp task creates a static gzip file. That is beeing served to the client with the code below:
app.get("*.js", (req, res, next) => {
// only if file exists, the substr is to remove /assets in front
if (!fs.existsSync(`./static/js/${req.url.substr(4)}.gz`)) {
console.log(req.url.substr(4))
return next();
}
console.log(`${req.url} -> ${req.url}.gz`);
req.url = `${req.url}.gz`;
res.set("Content-Encoding", "gzip");
res.set("Content-Type", "text/javascript");
next();
});
app.get("*.css", (req, res, next) => {
// only if file exists, the substr is to remove /assets in front
if (!fs.existsSync(`./static/css/${req.url.substr(4)}.gz`)) {
console.log(req.url.substr(4))
return next();
}
console.log(`${req.url} -> ${req.url}.gz`);
req.url = `${req.url}.gz`;
res.set("Content-Encoding", "gzip");
res.set("Content-Type", "text/css");
next();
});
to run this, I've created a npm script
npm run-script build
Since the image's come from an API, it's not possible to compress those to .webp. But we could do something with perceived performance and display placeholders until the image is fully loaded! :D. That will require JS though.
##CACHING
For caching we will be using a simple service worker.
Caching is now been done from the serviceworker.
var cache_name = "zekkie-cache-1";
var urls = [
"/css/vendor.css",
"/js/script.js"
];
self.addEventListener("install",function(event) {
event.waitUntil(
caches.open(cache_name).then(function(cache){
return cache.addAll(urls);
})
);
});
self.addEventListener("fetch", function(event){
event.respondWith(
caches.match(event.request).then(function(response) {
if(response) {
console.log(response)
return response
}
return fetch(event.request);
})
);
});
All of the tests were done under slow-3g.