一、优化前端资源加载
js
加载资源方式:
1.1、使用内联图片,也就是将图片转换为base64编码的data-url。这种方式,其实是将图片的信息集成到css文件中,避免了图片资源的单独加载。但图片内联会增加css文件的大小,增加首屏渲染的时间。
1.2、使用js代码对图片进行预加载。
preloadImage() {
const imgList = [
require('@/assets/imgs/error.png'),
require('@/assets/imgs/ticket_bg.png')
];
for (let i = 0; i < imgList.length; i++) {
const newIMG = new Image();
newIMG.src = imgList[i];
}
}
1.3、preload/prefetch
,它们能够辅助浏览器优化资源加载的顺序和时机,提升页面性能
<head>
...
<link rel="prefetch" href="static/img/ticket_bg.a5bb7c33.png">
...
</head>
<head>
...
<link rel="preload" as="font" href="<%= require('/assets/fonts/AvenirNextLTPro-Demi.otf') %>" crossorigin>
<link rel="preload" as="font" href="<%= require('/assets/fonts/AvenirNextLTPro-Regular.otf') %>" crossorigin>
...
</head>
const PreloadWebpackPlugin = require('preload-webpack-plugin');
...
plugins: [
new PreloadWebpackPlugin({
rel: 'preload',
as(entry) {
//资源类型
if (/\.css$/.test(entry)) return 'style';
if (/\.woff$/.test(entry)) return 'font';
if (/\.png$/.test(entry)) return 'image';
return 'script';
},
include: 'asyncChunks', // preload模块范围,还可取值'initial'|'allChunks'|'allAssets',
fileBlacklist: [/\.svg/] // 资源黑名单
fileWhitelist: [/\.script/] // 资源白名单
})
]
二、OCR工具类
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import javax.imageio.ImageIO;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.spiderflow.ocr.model.Ocr;
import com.baidu.aip.ocr.AipOcr;
public class OcrUtil {
private static HashMap<String, AipOcr> aipOcrMap = new HashMap<String, AipOcr>();
private static HashMap<String, String> options = new HashMap<String, String>();
private static class ErrorCode {
/**
* 图片格式不对
*/
private static final int IMAGE_FORMAT_ERROR = 216201;
/**
* 响应无效
*/
private static final int URL_RESPONSE_INVALID = 282113;
}
static {
options.put("detect_direction", "true");
options.put("detect_language", "true");
options.put("probability", "true");
}
public static AipOcr getAipOcr(Ocr ocr) {
String ocrMapKey = ocr.getAppId()+ocr.getApiKey()+ocr.getSecretKey();
AipOcr aipOcr = aipOcrMap.get(ocrMapKey);
if(aipOcr == null) {
aipOcr = new AipOcr(ocr.getAppId(), ocr.getApiKey(), ocr.getSecretKey());
aipOcrMap.put(ocrMapKey, aipOcr);
}
return aipOcr;
}
public static int getErrorCode(JSONObject bgJson) {
if(!bgJson.isNull("error_code")) {
int errorCode = bgJson.getInt("error_code");
return errorCode;
}
return -996;
}
public static boolean isImageFormatError(int errorCode) {
if(errorCode != -996) {
// 图片格式不对
if(errorCode == ErrorCode.IMAGE_FORMAT_ERROR) {
return true;
}
}
return false;
}
public static boolean isUrlResponseInvalid(int errorCode) {
if(errorCode != -996) {
if(errorCode == ErrorCode.URL_RESPONSE_INVALID) {
return true;
}
}
return false;
}
public static byte[] imgConvert(byte[] bytes) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
ByteArrayInputStream input = new ByteArrayInputStream(bytes);
ImageIO.write(ImageIO.read(input), "png", output);
return output.toByteArray();
}
public static JSONObject ocrIdentify(Ocr ocr,byte[] bytes) throws Exception {
try {
AipOcr aipOcr = getAipOcr(ocr);
JSONObject bgJson = aipOcr.basicGeneral(bytes, options);
if(isImageFormatError(getErrorCode(bgJson))) {
return aipOcr.basicGeneral(imgConvert(bytes), options);
}
return bgJson;
} catch (Exception e) {
throw e;
}
}
public static JSONObject ocrIdentify(Ocr ocr,String url) throws IOException {
AipOcr aipOcr = getAipOcr(ocr);
JSONObject bgJson = aipOcr.basicGeneralUrl(url, options);
if(isUrlResponseInvalid(getErrorCode(bgJson))) {
return aipOcr.basicGeneral(imgConvert(Jsoup.connect(url).ignoreContentType(true).execute().bodyAsBytes()), options);
}
return bgJson;
}
}
三、下划线互转驼峰
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class FieldUtils {
private static Pattern humpPattern = Pattern.compile("[A-Z]");
public static List<String> allFields(Class clazz){
return Arrays.stream(clazz.getDeclaredFields()).map(item->humpToLine2(item.getName())).collect(Collectors.toList());
}
public static List<String> updateFields(Class clazz){
return Arrays.stream(clazz.getDeclaredFields())
.filter(item->item.getAnnotation(ApiUpdateField.class) != null)
.map(item-> humpToLine2(item.getName())).collect(Collectors.toList());
}
/**
* 下划线转驼峰
*/
public static String underlineToCamel(String name){
StringBuilder sb = new StringBuilder(name.length());
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
if ('_' == c) {
if (++i < name.length()){
sb.append(Character.toUpperCase(name.charAt(i)));
}
}else {
sb.append(c);
}
}
return sb.toString();
}
/**
* 驼峰转下划线
*/
public static String humpToLine2(String str) {
Matcher matcher = humpPattern.matcher(str);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
}
matcher.appendTail(sb);
return sb.toString();
}
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ApiUpdateField {
}
四、表结构解析
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* 表结构解析
*/
public class SqlUtils {
public static String getByPattern(String sql, String pattern, int group) {
Pattern compile = Pattern.compile(pattern);
Matcher matcher = compile.matcher(sql);
while (matcher.find()) {
return matcher.group(group);
}
return null;
}
public static List<String> getColumnSqls(String sql) {
List<String> lines = new ArrayList<>();
Scanner scanner = new Scanner(sql);
boolean start = false;
while (scanner.hasNextLine()) {
String nextLine = scanner.nextLine();
if (nextLine.indexOf("CREATE TABLE") != -1) {
start = true;
continue;
}
if (nextLine.indexOf("PRIMARY KEY") != -1 || nextLine.indexOf("ENGINE=") != -1) {
start = false;
continue;
}
if (start) {
lines.add(nextLine);
}
}
return lines;
}
}