赣州新闻网

首页 / 科技

【开源资讯】JFinal-layui v1.4.2 来袭,XSS、CSRF防御、代码器

2020-03-30 · 赣州新闻网 · 科技

本文主要介绍前端性能优化中的资源预加载,不仅会介绍常规的一些预加载手段;还会介绍工程实践中的应用。

涉及内容:

  • link相关(rel、as、media、defer、a: 0 c R Usync);
  • 缓存(4种缓存、缓存策略、ServiceWork);
  • 优化网络(H. P m |TTP/2 ServerPush、Preload/Prefetch、域名拆分);
  • 同步接口JSON数据内联: E & ] A I Y 7 E,加速首页渲染;
  • 浏览器中M v W h各资源加载的优先级;
  • 实践:webpack插件、quik` r ^ 9link.

前言

当我们需要某些网络资源时,加载和执行往往耦合在一起,下载完立即执行,而加载过程是阻塞式的,{ 0 j A H y延长了onload时间。因此如何在资源执行前预加载资源,减少等待网络的开销便是我们要探讨的问题。w ] ( c ) {

1. 常规做法

附一张不同资源浏览器优先级的图示(来源):

Web前端资源预加载

1)async/defer: 无阻塞加载

defer:DOMContentLq B q 1 v U f ;oaded事件触发前执行;在现实当中,延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoade, @ b ) ,d事件触发前执行,因此 S r E R 3 )最好只包含一个延迟脚本;

async:加载完立即执行,无法控制执行时机和执行顺序。适用于无依赖的外部独立资源。

不足:仅; D L r限于脚本资源;执行时机不可控或存在执行顺序问题,用于非关键资源。

2)使用ajax加载资源:可以实现预加载。

不足:优先级较低,无法对首屏资源提前加载。

3)Webkit浏览3 f i 5 !器预测解析:chrome的预加载扫描器ht% { ? }ml-preload-scannerO A 5 p v J S通过扫描节点中的 \"src\" , \"link\"等属性,找到外部连接资源后进行预加载,避免了资源加载的等待时间,同样实现了提前加载以及加载和执行分离。

原始解析做法:

Web前端资源预加载

采用预解析(扫描)器:

Web前端资源预加载

不足:

-) - 1 o . Q _ r ` 仅限解析HTML中收集到的外链资源,对JS异步加载的资源无法提前收集。

- 未暴露类似于Preload的onload事件。

4)Server Push 图: ) & 6 p 8 ! &片来源

Web前端资源预加载

资源推送:

Link: <https://example.com/other/styles.css>; rel=preload; as=style;

资源仅预加载,不推送:

Link: <https://exG G s n + Jample.com/other/styles.css>; rel=preload; as=style;nopush

目标:减少请求数量和提高页面加载速度。

特点:多页面共享push cache(动态数O ` N s T % Y据json除外)

适用场景:如果不推送这个资源,浏览器就会请求这个资源。

需要注意:要确保没有发起不必要的推送,浪费流量。可以使用preload标签代替,或者在HTTP头中加nopush属性。

Tips:如果服务器或者浏览器不支持 HTTP/2,那么浏E V b h r览器就会按照k 6 V e S _ C S preload 来处理这个头信息,预加载指定的资源文件。

不足:

- Edge和Safari的支持不好,慎用;

- 如果浏览器不从push cache中获取资源,推送反而不利于网页性能;

- 只能推送] ; D @ D不带请求体的GET和HEAp 8 . n nD请求;

- push cache中的资源只能使用一次a Q j 9 0 + {;

- 不考虑客户端的缓存,始终推送:

- 只对第一次T Z T 7 / f V A k访问的用 S D = . } 2 / q Nefetch预加载。

- font字体文件的预加载由于字体文件必须等到CSSOM构建完成并且作用到页面元素了才会开始加载,会导致页面字体样式闪动。而浏览器为了避免FOUT,会尽量等待字体加载完成后,再显示应用了该字体的内容,会导致加载完成前显示空白。

检测prelaod和prefetch的支持情况

let { relList } = document.createElement(\'linkM 8 = ` 8 q D\');

如何使用

//link标签

as属性值- j _ V F _ .

不同值表明资源类型,g @ J L = n对应的优先级不H G 3 9 K同:style, script, image, media, document, font。(问题:官方X v , # = Y ?说法:不带 “as”属性的 preload 的优先级将会等同于异步请求。测试后发现不写a q / T 4 as并没有发请求。)

注意事项

- 造成二次下载

- 同一资源分别使用as=\'style\'和P ^ K Ras=\'script\'V 9 Q j预加载K d 1 n %,会造成二次下载;

- prefetch和preload同时对同一资源使用,会造成二次下载;

- 实际是script脚本,但使用as=\'style\'会造成二次下载;

- prelo: E + ? ! 5 x Zad字体时不带cro2 E Y 3 S = xssOrigin(默认指n y h % m T定anonymous匿名,不f 4 I Q ] L带认证信息),同样会造成二次下载pr7 L w = 1 _ 7 Xeload字体时即使同域也需要Y I 7 t带crossOrigin,否则同样R U r F会造成二次下载;Requests with. C . 0 { # U qout credF $ U ~ _ ] & *entiaf { # t X Q :ls use a separate connectig :on。

- 没有使用preload资源,Chrome会在onload事件3s后做出警示,避免R ( ) U ! E无效的优化,浪费流量。

-浏览器 M + P对同一域名有并行加载数限制,因此考虑域名拆分等优化。

实践

下面是twitter页面中应用:

preload的polyfc k 4 Z K X -ill

背n d E ~ j O ; v G景知识

//若支持preload,异步下载完不会立即执行

polyfill实现思路

参见loadCSS,提供了css的preload的polyfill实现(只展示关键代码):

// 1. 【支持preload的情况】

注意这里实现的是对CS9 ( X ~ N ! k sS的预加载。

适用于对于首页无关的样式:

由于preload{ 5 c S 2能够异步加载样式,因此可以避免在加载首页无Q : l A关样式时阻塞初始渲染。

对于首页初始渲染中重要的样式:- q N

1)内联 (注意,会将静态资源的缓存策略与页面的缓存D a _ t策略捆绑)

2)HTTP/2的serverF X R 6Push

“知道了preload和pref: k L metch的用途,那如何结合项目实践呢?由于webpack目前基本是项目必备,所以首先介绍结合webpack的使用;然后对q9 Q e Y V R J duikl% m m * 6 q Fink进行简单介绍。 ”

结合webpack的实践

1. 使用插件:PreloadWebpackPlugin

常用的配置如下:

new Pt _ ; ^ m O ] hreloadWebpackPlugin({

其中include的两种使用:

1) 根据chunk类型进行处理:

i, z vnclude: \'asyncChunks\' | \'initial\' | \'allChunks\'

asyncChunks:V n F l t d 1 8 ,import()动态导入的模8 q ` w O C P块,可以使Y n c i f Q e 6 l用prefetch方式异步加载模块;

inb [ ` h l 7 ) qitial:初始化需要的模块;

allChunks:处理所有模块(asyncChunks & initia, Q q C $l)。

2) 对已知命名| 9 m R p b的chunk,可以更精确的使用数组的方式配置需要使用的chunk

