DNS blocking works quite well. It's also very effective if you can set it up on your gateway so that it blocks ads/malware for all devices (PCs, phones, tablets ... even your guests will get adblocking for free!). However, while the /etc/hosts trick works I don't think it's the best way. The reason is that while parsing a plaintext file is easy and generally fast, it doesn't scale well especially when you have to traverse several megabytes of it for _every_ DNS request.
The way I have done it is by installing unbound[0]. If you aren't using something else like dnsmasq, you will notice a speedup from the DNS caching alone. While unbound isn't supposed to serve authoritative answers (i.e.: don't use it to manage your zone) the possibility is there. The unbound-block-hosts script[1] can be used to convert Dan Pollocks' hosts file to the appropriate unbound syntax.
To avoid the timeout from localhost, my first approach was to setup a firewall rules that discards the request (the browser receives a connection refused message _immediately_)
Another way of proceeding is to setup nginx to serve a 1*1 transparent GIF for every request it receives. If you find nginx to be too big a dependency, there are alternatives such as pixelserv[2].
The issue is that you can't block a specific element, but you still catch a fair share of ads.
I have explored the possibility of running a http proxy to address this, but I haven't got around to it yet. (In addition, I'll probably need to MITM myself if I want to block elements in HTTPS; still needs some thinking :)).
[0] https://unbound.net/
[1] https://github.com/jodrell/unbound-block-hosts
[2] https://github.com/h0tw1r3/pixelserv