代码分割的一点思考

125 阅读3分钟
如题这里只是记录了代码分割的一点点感想,主要是一些思考,而不是具体的做法,请辩证看待,如有问题,请勿喷留言,虚心接受。

随着前端技术的发展,SPA已经成为了前端日常(无论是React还是Vue作为技术栈,也不论是Webpack还是Vite作为打包工具)。其核心都是将资源打包为若干js文件(抛开一些静态资源不说),在信息高度流转的今天,我们也不得越来越重视效率和性能。

首屏加载速度也成为了前端web应用的一个关键性指标,怎么达到,很简单(说起来),让你的首页需要加载的资源文件越小自然越快,如何达到这个目的呢?(呵呵呵呵) 不管你用webpack还是vite去打包,观察一下产物,应该是必然有一个index.xxxx.js的有效js文件的,可能仅此一个,如果你的项目足够大,看看它是不是也足够庞大?虽然可以有cdn、缓存、zip等各种方案让这些资源加载的更流畅,但是还是不治本的。毕竟不管cdn还是缓存总有第一次。而zip,如果你的文件足够大,纵使压缩了60%是不是也还是足够大。

忘了从webpack的什么版本开始,有了codesplit这个说法,顾名思义,对代码进行分割,把很庞大的一个index.xxxx.js文件分割成必须首次加载的index.js文件和后续当进入到对应页面的时候才会加载的若干inxdex.other.js文件。 那代码分割的原理是什么?这里会提到两点(只是概念性的)

  • 1.抽出第三方库,现如今的web应用,说不会用到第三方库,是完全不可能的,这些库可能是庞大的,那可不可以把它们抽出去,让它们的打包产物不要跟我们的业务代码糅合在一起呢?(得益于现代浏览器,同时可以并行加载多个资源文件,或许可以提升一些性能的。

  • 2.对自己的业务代码进行分割,这里是如何分割的?也不太记得从哪个版本开始esmodule支持import()异步加载,依托于此Vue和React都实现了异步加载机制,这里大概提一下React的。

    主要是React.Suspense和React.Lazy(其实有些像React提供了类似await这种同步书写实现异步功能),让你可以更舒服的使用jsx语法去书写一个异步组件,如下

    const NetDiskFileList  = React.lazy(() => import( '../components/file-list'));
    const NetDiskFolder  = React.lazy(() => import( '../components/folder'));
    const NetDiskToolbar = React.lazy(() => import('../components/toolbar'));
    
    <React.Suspense fallback={<div>loading</div>}>
      <NetDiskToolbar />
      <NetDiskFolder />
      <NetDiskFileList />
    </React.Suspense>
    

    当然这里只是说了React怎么去利用import()的异步加载,那跟代码分割有什么关系呢? 关系就是当你的代码里存在这种异步加载的组件,打包的时候打包工具会自行把异步组件抽出刀一个单独的js文件。试想下,如果都在一个js文件,那异步加载个什么呢?毕竟js是下载完成后编译执行的。

    这里有两张图稍作对比,图一是没有使用React.Lazy,最终的打包产物只有一个有效的js文件,并且大小是9170 image.png 图二是使用了React.Lazy写法后的打包产物,多了一个js文件,并且首页文件的大小少了一点点,虽然只是小小的1kb,但是也能说明问题不是吗?
    image.png