相较于单线程,多线程无疑是性能更好的选择,虽然多线程面临着各式各样的挑战,但只要程序员能够熟练掌握多线程的控制,便能很好的利用cpu和内存资源来给自己的程序提速。但JavaScript却并没有提供一个能够开启多线程的功能,这是为什么呢?网络上很多答案都模凌两可,我也并没有找到一份自己认为正确的答案,所以我自己思考,认为可能有以下三个原因:
1. 安全问题
js代码并不像C++代码或Java代码开发的程序一样,是长期来一个主机下运行。js代码通常作为静态资源在网络中进行传输,传输到指定ip后发挥作用,这就导致js传播范围极广,切传播方式简单(只需要向url发起请求即可),一旦js代码具有攻击性,那么电脑使用者将会防不胜防。
所以V8引擎的开发者不允许js具有系统调用的能力,换句话说就是不允许js有访问硬件的能力,这样js便无法攻击使用者的电脑,指具有执行逻辑的功能。
2. 浏览器提供系统调用能力
虽然限制js代码的系统调用能力可以保证页面的安全性,但是页面通常有不得不进行系统调用,比如网络请求,这个怎么办呢?
js代码虽然没有为这个需求提供解决方法,但是其运行环境解决了。浏览器在渲染一个页面时会提供多个线程来执行代码,换句话说js虽然不能创建线程,不过浏览器创建了多个线程来执行代码内容。其中包括主线程,渲染线程,网络线程等等。其中网络请求是前端为数不多的耗时操作之一,由js调用浏览器api,在网络线程中执行,很好的解决了网络请求阻塞程序的问题,并且浏览器也会提供文件选择等大量系统调用相关的功能,让js代码具有了可以实现更多需求的能力。
3. 性能优化
虽然多线程能够极大的优化程序性能,不过这是建立在程序需要长时间处理长任务的情况下才会有明显效果,而js代码控制前端逻辑,是绝对不会涉及这种长任务的,耗时任务都会由后端处理。而js通常只是控制页面显示跳转的逻辑,这一部分逻辑即使运行速度再快,也不会对用户体验有什么提高。
可是前端代码确实会影响用户体验呀,比如页面有时确实会反应很慢啊,你怎么说js代码对用户体验没有什么提高呢?实际上只要细心观察就可以发现,前端页面反应慢通常是因为网络请求速度,而非js代码执行速度。所以这种耗时行为实际上是发生在浏览器中的,而非js代码。浏览器内部也是为当前页面专门提供了网络请求的线程,使其处理网络请求时,不会阻塞用户在当前程序的其他操作。
那js代码就完全不会影响程序性能?我们前端工程师的代码可以随便写了吗?当然不是,js代码的执行速度虽然在大部分时候对用户体验影响微乎其微,但是其作为静态资源,仍然影响着程序中最重要的一个性能优化点,那就是首屏渲染速度。js需要在网络中作为静态资源频繁传输,所以需要通过复用代码及代码压缩来减少js代码体积,进而提高页面的首评渲染速度。这样是为什么前端工程师会不断的对代码进行抽取封装,webpack等打包工具在进行性能优化时,也是不断针对html,css,js等前端代码进行丑化,压缩,摇树以及CDN内容分发网络,不断减少前端代码体积。
总的来说,js之所以是单线程的,是因为其传播速度快,传播方式简单,为了安全起见不允许其访问计算系底层资源。并且对于用户日益增常的需求,其运行环境浏览器也提供了api,来让js代码有间接系统调用的能力。并且js代码的执行速度也和用户体验关系不大,也不需要多线程来提高代码执行速度。