i- o Enclude: 

注意事项

1)需要结合HtmlWebpackPlugin插件使用

2)必须放到HtmlWebpackPlugin后面M { A F g m z,因为PreloadWebpackPlugin需要使用其提供的hook钩子将构造的<link>插入html中:

pj S N P - G Qlugins: ">

当真正使用时,由于已经下载到本地,直接读取执行,性能得到较大的提升。

2. 结合import()

好处:拆分chunk,减少首屏js体积B M Q G c -。

如果工程没有使用Z , - A * f n 4 4HtmlWebpackPlugin,可以对动态导入的资源做如下处理:

import(/* webpackPrefetch: true */)

【版本限& 4 w B + V * * +制】需webpack v4.6.0+ 才B P : A M O !支持预取和预加载。本地测试后,发| @ 0现prefetch可用,preload无效。

quiklink

旨在成为根据用户viewport中的链接预取内容的简易解决方案。

工作原理

通过获取页面中a标签的href,试图7 j } r ^ Q K .更快的加载接下来可能要访问的页面。

1) Int3 h D W j lersectionObserver(交叉观察器): 检测当前视口的links

let target= document.getE+ O } x ; FlementById(\'a\');

【备注】常规的主要是通过getBoundingCF R U z TlientRect()获取元素在视口中的详细位置,来实现滚动加载以及吸附等功能。

2) requestIdleCallback:等到浏览器空闲时;

注意其和requestAnimationFrame的区别.

3) 检查当前的网络环境:

navigator.connection.effectiveTypN r n x C c ^ U Ie //4G、2G...;

4) 提供了多种方式预取链接

小巧的js库,使用了如上4个特性,每一个都值得细细^ m 1 D N品味。有兴趣的可以看下源码: https:} 4 p 9 2 g 7 x ]//github.com/GoogleChro... 。

工作流程:

1) 浏览器空闲时,获取页面所有a标签的链接links;

2) 使用IntersectionObserver对link进行监听;

3) 在视口区的link,使用prefetch下载;

4) 判断当前网络状况,若使用的是2G或者开启了省流模式(A u 4 0 Z H & 8data-saver),则不做处理。

data-saver: The user may ei w ^ ]nable such preference, if made available by the user agent, due to high da1 j e U & z h + ta transfer costs, slow connection speeds, or other reasons.

题外话:prefetch有点偷流量的意思,用户想看什么才消耗对应资源产生的流量,而prefetch则会擅自做主,偷偷下载很多可能并不需d V f % ]要的资源(在早前流量特贵的时候这么做,估计会被骂...)

5) 下载链接资源,三种下载方式:fetch、xhr、<link rel=prefetch href=\"\" />

使用说明

  • 只支持prefetch;
  • 通过a标签获取links;
  • 最佳实践是对后续可能访问的页面的提前下载,后续真正访问时,直接从本地获取执行。

总结

综合来看,PreloadWebu A A g fpackPluw G K j Q Z E ] ,gin更适合对chunk而非html文件的处理;而quikLink更适合博客类的网站,或者服务端渲染的页面K 6 D u 8 L # g,这样才能实现\"秒开\"的预期效果。

参考文献

  • preload-webpack-plugin
  • quicklink
  • IntersectionObserver
  • Preload$ $ ! k, Prefetch And Priorities in Chrome
  • loadCSS
  • A Tale of Four Caches
  • React 16 加载性能优化指南
  • PWA直出
  • 亿万级访问量下的前端同构直出实践

测试确保项目工作请求接口设置上犹防御