まずはbyte数計算速度を比較。構成文字によって最適法は変わってきます。以下の例ではほぼ多byte文字となります。
!function(){// utf8 size
var a=0,b=0,c,d,e,z=65536,A=[];
for(;a<0xd800;)A[a]=a++;
for(;a<z;A[a++]=0xdc00+(b++&0x3ff))A[a++]=0xd800|b>>10;//surrogate pair
A=String.fromCharCode(...A);//計算対象文字列
for(b=new Date,a=100;a--;)encodeURI(A).replace(/%../g,'i').length
console.log(new Date-b)
for(b=new Date,a=100;a--;)A.replace(/[\x80-\u07ff]/g,11).replace(/[\u0800-\ud7ff\ue000-\uffff]/g,111).replace(/[\ud800-\udbff][\udc00-\udfff]/g,1111).length
console.log(new Date-b)
for(b=new Date,a=100;a--;)for(c=e=0;c<z;e+=d<128?1:d<0x800?2:d<0xd800||d>0xdfff?3:(c++,4))d=A.charCodeAt(c++);
console.log(new Date-b)
for(b=new Date,a=100;a--;)new TextEncoder().encode(A).length;
console.log(new Date-b)
}()
encodeURI
がぶっちぎりで遅いです。