1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 关于React首屏白屏问题

关于React首屏白屏问题

时间:2019-06-08 11:25:09

相关推荐

关于React首屏白屏问题

主要从下面几个地方优化:

在HTML内实现Loading状态或者骨架屏去掉外联 css缓存基础框架使用动态 polyfill使用 SplitChunksPlugin 拆分公共代码正确地使用 Webpack 4.0 的 Tree Shaking使用动态 import,切分页面代码,减小首屏 JS 体积编译到 ES+,提高代码运行效率,减小体积使用 lazyload 和 placeholder 提升加载体验

------------------------------在HTML内实现Loading状态或者骨架屏------------------------1. 普通的处理方式,自定义Loading界面 (可以加载SVG文件)2. 使用html-webpack-plugin自动插入loadingvar HtmlWebpackPlugin = require('html-webpack-plugin');var path = require('path');// 读取写好的 loading 态的 html 和 cssvar loading = {html: fs.readFileSync(path.join(__dirname, './loading.html')),css: '<style>' + fs.readFileSync(path.join(__dirname, './loading.css')) + '</style>'}var webpackConfig = {entry: 'index.js',output: {path: path.resolve(__dirname, './dist'),filename: 'index_bundle.js'},plugins: [new HtmlWebpackPlugin({filename: 'xxxx.html',template: 'template.html',loading: loading})]};然后在模板中引用即可:<!DOCTYPE html><html lang="en"><head><%= htmlWebpackPlugin.options.loading.css %></head><body><div id="root"><%= htmlWebpackPlugin.options.loading.html %></div></body></html>3.使用prerender-spa-plugin渲染首屏(参考: /p/31954853)在一些比较大型的项目中,Loading 可能本身就是一个 React/Vue 组件,在不做服务器端渲染的情况下,想把一个已经组件化的 Loading 直接写入 html 文件中会很复杂,不过依然有解决办法。prerender-spa-plugin 是一个可以帮你在构建时就生成页面首屏 html 的一个 webpack 插件,原理大致如下:1).指定 dist 目录和要渲染的路径2).插件在 dist 目录中开启一个静态服务器,并且使用无头浏览器(puppeteer)访问对应的路径,执行JS,抓取对应路径的 html。3).把抓到的内容写入 html,这样即使没有做服务器端渲染,也能达到跟服务器端渲染几乎相同的作用(不考虑动态数据的话)plugins: [new PrerenderSpaPlugin(path.join(__dirname, 'dist'),[ '/', '/products/1', '/products/2', '/products/3'])]

------------------------------去掉外联CSS------------------------实际上,webpack 默认就是没有外链 css 的,你什么都不需要做就可以了。当然如果你的项目之前配置了 extract-text-webpack-plugin 或者 mini-css-extract-plugin 来生成独立的 css 文件,直接去掉即可。

------------------------------缓存基础框架--------------------------------------------------HTTP为我们提供了很好几种缓存的解决方案,不妨总结一下:1. expiresexpires: Thu, 16 May 03:05:59 GMT在 http 头中设置一个过期时间,在这个过期时间之前,浏览器的请求都不会发出,而是自动从缓存中读取文件,除非缓存被清空,或者强制刷新。缺陷在于,服务器时间和用户端时间可能存在不一致,所以 HTTP/1.1 加入了 cache-control 头来改进这个问题。2. cache-controlcache-control: max-age=31536000设置过期的时间长度(秒),在这个时间范围内,浏览器请求都会直接读缓存。当 expires 和 cache-control 都存在时,expires 的优先级更高。3. last-modified / if-modified-since这是一组请求/相应头响应头:last-modified: Wed, 16 May 02:57:16 GMT请求头:if-modified-since: Wed, 16 May 05:55:38 GMT服务器端返回资源时,如果头部带上了 last-modified,那么资源下次请求时就会把值加入到请求头 if-modified-since中,服务器可以对比这个值,确定资源是否发生变化,如果没有发生变化,则返回 304。4. etag / if-none-match这也是一组请求/相应头响应头:etag: "D5FC8B85A045FF720547BC36FC872550"请求头:if-none-match: "D5FC8B85A045FF720547BC36FC872550"原理类似,服务器端返回资源时,如果头部带上了 etag,那么资源下次请求时就会把值加入到请求头 if-none-match 中,服务器可以对比这个值,确定资源是否发生变化,如果没有发生变化,则返回 304。上面四种缓存的优先级:cache-control > expires > etag > last-modified

