1. 前端性能优化思路:
建立完善的开发规范, 提高代码的渲染效率及可维护性.
压缩代码, 合并代码, 减少文件体积
减少图片等静态资源的体积, 并使用图片懒加载技术
使用多域名负载网页内的多个文件, 图片
注意阻塞, 将 CSS 样式定义放置在文件头部, JS 脚本放在文件末尾
尽量减少页面中重复的 HTTP 请求数量
服务器开启 gzip 压缩功能, 对用户请求的页面进行压缩处理
上面的这些回答太过笼统, 并且大多数的前端都会这样说, 其实这个问题的拓展性非常强, 特别能体现出对前端领域的掌握深度, 网络层面? 浏览器渲染层面? CSS,JS 执行层面? 框架层面? 详细说, 越详细越好
2. 如何理解回流和重绘??
回流:
当我们对 DOM 的修改引发了 DOM 几何尺寸的变化 (比如修改元素的宽, 高或隐藏元素等) 时, 浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响), 然后再将计算的结果绘制出来. 这个过程就是回流(也叫重排).
重绘:
当我们对 DOM 的修改导致了样式的变化, 却并未影响其几何属性 (比如修改了颜色或背景色) 时, 浏览器不需重新计算元素的几何属性, 直接为该元素绘制新的样式(跳过了上图所示的回流环节). 这个过程叫做重绘. 由此我们可以看出, 重绘不一定导致回流, 回流一定会导致重绘.
避免方法
1. 减少使用行内样式, 使用 clas 关联样式
2. 对于需要经常隐藏和显示的内容在页面布局写入后使用 display:none; 属性进行操作, 这样不会引发页面的回流重绘, 尽量减少 DOM 操作.
3. 避免频繁读取会引发回流重绘的元素, 如果需要最好是缓存起来
4. 对复杂动画元素使用绝对定位, 使它脱离文档流
5. 减少 table 布局以及 CSS 表达式 (如 calc()) 的使用.
3.CDN 是什么?
CDN, 中文名叫做「内容分发网络」, 它的作用是减少传播时延, 找最近的节点, 实际上, 尽管互联网帮助我们实现了地球村, 但是从中国到日本和从中国到中国台湾的时延仍旧是不一样的,
CDN 的优点
1. 访问加速
2. 减轻源站 (服务器) 负载
一个非常简单就能想明白的问题, 如果 CDN 已经能帮我返回数据了, 那么请求就不会到达源站, 源站 (服务器) 的负载就减轻了.
3. 抗住攻击
既然源站的负载被减轻了, 那么在受到 DDOS 攻击的时候, 也能谈笑风生.
**CDN 的缺点?
1. 首先可控性差, 比如某个依赖节点挂了, 导致项目无法正常运行, 会直接导致用户的损失, 尤其是体量大的公司依赖 CDN 进行静态资源管理的时候, 发生这样的事情后果会非常严重.
2. 其次, 便宜没好货: 本来在只有网宿而没有阿里云的时代, CDN 是很昂贵的, 阿里腾讯在拉低 CDN 价格的同时, 也拉低了 CDN 的质量, 部分节点的访问质量不太高会导致有些用户访问的网络质量非常差.
然后, 一个微小的科普: 什么是混合 CDN-- 混合 CDN 这个名词看着很高端, 实际上就是, 我们用了多家厂商的 CDN, 可能也包括自己建的, 然后谁好的选谁, 但是有的时候反而会造成服务不可控, 进一步劣化 CDN 的质量.
CDN 这个东西本质就是一个缓存, 只是这个缓存离你特别特别的近, 作为用户还是开发都能从中享受到一点福利, 但作为一个服务于企业的开发人员, 不仅要考虑 CDN 的优点, 也要知道 CDN 给我们带来的坑, 这样才能成为靠谱的 CDN 使用者.
webpack 性能优化
优化可以从两个方面考虑, 一个是优化开发体验, 一个是优化输出质量.
优化开发体验
1. 缩小文件搜索范围. 涉及到 webpack 如何处理导入文件, 不再赘述, 不会的可以自行搜索. 由于 loader 对文件转换操作很耗时, 应该尽量减少 loader 处理的文件, 可以使用 include 命中需要处理的文件, 缩小命中范围.
2.DllPlugin 可以将特定的类库提前打包然后引入. 这种方式可以极大的减少打包类库的次数, 只有当类库更新版本才有需要重新打包, 并且也实现了将公共代码抽离成单独文件的优化方案
3. 因为 Node 是单线程运行的, 所以 Webpack 在打包的过程中也是单线程的, 特别是在执行 Loader 的时候, 这样会导致等待的情况, HappyPack 可以将 Loader 的同步执行转换为并行的
优化输出质量
优化输出质量最大的好处就是可以减少首屏的加载时间
1. 如果我们把十几个页面甚至更多的路由页面, 把这些页面全部打包进一个 JS 文件的话, 虽然将多个请求合并了, 但是同样也加载了很多并不需要的代码, 耗费了更长的时间. 那么为了首页能更快地呈现给客户, 这时候我们就可以使用按需加载, 将每个路由页面单独打包为一个文件
2. 使用 Tree Shaking, 删除项目中未被引用的代码
3. 开启 Scope Hoisting,Scope Hoisting 会分析出模块之间的依赖关系, 尽可能的把打包出来的模块合并到一个函数中, 让 Webpack 打包出来的代码更小, 运行更快
区分环境 -- 减小生产环境代码体积, 代码运行环境分为开发环境和生产环境, 代码需要根据不同环境做不同的操作, 许多第三方库中也有大量的根据开发环境判断的 if else 代码, 构建也需要根据不同环境输出不同的代码, 所以需要一套机制可以在源码中区分环境, 区分环境之后可以使输出的生产环境的代码体积减小. Webpack 中使用 DefinePlugin 插件来定义配置文件适用的环境.
- const DefinePlugin = require('webpack/lib/DefinePlugin');
- //...
- plugins:[
- new DefinePlugin({
- 'process.env': {
- NODE_ENV: JSON.stringify('production')
- }
- })
- ]
注意, JSON.stringify('production') 的原因是, 环境变量值需要一个双引号包裹的字符串, 而 stringify 后的值是'"production"'
然后就可以在源码中使用定义的环境:
- if(process.env.NODE_ENV === 'production'){
- console.log('你在生产环境')
- doSth();
- }else{
- console.log('你在开发环境')
- doSthElse();
- }
5. 使用 webpack 内置的 UglifyJS 插件, 压缩 JS 代码, ParallelUglifyPlugin 会分析 JS 代码语法树, 理解代码的含义, 从而做到去掉无效代码, 去掉日志输入代码, 缩短变量名等优化. 常用配置参数如下:
- const UglifyJSPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
- //...
- plugins: [
- new UglifyJSPlugin({
- compress: {
- warnings: false, // 删除无用代码时不输出警告
- drop_console: true, // 删除所有 console 语句, 可以兼容 IE
- collapse_vars: true, // 内嵌已定义但只使用一次的变量
- reduce_vars: true, // 提取使用多次但没定义的静态值到变量
- },
- output: {
- beautify: false, // 最紧凑的输出, 不保留空格和制表符
- comments: false, // 删除所有注释
- }
- })
- ]
伴随着越来越多的浏览器支持 ES6, 出现了很多第三方插件, 可以直接压缩 ES6 代码, 在使用的同时注意 xxxxx
压缩代码
CDN 加速
提取公共代码
按需加载
提升流畅度, 即代码性能:
使用 PrePack 优化代码运行时的效率
来源: http://www.jianshu.com/p/c1778746cac4