前端面试—网站性能优化

我们常将网站性能优化措施归结为三大方面:
1、减少请求数;
2、css放头部,js放底部;
3、合理利用缓存,提升网络传输速率;
4、减小请求资源体积;

1 减少请求数
1.1使用雪碧图,减少http请求,推荐一个自动化生成雪碧图的工具:https://www.toptal.com/developers/css/sprite-generator
1.2 使用字体图标,推荐使用阿里巴巴矢量图标库:www.iconfont.cn/。
这种图片能做很多事情,而且它只是往html里面插入字符和样式,和图片相比,占用内存更小。

2 css放头部,js放底部
javascript会阻塞dom的解析。当解析过程中遇到<script>标签的时候,便会停止解析过程,转而去处理脚本,如果脚本是内联的,浏览器会先去执行这段内联的脚本,如果是外链的,那么先会去加载脚本,然后执行。在处理完脚本之后,浏览器才继续解析HTML文档,所以把js放底部。

3 浏览器缓存
浏览器在向服务器发起请求前,会先查询本地是否有相同的文件,如果有,就会直接拉取本地缓存,缓存策略如下图:
在这里插入图片描述
在这里插入图片描述
浏览器默认的缓存是放在内存中的,关闭浏览器就会清除,而存在硬盘里的缓存才能被长期保留下去,打开network,可以看到两种不同的状态:from memory cache 和 frome disk cache,前者来自内存,后者来自硬盘。
之所以拉取缓存会出现200、304两种不同的状态码,只有向服务器发起验证请求并确认缓存是否更新,更新返回200,未被更新返回304状态码。
补充:浏览器第一次向服务器发请求,服务器返回200和last-modified(服务器文件最后更新时间)。F5刷新页面发送验证请求,请求头会带上if-Modified-Since,如果和响应头返回的last-Modify的值相同,则返回304,从浏览器拉取缓存,否则发送数据请求,返回200。
同理ETag和If-None-Match对比,ETag是一串哈希值,可以理解成版本号,如果1s内频繁修改文件,那么更适合用ETag来协商缓存。

4 资源打包压缩
减少请求资源体积,通常都需要打包工具(例如webpack)的协助,可以从以下几点来对webpack进行优化。
3.1 配置热更新插件HotModuleReplacementPlugin,热更新不刷新整个网页,只编译发生变化的模块,新模块替换老模块。
3.2 压缩JS用UglifyJs,再用ExtractTextWebpackPlugin从js文件分离出css文件。
3.3 设置多个入口文件,提取公共代码,以利用缓存(CommonsChunkPlugin )。
通常的入口文件有pollyfills.ts、vendor.ts、main.ts。

entry: {
    //填平浏览器的坑,包括es6的一些包
    'polyfills': './src/polyfills.ts',
    //第三供应商,包括angular,bootstrap,lodash
    'vendor': './src/vendor.ts',
    //应用代码
    'app': './src/main.ts'
  }  
  -----------------------------------------------------------------------------------------------------------------
 const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
    //...
    plugins:[
        new CommonsChunkPlugin({
            chunks:['polyfills','vendor','main'], //从哪些chunk中提取
            name:'common',  // 提取出的公共部分形成一个新的chunk
        })
    ]

3.4 区分运行环境,因为第三方库中有大量根据开发环境判断的if else代码,所以构建也需要根据不同环境输出不同的代码。这里用definePlugin插件来配置。

const DefinePlugin = require('webpack/lib/DefinePlugin');
//...
plugins:[
    new DefinePlugin({
        'process.env': {
            NODE_ENV: JSON.stringify('production')
        }
    })
]
-------------------------------------------------------------------------------------------------------------------
if(process.env.NODE_ENV === 'production'){
    console.log('你在生产环境')
    
    doSth();
}else{
    console.log('你在开发环境')
    doSthElse();
}

3.5 require.ensure()来实现按需加载

 mapBtn.click(function() {
   require.ensure([], function() {
       var baidumap = require('./baidumap.js') //baidumap.js放在我们当前目录下
   })
 })

参考文章:https://segmentfault.com/a/1190000015883378
https://blog.csdn.net/DINGYANG0315/article/details/80518720

猜你喜欢

转载自blog.csdn.net/qq_37012533/article/details/84632930