浏览器机制
通过 DNS 将 URL 解析为对应的 IP ,然后与服务器建立起 TCP 连接,随后我们发出 HTTP 请求,处理完请求之后,把数据放在响应里返回给客户端,拿到响应数据的浏览器就可以解析绘制流程。
内核
由浏览器厂商开发,用来对从服务端得到的响应进行逐个解析,决定了浏览器如何显示网页的内容以及页面的格式信息,由于javascript这门语言的前身,至今浏览器厂商的内核便自成一套解析方案,这也就是我们浏览器兼容的由来。
进程与线程
- 一个进程中至少有一个主线程。进程启动后自动创建。
- 一个进程中也可以同时运行多个线程,程序是多线程运行的。
-
一个进程内的数据可以提供其中的多个线程共享,多个进程之间的数据是不能直接共享的。
线程: 是建成内一个独立执行的单位,是CPU调度的最小单元,程序运行的基本单位。
线程池:保存多个线程对象的容器,实现线程对象的反复利用。
- Browser进程: 浏览器的主进程,负责浏览器页面的显示,和各个页面的管理。浏览器中所有其他类型进程的祖先,负责其他进程的创建和销毁,有且仅只有一个。
- Render进程: 网页渲染进程,负责页面的渲染,可以有多个,渲染进程的数量不一定等于你打开的网页的个数
- 各种插件进程负责每个第三方插件的使用
- GPU进程负责3D绘制和硬件加速
线程阻塞: 单线程 -> 同步 || 异步 任务队列
解析器
CRP(关键渲染路径Critical Rendering Path)优化
HTML、CSS、JavaScript、layout、paint
- HTML:将HTML解析为DOM树,
- CSS:为DOM的各个元素计算出样式信息,为布局提供基础设施。
- JavaScript:使用JavaScript代码可以修改网页的内容,也能修改css信息,JavaScript引擎能够解释JavaScript代码,并通过DOM接口和CSS树接口来修改网页内容和样式信息
- layout:在DOM创建后webkit需要将其中的元素对象同样式信息结合起来,计算他们的大小位置等布局信息,形成信息的内部表达模型载体
- paint:使用图形库将布局计算后的各个网页得节点绘制成图像结果
- HTML标签,调用HTML解析器解析成对应的标签队列并构建DOM树
- style/link 标签,调用CSS解析器处理CSS标记并构建CSS样式树。
- script标签,调用JavaScript解析器处理script,绑定事件、修改DOM树/CSS树 等。
- 将DOM树和CSS树合并成一个渲染树。
- 根据渲染树(render tree)来渲染,以计算每个节点上的几何信息
- 将各个节点回执到屏幕上。
优化点:
- css:页面style标签写的样式是异步解析,容易产生“闪屏”现象,link进来的样式,是由css解析器解析,css解析器会阻塞页面的渲染,但一般为了不让界面裸奔,还是会采用头部link样式引入
- SPA单页面首屏时间过长:样式同步记载
- 图层:减少页面生成的图层(3d,canvas,video,css动画,css加速属性(will-change))
- 重绘(图层)、回流
- 元素移动,使用transflorm取代top
- 文档碎片
- 批量修改样式
- 在出现前改变元素的样式
- 动画元素需要开发者自建图层(css硬件加速)
- css表达式弃用
- 减少选择器前缀
- IE7滤镜修复半透明png,但会阻塞渲染,用png8图片代替
- 从服务端请求含有外联js的html,会再去服务器拿取js文件,但是,自上而下解析dom树过程中,如果遇到非异步的外联js会被阻塞
资源预制
CSS文件
- 压缩 css
使用在线网站进行压缩
使用html-minifier 对html 中的css 进行压缩
使用clean-css 对css进行压缩
webpack,gulp打包工具 - 值为0时不需要任何单位
- 减少web字体文件的引用
- 减少声明字体大小的数量
优化图片
- Sprite
- 行内图片(Base64编码)
- 不要用在HTML中加载时缩放图片
- 避免src为空的请求发送出去
JS文件
- 去除重复脚本
- 减少dom访问和操作
- 避免使用eval(xss,侵占内存2次,一次解析成js,一次执行)
- 消耗性能的操作能异步最好异步
- 避免一次性循环过多数据(while)
- 事件委托
- 谨慎闭包的使用
- 优化高频时间(节流、防抖)
- 尽量改变class而不是style,使用classList代替className
- 尽量使用id选择器
HTML
- audio、video标签使用preload属性指向页面加载
- 减少iframe使用(阻塞页面渲染)
- 设置viewpor
webpack打包优化
1. 利用externals提取第三方依赖并用CDN引入
2. 利用SplitChunks插件提取公共js代码和分割js代码
3. 利用MiniCssExtractPlugin插件提取css样式
4. 利用OptimizeCssnanoPlugin插件压缩和去重css样式文件
5. 开启optimization.minimize来压缩js代码
6. 利用image-webpack-loader进行压缩图片
7. 利用CompressionWebpack 在Webpack上开启gzip压缩
资源请求
1. 图片懒加载,视区加载
2. CDN静态资源托管,回源
3. 缓存一切不变化的大数据,及可缓存的资源
4. GZIP
1. webpack打包gzip
2. nginx gzip压缩
5. 配置服务器ETags(Entity Tag 实体标签 一个特殊的字符串来标识某个资源的“版本”)
6. 添加expires/ cache-control (同上)
7. 保持JSON报文通讯
8. 服务端渲染
9. 减少cookie(纯静态页面可移除)
DNS
- 是减少DNS的请求次数,
- 是进行DNS预获取——DNS Prefetch
HTTP
- 减少请求次数
- 减少单次请求所花费的时间
SEO
TDK优化
TDK为title
,description
,keywords
三个的统称。当然title
是最有用的,是非常值得优化的;而keywords
因为以前被seo人员过度使用,所以现在对这个进行优化对搜索引擎是没用的,这里就不说了;description
的描述会直接显示在搜索的介绍中,所以对用户的判断是否点击还是非常有效的。
title优化
title
的分隔符一般有,
,_
,-
等,其中_
对百度比较友好,而-
对谷歌比较友好,第四个为空格,英文站点可以使用,中文少用。title
长度一般pc端大概30个中文,移动端20个,超过则会截断为省略号。
因为业务关系,我们做的更多的是针对百度搜索引擎的优化,所以这里把百度搜索引擎优化的建议分享下:
title
格式:
- 首页:
网站名称
或者网站名称_提供服务介绍or产品介绍
- 频道页:
频道名称_网站名称
- 文章页:
文章title_频道名称_网站名称
如果你的文章标题不是很长,还可以加入点关键词进去,如文章title_关键词_网站名称
推荐做法:
- 每个网页应该有一个独一无二的标题,切忌所有的页面都使用同样的默认标题
- 标题要主题明确,包含这个网页中最重要的内容
- 简明精练,不罗列与网页内容不相关的信息
- 用户浏览通常是从左到右的,重要的内容应该放到title的靠前的位置
- 使用用户所熟知的语言描述。如果你有中、英文两种网站名称,尽量使用用户熟知的那一种做为标题描述
description优化
description
不是权值计算的参考因素,这个标签存在与否不影响网页权值,只会用做搜索结果摘要的一个选择目标。其长度pc端大概为78个中文,移动端为50个,超过则会截断为省略号。
百度推荐做法为:
- 网站首页、频道页、产品参数页等没有大段文字可以用做摘要的网页最适合使用description
- 准确的描述网页,不要堆砌关键词
- 为每个网页创建不同的description,避免所有网页都使用同样的描述
- 长度合理,不过长不过短
页面内容优化
使用html5结构
如header
,footer
,section
,aside
,nav
,article
唯一的H1标题
每个页面都应该有个唯一的h1标题,但不是每个页面的h1标题都是站点名称。(但html5中h1标题是可以多次出现的,每个具有结构大纲的标签都可以拥有自己独立的h1标题,如header
,footer
,section
,aside
,article
)
首页的h1标题为站点名称,内页的h1标题为各个内页的标题,如分类页用分类的名字,详细页用详细页标题作为h1标题
首页
<h1 class="page-tt">腾讯课堂</h1>
分类页
<h1 class="page-tt">前端开发在线培训视频教程</h1>
详细页
<h1 class="page-tt">html5+CSS3</h1>
img设置alt
属性
img
必须设置alt
属性,如果宽度和高度固定请同时设置固定的值
<img src="" alt="seo优化实战" width="200" height="100" />
nofollow
对不需要跟踪爬行的链接,设置nofollow
。可用在博客评论、论坛帖子、社会化网站、留言板等地方,也可用于广告链接,还可用于隐私政策,用户条款,登录等。如下代码表示该链接不需要跟踪爬行,可以阻止蜘蛛爬行及传递权重。
<a href="http://example.com" rel="nofollow">no follow 链接</a>
正文
内容方面考虑:
- 高质量原创内容
- 吸引阅读的写作手法
- 突出卖点
- 增强信任感
- 引导进一步行为
用户体验方面考虑:
- 排版合理、清晰、美观、字体、背景易于阅读
- 实质内容处在页面最重要位置,用户一眼就能看到
- 实质内容与广告能够清晰区分
- 第一屏就有实质内容,而不是需要下拉页面才能看到
- 广告数量不宜过多,位置不应该妨碍用户阅读
- 如果图片、视频有利于用户理解页面内容,尽量制作图片、视频等
- 避免过多弹窗
URL优化
URL设计原则:
- 越短越好
- 避免太多参数
- 目录层次尽量少
- 文件及目录名具描述性
- URL中包括关键词(中文除外)
- 字母全部小写
- 连词符使用
-
而不是_
- 目录形式而非文件形式
URL规范化
1、统一连接
http://www.domainname.com
http://domainname.com
http://www.domainname.com/index.html
http://domainname.com/index.html
以上四个其实都是首页,虽然不会给访客造成什么麻烦,但对于搜索引擎来说就是四条网址,并且内容相同,很可能会被误认为是作弊手段,而且当搜索引擎要规范化网址时,需要从这些选择当中挑一个最好的代表,但是挑的这个不一定是你想要的。所以最好自己就规范好。
2、301跳转
第一种是URL发生改变,一定要把旧的地址301指向新的,不然之前做的一些收录权重什么的全白搭了。
VUE
- v-show,v-if合理使用(首屏资源优先级判断,多条件下的可以放在计算属性)
- 多个子组件出现在同一个页面,添加key,放点dom diff
- style的样式私有
- 减少页面浮动、定位,尽量使用flex布局
- 组件拆分颗粒级(减少组件打包的js大小)
- 组件懒加载
- .map文件的去除
- 大型公用API,如Vue、Vuex、Vue-Router、Axios可选择稳定源引入,在打包中忽略,webpack 配置:
externals: {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios'
}
- v-for高于v-if优先级,在v-for中不要使用v-if,可以使用计算属性将v-if 的内容过滤
- 利用v-once处理只会渲染一次的元素或组件
- Object.freeze()冻结不需要响应化的数据
- 组件互通数据优先处理数据
- v-for遍历时避免读取data数组类型的数据
解析:在数据劫持中会调用defineReactive函数中。由于 getter是函数,并且引用了 dep、childOb,形成了闭包,所以 dep、childOb 一直存在于内存(每个数据的getter函数)中,dep是每个数据的依赖收集容器,childOb是经过响应式处理后的数据。如果遇到数据,则会递归遍历,导致内存被大量占用
- 利用挂载点优化白屏
- store数据扁平存放
- 组件css提取
import Vue from 'vue'
import App from './App.vue'
new Vue({
render: h => h(App)
}).$mount('#app')
这里可以在div#app中书写骨架屏或者loading
雅虎军规
性能监测工具
- 在线工具 PageSpeed Insights
- Lighthouse 谷歌浏览器插件
- 页面加载的性能指标
缩写 | 释义 | 单词全称 |
---|---|---|
TTFP | 首字节时间 | Time TO Frist Byte |
FP | 首次绘制(第一个节点) | First Paint |
FCP | 首次有内容的绘制(骨架) | First Contentful Paint |
FMP | 首次有意义的绘制(包含所有元素/数据) | First Meaningful |
TTI | 达到可交互时间,推荐的响应时间是100ms以内否则有延迟 | Time To Interactive |
Long tasks | 超过了 50ms 的任务 | '' |
SSR&&CSR | 服务端渲染和客户端渲染 | Server-Side-Rendering / Client Side Rendering |
Isomorphic | 同构化 | '' |
Comments | NOTHING