CSS & Javascript truncated by nginx

On several recent projects I’ve been using VirtualBox and Vagrant to spin up new development machines. The simplicity and power of the two tools together is amazing, and stops me from cluttering up my main machine with tools and packages from random side projects. It hasn’t been all sweetness and light though. I wrote recently about issues with node.js, npm and express, and this week ran in to a far more frustrating issue. It involved nginx and sendfile, with javascript truncated and this developer frustrated.

The Problem: CSS & Javascript truncated

My setup was a very basic one – a VirtualBox running:

  • Ubuntu 12.04
  • nginx
  • PHP-FPM

My code was mounted from a windows host, and initially all was going well. Then suddenly my app started spitting out javascript errors. Digging in to chrome’s error console, it looked like the last 40 or 50 bytes of the file were missing. As these bytes contained the end of a function, them being absent meant the file had invalid syntax so the application didn’t run. It was a similar story with the css – random bits chopped off the end of some files, and in others changes I made not being reflected when viewed in the browser. Javascript truncated, the same for css – bad times all round.

You're gonna have a bad time

I suspected a cache issue initially. I flushed the browser cache, tried a new browser, and even restarted nginx on the vm – all to no avail. Interestingly, when I added more code to the bottom of an affected javascript file, it was still only the last 40-50 bytes being chopped off – the file itself wasn’t frozen in it’s original, broken state. So, what’s going on there?

Sendfile

Nginx has a sendfile directive, which defaults to on. It allows nginx to use the Linux kernel’s sendfile() operation to read the requested file from disk. This is typically quicker than using read() and write(). So far, so good.

The problem is that sendfile doesn’t work so well in virtual environments, as noted in nginx’s “Pitfalls” section. The fix turned out to be insanely simple – just turn sendfile off. As it’s a development machine, the performance hit incurred by turning off this feature is pretty negligible. (It would want to be a pretty significant performance hit to outweigh the file truncation!)

In the nginx config http server block, I added:

sendfile off;

Once nginx was restarted, I was getting served full static files, and all was well with the world again!


PHPers Summit 2024 Speaker

International PHP Conference
Munich, November 2024

In November 2024, I'll be giving a talk at the International PHP Conference in Munich, Germany. I'll be talking about the page speed quick wins available for backend developers, along with the challenges of policing dangerous drivers, the impact of TV graphics on web design, and the times when it might be better to send your dev team snowboarding for 6 months instead of writing code!

Get your ticket now and I'll see you there!


Share This Article

Related Articles


Lazy loading background images to improve load time performance

Lazy loading of images helps to radically speed up initial page load. Rich site designs often call for background images, which can't be lazily loaded in the same way. How can we keep our designs, while optimising for a fast initial load?

Idempotency - what is it, and how can it help our Laravel APIs?

Idempotency is a critical concept to be aware of when building robust APIs, and is baked into the SDKs of companies like Stripe, Paypal, Shopify, and Amazon. But what exactly is idempotency? And how can we easily add support for it to our Laravel APIs?

Calculating rolling averages with Laravel Collections

Rolling averages are perfect for smoothing out time-series data, helping you to gain insight from noisy graphs and tables. This new package adds first-class support to Laravel Collections for rolling average calculation.

More