宝哥软件园

详细说明如何在webpack中进行预渲染 以减少第一个屏幕的空白时间

编辑:宝哥软件园 来源:互联网 时间:2021-08-30

一、浏览器渲染过程

1.用户打开页面,留下空白屏幕,等待html返回

2.下载html后,开始解析html并进行初始呈现

3.下载css、js等资源,执行js渲染虚拟DOM

4.发起请求、获取数据和呈现内容

下面我们主要讨论如何通过预渲染减少空白屏幕时间

减少首屏加载时间是一个重要的优化项目,可以总结如下:

1.尽可能减少由webpack或其他打包工具生成的包的大小。2.使用服务器端呈现方法。3.使用预渲染方法。4.使用gzip降低网络传输的流量大小。5.根据页面或组件不情愿地加载

二、传统页面开发

在React和Vue等数据驱动框架盛行之前,我们通常直接在html上或者直接从服务器上编写dom结构。因此,下载html页面后,空白屏幕的时间非常短,因为dom是用html编写的,而不是像现在这样用js以虚拟dom的形式编写的。因此,我们在渲染页面之前不需要等待js下载,而是在下载html之后直接渲染dom结构。

如今,当我们使用Vue等框架进行开发时,html结构一般如下

!DOCTYPE html html lang=' en ' head meta charset=' UTF-8 ' title title/title/head body div id=' app '/div script src=' http :/bound . js '/script/body/当js资源没有下载时,页面总是空白的,会一直等到虚拟dom插入到id为app的div中。这时白屏消失,页面显示出来,反正让人感觉很慢!

现在我们已经知道了白屏是如何产生的,让我们来试试如何在webpack中集成预渲染功能来减少白屏时间。

第三,在webpack中集成预渲染功能

Github:如何在web pack中集成预渲染功能

这里,我们尝试在编译webpack的过程中,使用vue编写的加载组件将虚拟dom预渲染为html。以下是加载组件的内容

template div class=' loading-img '/div/templatescript export default { }/script style . loading-img { position : }已修复;top : 0;bottom : 0;right : 0;left : 0;margin: autodisplay:内联块;宽度: 60px;高度: 60px;background : URL(_ inline _ _)无重复中心中心;背景尺寸:容器;}/style上面的__inline__是插入下列图片的标记。这里不用担心。事实上,这个组件是一个简单的加载组件

最后,我们想要的是将这个vue组件的虚拟dom预渲染到一个html文件中

html头元字符集='UTF-8' titletest/title!-CSS提取-预渲染-加载-加载-样式。装载-img {位置:固定;top : 0;bottom : 0;right : 0;left : 0;margin: autodisplay:内联块;宽度: 60px;高度: 60px;-这里我们将把加载图编译成base64并直接插入到html-background : URL(data : image/gif;base64,)无重复中心中心;背景尺寸:容器;}/样式./head body div id='app '!-加载base64图表-div class=' loading-img '/div/div./body/html如上图,当html页面返回时,编译成base64并嵌入html的加载会立即显示,大大减少了白屏时间,基本达到了第二次页面打开。此时,我们不需要等待js资源的下载和虚拟dom的插入。当然,这里加载的内容可以是任何内容。

因为我们的加载组件在这里是用vue编写的,所以我们尝试看看如何进行预渲染并将其集成到webpack中(您可以一起查看仓库的代码,代码相当简单,只是一个演示)

这里,我们首先将html和css从vue单个文件中分离出来

//渲染加载。jslet vueAssets=nulllet vueTplPath=解析路径(' ./src/加载/预渲染加载。vue ')const extra cassinvuetpl=(vueTplPath)={ let vueTpl=clearEnter(fs。readfilesync(vueTplPath)).toString())让html=/template().*)/template/g.exec(vueTpl)[1]让css=/style(.*)/style/g . exec(vueTpl)[1]return { html,CSS } } vueAssets=extracsingvuetpl(vueTplPath)这里我们通过正则的方式将模板与风格标签中匹配到的内容单独抽离了出来,接下来我们需要将可交换的图像格式图转成base64并插入到我们抽出的钢性铸铁代码当中

让gifPath=resolvePath(' ./src/loading/imgs/loading。gif ')const transGifToCSSFile=(IMgpath)={ let ext=path。扩展名(IMgpath).切片(1)让PREStr=` data : image/$ { ext };base64,`//根据尾缀自动拼接对应base64前缀让BitDate=fs。ReadFileSync(IMgpath)让base64Str=BitDate。tostring(' base64 ')让dataURL=preStr base64Str返回数据URL }让DataURl=transgiftocsFile(gif path)上面我们通过extractAssetsInVueTpl函数抽离出了css,这里我们通过一个简单的函数将占位符替换成base64图片

const injectDataURLToCSS=(csstr,dataURL)={ return csstr。替换(/_ _ inline _/,dataURL)}让csstr=injectDataURLToCSS(vueassets。CSS,dataURL)下面我们就导出装货配置,包含了超文本标记语言模板与风格样式字符串

loading.html=vueasset。html加载。CSS=' style ' CSSTr/' style '模块。出口=装载简单写一个工具入口配置,这里我们需要使用html-web包-插件将装货插入到超文本标记语言中(这里用到了插件的自定义模板)

const HTMl WebPACKlugin=require(' HTMl-web pack-plugin ')const loading=require(' ./render-loading ')模块,exports={ entry: ' ./src/index.js '、输出: { path : _ _ dirname/' dist '、文件名: ' index _ bundle。js ' }、plugins :[新的HTMlWebPackLugin({ template : })./src/index.html ',load : loading })]}在超文本标记语言中我们通过模板语法将装货的内容插入到超文本标记语言模板中对应的位置了

html head meta charset=' UTF-8 '标题测试/标题.%=html webpackkplugin。选项。装货。CSS %/头体div id=' app '!-装载底座64图-%=htmlWebpackPlugin.options.loading.html %/div./body/html四、总结

这里只是写一个演示介绍一下原理,更复杂的可以使用vue-服务器-渲染来做同构直出或者使用一些像把手的模板引擎来生成模板,其实就是将服务端的渲染工作放到了编译的过程当中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

更多资讯
游戏推荐
更多+