------------------------------使用动态Polyfill----------------------------------------------

------------------------------使用SplitChunksPlugin拆分公共代码------------------------Webpack 4 抛弃了原有的 CommonChunksPlugin,换成了更为先进的 SplitChunksPlugin,用于提取公用代码。它们的区别就在于,CommonChunksPlugin 会找到多数模块中都共有的东西,并且把它提取出来(common.js),也就意味着如果你加载了 common.js,那么里面可能会存在一些当前模块不需要的东西。而 SplitChunksPlugin 采用了完全不同的 heuristics 方法,它会根据模块之间的依赖关系,自动打包出很多很多(而不是单个)通用模块,可以保证加载进来的代码一定是会被依赖到的。下面的配置对象代表了splitChunksPlugin的默认行为:splitChunks: {chunks: "async",minSize: 30000,minChunks: 1,maxAsyncRequests: 5,maxInitialRequests: 3,automaticNameDelimiter: '~',name: true,cacheGroups: {vendors: {test: /[\\/]node_modules[\\/]/,priority: -10},default: {minChunks: 2,priority: -20,reuseExistingChunk: true}}}参考:/a/1190000015938570

------------------------------正确地使用Webpack 4.0的Tree Shaking-------------------------去掉用不到的CSS, 使用purifycss-webpackconst path = require('path');const glob = require('glob');const ExtractTextPlugin = require('extract-text-webpack-plugin');const PurifyCSSPlugin = require('purifycss-webpack');module.exports = {entry: {...},output: {...},module: {rules: [{test: /\.css$/,loader: ExtractTextPlugin.extract({fallbackLoader: 'style-loader',loader: 'css-loader'})}]},plugins: [new ExtractTextPlugin('[name].[contenthash].css'),// Make sure this is after ExtractTextPlugin!new PurifyCSSPlugin({// Give paths to parse for rules. These should be absolute!paths: glob.sync(path.join(__dirname, 'app/*.html')),})]};参考: /package/purifycss-webpack

----------------------------使用动态import切分页面代码,减小首屏JS体积------------------------import: 遵循组件化思想, 减少当前JS代码的体积,好处就是代码易读,减少渲染,按需加载

--------------------编译到ES+,提高代码运行效率,减小体积---------------------------------遵循ES6语法

------------------------------使用Lazyload和placeholder提升加载体验------------------------1. placeholder: 简单的处理方式, 给标签设置默认值, 或者说是占位符2. Lazyload:懒加载import React from 'react';import ReactDOM from 'react-dom';import LazyLoad from 'react-lazyload';import MyComponent from './MyComponent';const App = () => {return (<div className="list"><LazyLoad height={200}><img src="tiger.jpg" /> /*Lazy loading images is supported out of box,no extra config needed, set `height` for betterexperience*/</LazyLoad><LazyLoad height={200} once >/* Once this component is loaded, LazyLoad willnot care about it anymore, set this to `true`if you're concerned about improving performance */<MyComponent /></LazyLoad><LazyLoad height={200} offset={100}>/* This component will be loaded when it's topedge is 100px from viewport. It's useful tomake user ignorant about lazy load effect. */<MyComponent /></LazyLoad><LazyLoad><MyComponent /></LazyLoad></div>);};ReactDOM.render(<App />, document.body);参考: /package/react-lazyload

欢迎纠错

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。