The value in rainbow tables is running them against data such as a complete list of passwords in a system that has already been acquired (e.g by sql injection or other exploit). There’s no relevance to using them against a live login on the web.
The millions of attempts can be run extremely quickly on the offline data. Even without rainbow tables cracking hashes can be done in many case in the space of hours to a few days using cloud resources like amazon gpu clusters. The key is not to let people access your database to acquire password hashes, and to use individual salts so that full table cracks can’t be performed.
Yes this is secure, as long as you use unique salts (which it does by default if you don’t pass one to the function). If you use static salts it’s theoretically possible to analyse the statistics of large tables against common password lists to accelerate a full table crack.