记录使用较小的成本换来较好的用户体验和提升页面加载速度,适用场景:web 移动端单页应用,前后端(数据层)分离的项目。
在做 Web 移动端项目的时候遇到首屏加载慢的情况,因为页面的渲染都依赖 JS 文件输出,所以就导致需要等待 JS 文件加载完成页面才能被渲染出来。在未加载完 JS 文件的情况下,会导致页面白屏一段时间。
解决白屏问题:
Vue/React
有现成的解决方案:Vue Nuxt
,React Next
,利用这些同构框架在服务端渲染好页面输出到浏览器而无需等待 JS 加载完成,解决首屏渲染白屏问题。还有就是使用预渲染插件,在打包构建时分离动静资源,如:Vue prerender-spa-plugin
插件。async/defer
,CSS 只加载基础样式,业务和组件的样式可以异步加载。在做加载性能测试的时候,还发现了一个问题:用
IOS 10.X Safari
访问页面时,当目标页面的Content-Length
长度大概小于1000~1500字节左右并且页面有好几个外链文件的情况下,页面加载的外链脚本文件会堵塞页面的渲染,无论是给脚本文件加defer
属性,还是把它放Body
标签后面都会无效,而async
则不受影响,后来发现分块传输方式在这种情况下也会失效。以上的这些问题在Chrome
下不会出现。
使用同构框架也会有一些问题,一个是依赖服务器,页面刷新渲染挪到了服务端,给服务器带来了一些压力。开发上也需要兼顾两端,服务端没有 window document location
等这些浏览器变量,需要做兼容处理,特别是在项目中使用了第三方的插件,如果插件本身不支持 SSR
,还得自己对它进行改造,带来了开发成本和维护上的问题。
根据业务和项目大小使用不同的方案。如果项目是完全前后端分离,只通过接口来通讯,可以预渲染+骨架屏搭配使用,在页面级组件上写好占位元素(骨架屏),然后用 nuxt generate
命令构建 (基于 nuxt 的项目),生成渲染后带占位元素的 HTML,接口的请求和拿到数据后的渲染依旧在浏览器端完成,这样做的好处有:
nuxt generate
生成了静态页面,所以减少了开发和服务器成本,只需要一个 web 服务器就可以。nuxt generate
会自动生成。SEO
的页面:about、contact。prerender-spa-plugin
预渲染插件适合小型项目,而用 Nuxt
可扩展性强,功能多,并且考虑到项目后期有些页面可能会使用到服务端渲染的情况,所以使用 Nuxt
省去了迁移的麻烦。
利用预渲染和骨架屏已经可以带来较好的用户体验和加载速度了,有 CDN 的话,可以把打包生成的静态资源都放到 CDN 上,还可以使用 service worker
、http2
等技术来更进一步的提升性能。