To compare the two, together with Google's DNS as a reference, from a fast connection:
64 bytes from 1.1.1.1: icmp_seq=5 ttl=59 time=3.62 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=60 time=3.60 ms
64 bytes from 9.9.9.9: icmp_seq=5 ttl=60 time=9.20 ms
...and from a slower (home) connection: 64 bytes from 1.1.1.1: icmp_seq=5 ttl=58 time=11.1 ms
64 bytes from 8.8.8.8: icmp_seq=5 ttl=59 time=11.9 ms
64 bytes from 9.9.9.9: icmp_seq=5 ttl=59 time=34.2 ms
Note that I just used the speed of every fifth package instead of the average for five packets in order to keep the comment relatively short and more humanly readable than "rtt min/avg/max/mdev".I'm not sure what you meant in point (a) but, of course, DNS cannot be parallelized with HTTP since the browser doesn't know where to connect until DNS completes. Also, DNS requests for subresources can't start until the referring resource has been loaded. So you could easily see a few serialized DNS requests in the long pole for loading a web site.
Also note that the timing above were ping times. An actual DNS query will have to recurse if the result is not cached at the DNS server -- which in these days of 60-second TTLs for is not uncommon. Cloudflare, though, happens to be the authoritative DNS for quite a few web sites, in which case no recursion is necessary.
I meant that DNS requests are parallelized within the browser. Once it loads the initial resource (html), there might be 10 more dependencies it needs at various different URLs under different domain names. It's usually loading all these dependencies that make up the vast majority of the load time on a complex web page.
Those subsequent DNS requests can of course be made in parallel, so if your DNS latency is 20ms then you're adding ~20ms, not 10 x 20ms.
Even then, DNS is probably making up a small fraction of the overall load time. If a complex page is taking, say, 3000ms to load and render, then adding 20-40ms of DNS time is not going to make a perceptible difference.