The more extensive the meta programming you can do, the more work it is to implement this under the scenes. For example in Java you can change the visibility of fields, and you can load new classes, so that's not too hard to take account of, but in Ruby you can redefine methods, add refinements so they behave differently depending on where they are called, or radically change the inheritance hierarchy. Implementations like TruffleRuby can maintain high performance even with these features being used, but it's taken a lot of work to achieve that.
Optimising away the performance impact of most of the metaprogramming features I mentioned there requires truly heroic optimisations, beyond what has ever been used for any other language.
Some of them are even worse - I'm not sure there any way to optimise away the non-local effects of Proc#binding, which allows you to access local variables not lexically referenced.
JS on the other hand can do most of what ruby does, to my knowledge. Objects are key value pairs so you're free to mess with them in virtually any way you please. You can also mess with the inheritance by altering JS prototype chains.
I don't think metaprogramming itself has much to do with the speed of Ruby, with my admittedly limited knowledge of this stuff
If you want to find out more about the limits of what can be done to optimize Ruby, check out the Truffle project. That came out of someone's PhD dissertation on novel methods for doing JIT optimization for Ruby. It is sufficiently difficult and novel to warrant awarding a PhD for. Last time I heard, Truffle still could not run Rails.
I think the most exciting optimization people have seen with Ruby is Truffle.
I don't regret the 14 years I put into writing Ruby professionally. I've used and abused metaprogramming, and it has shaped how I reason and architect things. I learned to appreciate well-designed, semantically-meaningful DSL. But I've moved on. I write server code with Elixir these days, and I'm exploring other ways of reasoning and writing code.
no offence to JS, but JS and a proper programming language are not even the same species.
JS you can redefine anything, Java support is pretty good, C# better support is coming with generators