运行环境
Jonnzer Lv4

网页加载

知识点:
  • 加载资源的形式:
    HTML 代码
    媒体文件,图片,视频
    JS CSS

  • 加载资源的过程:
    DNS 解析:域名 => IP 地址
    浏览器根据 IP 地址,向服务器发起 Http 请求
    三次握手
    服务器处理 Http 请求,并返回给浏览器

  • 渲染页面的过程:
    根据 HTML 代码生成 DOM Tree
    根据 CSS 代码生成 CSSOM
    将 DOM Tree 和 CSSOM 整合进 Render Tree
    根据 Render Tree 渲染页面
    JS 可能会改变 DOM,所以 JS 线程 和 渲染线程,是共用线程,所以遇到 script 暂停渲染,优先加载并执行 JS 代码,然后继续渲染页面,直至完成 Render Tree

从输入 url 到 渲染出页面的整个过程?

加载资源的过程 + 渲染页面的过程

window.onload 和 DOMContentLoaded 的区别?

onload:页面全部资源加载完 才执行,包括 图片、视频
window.addEventListener(‘load’, function() {})

DOMContentLoaded:DOM 渲染完 即执行,此时 图片、视频还可能没有加载完( 快 )
document.addEventListener(‘DOMContentLoaded’, function() {})

为什么建议把 CSS 放在 head 中?JS 为什么建议 放后面?

早点生成 CSSOM,避免 Render 延迟
JS 会 阻碍页面渲染,同步等待,会让 用户等待时间延长

性能优化

知识点:
  • 缓存:url 和 文件不变,则会自动触发 http 缓存机制,返回 304

  • SSR: 服务端渲染,将网页和数据一起加载,一起渲染

  • 懒加载:

    1
    2
    3
    4
    5
    <img id="img1" src="preview.png" data-realsrc="abc.png">
    <script type="text/javascript">
    var img1 = document.getElementById('img1')
    img.src = img1.getAttribute('data-realsrc')
    </script>
  • DOM 缓存 :用变量存储查询的 DOM 结果,避免 For 循环 一直查询

  • 防抖 ( debounce )
    常用场景:
    监听输入框,文字变化后 触发 change 事件
    直接用 keyup 事件,频繁触发 change 事件
    用户输入结束或暂停时,才会 触发 change 事件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    var input = document.getElementById('input1')
    let timer = null
    input.addEventListener('keyup', function(e) {
    if (timer) { clearTimeout(timer) }
    timer = setTimeout(() => {
    console.log(input.value)
    timer = null
    }, 500)
    })

    // 封装版
    function debounce (fn, delay = 500) {
    let timer = null
    return function () {
    if (timer) { clearTimeout(timer) }
    timer = setTimeout(() => {
    fn.apply(this, arguments)
    timer = null
    }, delay)
    }
    }
    input1.addEventListener('keyup', debounce(function(){
    console.log(input1.value)
    }, 500))
  • 节流
    适用于任何频繁触发的,如 scroll 、mousemove 、 drag
    拖拽一个元素,随时拿到该元素被拖拽的位置,按一定触发的速率去触发,而不是频繁触发,

    1
    <div id="dragDiv" draggable="true"></div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    const dragDiv = document.getElementById('dragDiv')
    dragDiv.addEventListener('drag', throttle(function(e) {
    console.log(e.offsetX, e.offsetY)
    }, 200))

    function throttle(fn, delay=100) {
    let timer = null
    return function() {
    if (timer) return
    timer = setTimeout(() => {
    fn.apply(this, arguments)
    timer = null
    }, delay)
    }
    }

    掘金 节流优化

性能优化入手:

加载更快:
减少资源体积大小( 打包📦工具压缩代码 )
减少请求次数:合并代码,SSR 服务器端渲染,缓存( 根据内容进行静态资源加哈希后缀,文件内容变化才会影响哈希后缀 )
使用更快的网络:CDN

渲染更快:
CSS 放 Head 位置,JS 放在 Body 下面
尽早开始执行 JS,用 DOMContentLoaded 触发
懒加载( 图片懒加载,上滑加载更多 )
对 DOM 查询进行缓存
频繁 DOM 操作,合并到一起插入 DOM 结构
节流 throttle ,防抖 debounce

原则:

多使用 内存、缓存 或其他方法
减少 CPU 计算量,减少网络加载耗时
适用于所有编程的性能优化 — 空间换时间( 内存 换 加载时间 )

安全

常见的 web 安全 :

XSS 跨站请求攻击:嵌入恶意 script 脚本,获取 阅读者 用户敏感信息

预防:
替换特殊字符,如 < 变为 < , > 变为 >
将 script 标签左右的 尖括号,前端后端都替换,直接显示,不作为脚本执行
有个工具做的不错的,npmjs.com/package/xss

XSRF 跨站请求伪造:

伪造用户身份去跨域请求
预防:
post 请求
请求增加验证手段,密码,验证码,指纹等

  • 本文标题:运行环境
  • 本文作者:Jonnzer
  • 创建时间:2021-04-06 12:30:00
  • 本文链接:https://jonnzer.github.io/2021/04/06/运行环境/运行环境/
  • 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
 评论